2 * Copyright (C) 2015-2019 "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.
26 #include "afb-session.h"
27 #include "afb-context.h"
28 #include "afb-token.h"
30 #include "afb-permission-text.h"
33 static void init_context(struct afb_context *context, struct afb_session *session, struct afb_token *token, struct afb_cred *cred)
35 assert(session != NULL);
37 /* reset the context for the session */
38 context->session = session;
40 context->super = NULL;
41 context->api_key = NULL;
42 context->token = afb_token_addref(token);
43 context->credentials = afb_cred_addref(cred);
46 void afb_context_subinit(struct afb_context *context, struct afb_context *super)
48 context->session = afb_session_addref(super->session);
50 context->super = super;
51 context->api_key = NULL;
52 context->token = afb_token_addref(super->token);
53 context->credentials = afb_cred_addref(super->credentials);
56 void afb_context_init(struct afb_context *context, struct afb_session *session, struct afb_token *token, struct afb_cred *cred)
58 init_context(context, afb_session_addref(session), token, cred);
61 int afb_context_connect(struct afb_context *context, const char *uuid, struct afb_token *token, struct afb_cred *cred)
64 struct afb_session *session;
66 session = afb_session_get (uuid, AFB_SESSION_TIMEOUT_DEFAULT, &created);
69 init_context(context, session, token, cred);
76 int afb_context_connect_validated(struct afb_context *context, const char *uuid, struct afb_token *token, struct afb_cred *cred)
78 int rc = afb_context_connect(context, uuid, token, cred);
80 context->validated = 1;
84 void afb_context_init_validated(struct afb_context *context, struct afb_session *session, struct afb_token *token, struct afb_cred *cred)
86 afb_context_init(context, session, token, cred);
87 context->validated = 1;
90 void afb_context_disconnect(struct afb_context *context)
92 if (context->session && !context->super && context->closing && !context->closed) {
93 afb_context_change_loa(context, 0);
94 afb_context_set(context, NULL, NULL);
97 afb_session_unref(context->session);
98 context->session = NULL;
99 afb_cred_unref(context->credentials);
100 context->credentials = NULL;
101 afb_token_unref(context->token);
102 context->token = NULL;
105 void afb_context_change_cred(struct afb_context *context, struct afb_cred *cred)
107 struct afb_cred *ocred = context->credentials;
109 context->credentials = afb_cred_addref(cred);
110 afb_cred_unref(ocred);
114 void afb_context_change_token(struct afb_context *context, struct afb_token *token)
116 struct afb_token *otoken = context->token;
117 if (otoken != token) {
118 context->token = afb_token_addref(token);
119 afb_token_unref(otoken);
123 const char *afb_context_on_behalf_export(struct afb_context *context)
125 return context->credentials ? afb_cred_export(context->credentials) : NULL;
128 int afb_context_on_behalf_import(struct afb_context *context, const char *exported)
131 struct afb_cred *imported, *ocred;
133 if (!exported || !*exported)
136 if (afb_context_has_permission(context, afb_permission_on_behalf_credential)) {
137 imported = afb_cred_import(exported);
139 ERROR("Can't import on behalf credentials: %m");
142 ocred = context->credentials;
143 context->credentials = imported;
144 afb_cred_unref(ocred);
148 ERROR("On behalf credentials refused");
155 void afb_context_on_behalf_other_context(struct afb_context *context, struct afb_context *other)
157 afb_context_change_cred(context, other->credentials);
158 afb_context_change_token(context, other->token);
161 int afb_context_has_permission(struct afb_context *context, const char *permission)
163 return afb_cred_has_permission(context->credentials, permission, context);
166 const char *afb_context_uuid(struct afb_context *context)
168 return context->session ? afb_session_uuid(context->session) : NULL;
171 void *afb_context_make(struct afb_context *context, int replace, void *(*make_value)(void *closure), void (*free_value)(void *item), void *closure)
173 assert(context->session != NULL);
174 return afb_session_cookie(context->session, context->api_key, make_value, free_value, closure, replace);
177 void *afb_context_get(struct afb_context *context)
179 assert(context->session != NULL);
180 return afb_session_get_cookie(context->session, context->api_key);
183 int afb_context_set(struct afb_context *context, void *value, void (*free_value)(void*))
185 assert(context->session != NULL);
186 return afb_session_set_cookie(context->session, context->api_key, value, free_value);
189 void afb_context_close(struct afb_context *context)
191 context->closing = 1;
194 int afb_context_check(struct afb_context *context)
198 if (context->validated)
200 else if (context->invalidated)
204 r = afb_context_check(context->super);
206 r = afb_context_has_permission(context, afb_permission_token_valid);
208 context->validated = 1;
210 context->invalidated = 1;
215 static inline const void *loa_key(struct afb_context *context)
217 return (const void*)(1+(intptr_t)(context->api_key));
220 static inline void *loa2ptr(unsigned loa)
222 return (void*)(intptr_t)loa;
225 static inline unsigned ptr2loa(void *ptr)
227 return (unsigned)(intptr_t)ptr;
230 int afb_context_change_loa(struct afb_context *context, unsigned loa)
236 if (!afb_context_check(context)) {
241 return afb_session_set_cookie(context->session, loa_key(context), loa2ptr(loa), NULL);
244 unsigned afb_context_get_loa(struct afb_context *context)
246 assert(context->session != NULL);
247 return ptr2loa(afb_session_get_cookie(context->session, loa_key(context)));
250 int afb_context_check_loa(struct afb_context *context, unsigned loa)
252 return afb_context_get_loa(context) >= loa;