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);
47 if (afb_token_check(token))
48 context->validated = 1;
50 context->invalidated = 1;
54 void afb_context_init(struct afb_context *context, struct afb_session *session, struct afb_token *token, struct afb_cred *cred)
56 init_context(context, afb_session_addref(session), token, cred);
59 void afb_context_init_validated(struct afb_context *context, struct afb_session *session, struct afb_token *token, struct afb_cred *cred)
61 afb_context_init(context, session, token, cred);
62 context->validated = 1;
65 void afb_context_subinit(struct afb_context *context, struct afb_context *super)
67 context->session = afb_session_addref(super->session);
69 context->super = super;
70 context->api_key = NULL;
71 context->token = afb_token_addref(super->token);
72 context->credentials = afb_cred_addref(super->credentials);
75 int afb_context_connect(struct afb_context *context, const char *uuid, struct afb_token *token, struct afb_cred *cred)
78 struct afb_session *session;
80 session = afb_session_get (uuid, AFB_SESSION_TIMEOUT_DEFAULT, &created);
83 init_context(context, session, token, cred);
90 int afb_context_connect_validated(struct afb_context *context, const char *uuid, struct afb_token *token, struct afb_cred *cred)
92 int rc = afb_context_connect(context, uuid, token, cred);
94 context->validated = 1;
98 void afb_context_disconnect(struct afb_context *context)
100 if (context->session && !context->super && context->closing && !context->closed) {
101 afb_context_change_loa(context, 0);
102 afb_context_set(context, NULL, NULL);
105 afb_session_unref(context->session);
106 context->session = NULL;
107 afb_cred_unref(context->credentials);
108 context->credentials = NULL;
109 afb_token_unref(context->token);
110 context->token = NULL;
113 void afb_context_change_cred(struct afb_context *context, struct afb_cred *cred)
115 struct afb_cred *ocred = context->credentials;
117 context->credentials = afb_cred_addref(cred);
118 afb_cred_unref(ocred);
122 void afb_context_change_token(struct afb_context *context, struct afb_token *token)
124 struct afb_token *otoken = context->token;
125 if (otoken != token) {
126 context->validated = 0;
127 context->invalidated = 0;
128 context->token = afb_token_addref(token);
129 afb_token_unref(otoken);
133 const char *afb_context_on_behalf_export(struct afb_context *context)
135 return context->credentials ? afb_cred_export(context->credentials) : NULL;
138 int afb_context_on_behalf_import(struct afb_context *context, const char *exported)
141 struct afb_cred *imported, *ocred;
143 if (!exported || !*exported)
146 if (afb_context_has_permission(context, afb_permission_on_behalf_credential)) {
147 imported = afb_cred_import(exported);
149 ERROR("Can't import on behalf credentials: %m");
152 ocred = context->credentials;
153 context->credentials = imported;
154 afb_cred_unref(ocred);
158 ERROR("On behalf credentials refused");
165 void afb_context_on_behalf_other_context(struct afb_context *context, struct afb_context *other)
167 afb_context_change_cred(context, other->credentials);
168 afb_context_change_token(context, other->token);
171 int afb_context_has_permission(struct afb_context *context, const char *permission)
173 return afb_cred_has_permission(context->credentials, permission, context);
176 const char *afb_context_uuid(struct afb_context *context)
178 return context->session ? afb_session_uuid(context->session) : NULL;
181 void *afb_context_make(struct afb_context *context, int replace, void *(*make_value)(void *closure), void (*free_value)(void *item), void *closure)
183 assert(context->session != NULL);
184 return afb_session_cookie(context->session, context->api_key, make_value, free_value, closure, replace);
187 void *afb_context_get(struct afb_context *context)
189 assert(context->session != NULL);
190 return afb_session_get_cookie(context->session, context->api_key);
193 int afb_context_set(struct afb_context *context, void *value, void (*free_value)(void*))
195 assert(context->session != NULL);
196 return afb_session_set_cookie(context->session, context->api_key, value, free_value);
199 void afb_context_close(struct afb_context *context)
201 context->closing = 1;
204 int afb_context_check(struct afb_context *context)
207 return afb_context_check(context);
208 return context->validated;
211 int afb_context_check_loa(struct afb_context *context, unsigned loa)
213 return afb_context_get_loa(context) >= loa;
216 static inline const void *loa_key(struct afb_context *context)
218 return (const void*)(1+(intptr_t)(context->api_key));
221 static inline void *loa2ptr(unsigned loa)
223 return (void*)(intptr_t)loa;
226 static inline unsigned ptr2loa(void *ptr)
228 return (unsigned)(intptr_t)ptr;
231 int afb_context_change_loa(struct afb_context *context, unsigned loa)
233 if (!context->validated || loa > 7) {
238 return afb_session_set_cookie(context->session, loa_key(context), loa2ptr(loa), NULL);
241 unsigned afb_context_get_loa(struct afb_context *context)
243 assert(context->session != NULL);
244 return ptr2loa(afb_session_get_cookie(context->session, loa_key(context)));