X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-hreq.c;h=7e3d7ceb9f38591fc08b73c7c4a358c4de97f738;hb=65353dce81a629e042800bb7b86fcd869a76727e;hp=462f7ad5369582ee7dbabe6e9dc62993d7ca94ed;hpb=1b240e6b92eb3762594312cc603180ae5ce77f72;p=src%2Fapp-framework-binder.git diff --git a/src/afb-hreq.c b/src/afb-hreq.c index 462f7ad5..7e3d7ceb 100644 --- a/src/afb-hreq.c +++ b/src/afb-hreq.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2019 "IoT.bzh" + * Copyright (C) 2015-2020 "IoT.bzh" * Author: José Bollo * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -42,7 +42,8 @@ #include "afb-hreq.h" #include "afb-hsrv.h" #include "afb-session.h" -#include "afb-cred.h" +#include "afb-token.h" +#include "afb-error-text.h" #include "verbose.h" #include "locale-root.h" @@ -61,6 +62,9 @@ static const char short_key_for_token[] = "token"; static const char long_key_for_reqid[] = "x-afb-reqid"; static const char short_key_for_reqid[] = "reqid"; +static const char key_for_bearer[] = "Bearer"; +static const char key_for_access_token[] = "access_token"; + static char *cookie_name = NULL; static char *cookie_setter = NULL; static char *tmp_pattern = NULL; @@ -163,7 +167,8 @@ static void afb_hreq_reply_v(struct afb_hreq *hreq, unsigned status, struct MHD_ MHD_add_response_header(response, k, v); k = va_arg(args, const char *); } - v = afb_context_sent_uuid(&hreq->xreq.context); + + v = afb_context_uuid(&hreq->xreq.context); if (v != NULL && asprintf(&cookie, cookie_setter, v) > 0) { MHD_add_response_header(response, MHD_HTTP_HEADER_SET_COOKIE, cookie); free(cookie); @@ -339,7 +344,6 @@ static void req_destroy(struct afb_xreq *xreq) json_object_put(hreq->json); free((char*)hreq->xreq.request.called_api); free((char*)hreq->xreq.request.called_verb); - afb_cred_unref(hreq->xreq.cred); free(hreq); } @@ -738,11 +742,10 @@ const char *afb_hreq_get_header(struct afb_hreq *hreq, const char *name) const char *afb_hreq_get_authorization_bearer(struct afb_hreq *hreq) { - static const char bearer[] = "Bearer"; const char *value = afb_hreq_get_header(hreq, MHD_HTTP_HEADER_AUTHORIZATION); if (value) { - if (strncasecmp(value, bearer, sizeof bearer - 1) == 0) { - value += sizeof bearer - 1; + if (strncasecmp(value, key_for_bearer, sizeof key_for_bearer - 1) == 0) { + value += sizeof key_for_bearer - 1; if (isblank(*value++)) { while (isblank(*value)) value++; @@ -917,9 +920,13 @@ static struct json_object *req_json(struct afb_xreq *xreq) return obj; } +static inline const char *get_json_string(json_object *obj) +{ + return json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN|JSON_C_TO_STRING_NOSLASHESCAPE); +} static ssize_t send_json_cb(json_object *obj, uint64_t pos, char *buf, size_t max) { - ssize_t len = stpncpy(buf, json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN|JSON_C_TO_STRING_NOSLASHESCAPE)+pos, max) - buf; + ssize_t len = stpncpy(buf, get_json_string(obj)+pos, max) - buf; return len ? : (ssize_t)MHD_CONTENT_READER_END_OF_STREAM; } @@ -940,8 +947,20 @@ static void req_reply(struct afb_xreq *xreq, struct json_object *object, const c if (reqid != NULL && json_object_object_get_ex(reply, "request", &sub)) json_object_object_add(sub, "reqid", json_object_new_string(reqid)); - response = MHD_create_response_from_callback((uint64_t)strlen(json_object_to_json_string_ext(reply, JSON_C_TO_STRING_PLAIN|JSON_C_TO_STRING_NOSLASHESCAPE)), SIZE_RESPONSE_BUFFER, (void*)send_json_cb, reply, (void*)json_object_put); - afb_hreq_reply(hreq, MHD_HTTP_OK, response, NULL); + response = MHD_create_response_from_callback( + (uint64_t)strlen(get_json_string(reply)), + SIZE_RESPONSE_BUFFER, + (void*)send_json_cb, + reply, + (void*)json_object_put); + + /* handle authorisation feedback */ + if (error == afb_error_text_invalid_token) + afb_hreq_reply(hreq, MHD_HTTP_UNAUTHORIZED, response, MHD_HTTP_HEADER_WWW_AUTHENTICATE, "error=\"invalid_token\"", NULL); + else if (error == afb_error_text_insufficient_scope) + afb_hreq_reply(hreq, MHD_HTTP_FORBIDDEN, response, MHD_HTTP_HEADER_WWW_AUTHENTICATE, "error=\"insufficient_scope\"", NULL); + else + afb_hreq_reply(hreq, MHD_HTTP_OK, response, NULL); } void afb_hreq_call(struct afb_hreq *hreq, struct afb_apiset *apiset, const char *api, size_t lenapi, const char *verb, size_t lenverb) @@ -963,6 +982,7 @@ int afb_hreq_init_context(struct afb_hreq *hreq) { const char *uuid; const char *token; + struct afb_token *tok; if (hreq->xreq.context.session != NULL) return 0; @@ -981,15 +1001,21 @@ int afb_hreq_init_context(struct afb_hreq *hreq) /* get the authorisation token */ token = afb_hreq_get_authorization_bearer(hreq); if (token == NULL) { - token = afb_hreq_get_header(hreq, long_key_for_token); + token = afb_hreq_get_argument(hreq, key_for_access_token); if (token == NULL) { - token = afb_hreq_get_argument(hreq, long_key_for_token); - if (token == NULL) - token = afb_hreq_get_argument(hreq, short_key_for_token); + token = afb_hreq_get_header(hreq, long_key_for_token); + if (token == NULL) { + token = afb_hreq_get_argument(hreq, long_key_for_token); + if (token == NULL) + token = afb_hreq_get_argument(hreq, short_key_for_token); + } } } + tok = NULL; + if (token) + afb_token_get(&tok, token); - return afb_context_connect(&hreq->xreq.context, uuid, token); + return afb_context_connect(&hreq->xreq.context, uuid, tok, NULL); } int afb_hreq_init_cookie(int port, const char *path, int maxage)