2 * Copyright (C) 2016, 2017 "IoT.bzh"
3 * Author "Fulup Ar Foll"
4 * Author José Bollo <jose.bollo@iot.bzh>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
23 #include <json-c/json.h>
24 #include <afb/afb-auth.h>
25 #include <afb/afb-session-v2.h>
28 #include "afb-context.h"
33 int afb_auth_check(struct afb_xreq *xreq, const struct afb_auth *auth)
41 return afb_context_check(&xreq->context);
44 return afb_context_check_loa(&xreq->context, auth->loa);
46 case afb_auth_Permission:
47 return afb_auth_has_permission(xreq, auth->text);
50 return afb_auth_check(xreq, auth->first) || afb_auth_check(xreq, auth->next);
53 return afb_auth_check(xreq, auth->first) && afb_auth_check(xreq, auth->next);
56 return !afb_auth_check(xreq, auth->first);
63 /*********************************************************************************/
64 #ifdef BACKEND_PERMISSION_IS_CYNARA
67 #include <cynara-client.h>
69 static cynara *handle;
70 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
72 int afb_auth_has_permission(struct afb_xreq *xreq, const char *permission)
77 /* case of permission for self */
81 ERROR("Got a null permission!");
85 /* cynara isn't reentrant */
86 pthread_mutex_lock(&mutex);
88 /* lazy initialisation */
90 rc = cynara_initialize(&handle, NULL);
91 if (rc != CYNARA_API_SUCCESS) {
93 ERROR("cynara initialisation failed with code %d", rc);
98 /* query cynara permission */
99 rc = cynara_check(handle, xreq->cred->label, afb_context_uuid(&xreq->context), xreq->cred->user, permission);
101 pthread_mutex_unlock(&mutex);
102 return rc == CYNARA_API_ACCESS_ALLOWED;
105 /*********************************************************************************/
107 int afb_auth_has_permission(struct afb_xreq *xreq, const char *permission)
109 WARNING("Granting permission %s by default of backend", permission ?: "(null)");
114 /*********************************************************************************/
116 static struct json_object *addperm(struct json_object *o, struct json_object *x)
118 struct json_object *a;
123 if (!json_object_object_get_ex(o, "allOf", &a)) {
124 a = json_object_new_array();
125 json_object_array_add(a, o);
126 o = json_object_new_object();
127 json_object_object_add(o, "allOf", a);
129 json_object_array_add(a, x);
133 static struct json_object *addperm_key_val(struct json_object *o, const char *key, struct json_object *val)
135 struct json_object *x = json_object_new_object();
136 json_object_object_add(x, key, val);
137 return addperm(o, x);
140 static struct json_object *addperm_key_valstr(struct json_object *o, const char *key, const char *val)
142 return addperm_key_val(o, key, json_object_new_string(val));
145 static struct json_object *addperm_key_valint(struct json_object *o, const char *key, int val)
147 return addperm_key_val(o, key, json_object_new_int(val));
150 static struct json_object *addauth_or_array(struct json_object *o, const struct afb_auth *auth);
152 static struct json_object *addauth(struct json_object *o, const struct afb_auth *auth)
155 case afb_auth_No: return addperm(o, json_object_new_boolean(0));
156 case afb_auth_Token: return addperm_key_valstr(o, "session", "check");
157 case afb_auth_LOA: return addperm_key_valint(o, "LOA", auth->loa);
158 case afb_auth_Permission: return addperm_key_valstr(o, "permission", auth->text);
159 case afb_auth_Or: return addperm_key_val(o, "anyOf", addauth_or_array(json_object_new_array(), auth));
160 case afb_auth_And: return addauth(addauth(o, auth->first), auth->next);
161 case afb_auth_Not: return addperm_key_val(o, "not", addauth(NULL, auth->first));
162 case afb_auth_Yes: return addperm(o, json_object_new_boolean(1));
167 static struct json_object *addauth_or_array(struct json_object *o, const struct afb_auth *auth)
169 if (auth->type != afb_auth_Or)
170 json_object_array_add(o, addauth(NULL, auth));
172 addauth_or_array(o, auth->first);
173 addauth_or_array(o, auth->next);
179 struct json_object *afb_auth_json_v2(const struct afb_auth *auth, int session)
181 struct json_object *result = NULL;
183 if (session & AFB_SESSION_CLOSE_V2)
184 result = addperm_key_valstr(result, "session", "close");
186 if (session & AFB_SESSION_CHECK_V2)
187 result = addperm_key_valstr(result, "session", "check");
189 if (session & AFB_SESSION_REFRESH_V2)
190 result = addperm_key_valstr(result, "token", "refresh");
192 if (session & AFB_SESSION_LOA_MASK_V2)
193 result = addperm_key_valint(result, "LOA", session & AFB_SESSION_LOA_MASK_V2);
196 result = addauth(result, auth);