From 15efef0b066a1416778a304ed41cdf3ecb3209ef Mon Sep 17 00:00:00 2001 From: Romain Forlot Date: Mon, 18 Dec 2017 16:40:50 +0100 Subject: More security to add new signals/source at runtime Also renamed loadConf to addObjects to avoid confusion with loadConf at init time. Improve file research if fullpath not procided by searching in the CONTROL_CONFIG_PATH. Change-Id: I8e541ff7437f0378bcdc7215ff9f391dcce6db9f Signed-off-by: Romain Forlot --- signal-composer-binding/signal-composer-apidef.h | 55 +++++++++++++--------- .../signal-composer-apidef.json | 20 +++++--- .../signal-composer-binding.cpp | 9 +++- signal-composer-binding/signal-composer.cpp | 11 +++-- 4 files changed, 61 insertions(+), 34 deletions(-) diff --git a/signal-composer-binding/signal-composer-apidef.h b/signal-composer-binding/signal-composer-apidef.h index abd0539..3f10fa5 100644 --- a/signal-composer-binding/signal-composer-apidef.h +++ b/signal-composer-binding/signal-composer-apidef.h @@ -21,31 +21,40 @@ static const char _afb_description_v2_signal_composer[] = "ct\"}}},\"afb-event-v2\":{\"type\":\"object\",\"required\":[\"jtype\",\"" "event\"],\"properties\":{\"jtype\":{\"type\":\"string\",\"const\":\"afb-" "event\"},\"event\":{\"type\":\"string\"},\"data\":{\"type\":\"object\"}}" - "}},\"x-permissions\":{},\"responses\":{\"200\":{\"description\":\"A comp" - "lex object array response\",\"content\":{\"application/json\":{\"schema\"" - ":{\"$ref\":\"#/components/schemas/afb-reply\"}}}}}},\"paths\":{\"/subscr" - "ibe\":{\"description\":\"Subscribe to a signal object\",\"parameters\":[" - "{\"in\":\"query\",\"name\":\"event\",\"required\":false,\"schema\":{\"ty" - "pe\":\"string\"}}],\"responses\":{\"200\":{\"$ref\":\"#/components/respo" - "nses/200\"}}},\"/unsubscribe\":{\"description\":\"Unsubscribe previously" - " suscribed signal objects.\",\"parameters\":[{\"in\":\"query\",\"name\":" - "\"event\",\"required\":false,\"schema\":{\"type\":\"string\"}}],\"respon" - "ses\":{\"200\":{\"$ref\":\"#/components/responses/200\"}}},\"/get\":{\"d" - "escription\":\"Get informations about a resource or element\",\"response" - "s\":{\"200\":{\"$ref\":\"#/components/responses/200\"}}},\"/list\":{\"de" - "scription\":\"List all signals already configured\",\"responses\":{\"200" - "\":{\"$ref\":\"#/components/responses/200\"}}},\"/loadConf\":{\"descript" - "ion\":\"Load config file in directory passed as argument searching for p" - "attern 'sig' in filename\",\"parameters\":[{\"in\":\"query\",\"name\":\"" - "path\",\"required\":true,\"schema\":{\"type\":\"string\"}}],\"responses\"" - ":{\"200\":{\"$ref\":\"#/components/responses/200\"}}}}}" + "}},\"x-permissions\":{\"addObjects\":{\"permission\":\"urn:AGL:permissio" + "n::platform:composer:addObjects\"}},\"responses\":{\"200\":{\"descriptio" + "n\":\"A complex object array response\",\"content\":{\"application/json\"" + ":{\"schema\":{\"$ref\":\"#/components/schemas/afb-reply\"}}}}}},\"paths\"" + ":{\"/subscribe\":{\"description\":\"Subscribe to a signal object\",\"par" + "ameters\":[{\"in\":\"query\",\"name\":\"event\",\"required\":false,\"sch" + "ema\":{\"type\":\"string\"}}],\"responses\":{\"200\":{\"$ref\":\"#/compo" + "nents/responses/200\"}}},\"/unsubscribe\":{\"description\":\"Unsubscribe" + " previously suscribed signal objects.\",\"parameters\":[{\"in\":\"query\"" + ",\"name\":\"event\",\"required\":false,\"schema\":{\"type\":\"string\"}}" + "],\"responses\":{\"200\":{\"$ref\":\"#/components/responses/200\"}}},\"/" + "get\":{\"description\":\"Get informations about a resource or element\"," + "\"responses\":{\"200\":{\"$ref\":\"#/components/responses/200\"}}},\"/li" + "st\":{\"description\":\"List all signals already configured\",\"response" + "s\":{\"200\":{\"$ref\":\"#/components/responses/200\"}}},\"/addObjects\"" + ":{\"description\":\"Load new objects from an additional config file desi" + "gnated by JSON argument with the key 'file'.\",\"get\":{\"x-permissions\"" + ":{\"$ref\":\"#/components/x-permissions/addObjects\"},\"responses\":{\"2" + "00\":{\"$ref\":\"#/components/responses/200\"}}},\"parameters\":[{\"in\"" + ":\"query\",\"name\":\"path\",\"required\":true,\"schema\":{\"type\":\"st" + "ring\"}}]}}}" ; +#ifdef __cplusplus +#include +#endif +static const struct afb_auth _afb_auths_v2_signal_composer[] = { + afb::auth_permission("urn:AGL:permission::platform:composer:addObjects") +}; void subscribe(struct afb_req req); void unsubscribe(struct afb_req req); void get(struct afb_req req); void list(struct afb_req req); - void loadConf(struct afb_req req); + void addObjects(struct afb_req req); static const struct afb_verb_v2 _afb_verbs_v2_signal_composer[] = { { @@ -77,10 +86,10 @@ static const struct afb_verb_v2 _afb_verbs_v2_signal_composer[] = { .session = AFB_SESSION_NONE_V2 }, { - .verb = "loadConf", - .callback = loadConf, - .auth = NULL, - .info = "Load config file in directory passed as argument searching for pattern 'sig' in filename", + .verb = "addObjects", + .callback = addObjects, + .auth = &_afb_auths_v2_signal_composer[0], + .info = "Load new objects from an additional config file designated by JSON argument with the key 'file'.", .session = AFB_SESSION_NONE_V2 }, { diff --git a/signal-composer-binding/signal-composer-apidef.json b/signal-composer-binding/signal-composer-apidef.json index fffeda3..cf45aec 100644 --- a/signal-composer-binding/signal-composer-apidef.json +++ b/signal-composer-binding/signal-composer-apidef.json @@ -82,6 +82,9 @@ } }, "x-permissions": { + "addObjects": { + "permission": "urn:AGL:permission::platform:composer:addObjects" + } }, "responses": { "200": { @@ -137,8 +140,16 @@ "200": {"$ref": "#/components/responses/200"} } }, - "/loadConf": { - "description": "Load config file in directory passed as argument searching for pattern 'sig' in filename", + "/addObjects": { + "description": "Load new objects from an additional config file designated by JSON argument with the key 'file'.", + "get": { + "x-permissions": { + "$ref": "#/components/x-permissions/addObjects" + }, + "responses": { + "200": {"$ref": "#/components/responses/200"} + } + }, "parameters": [ { "in": "query", @@ -146,10 +157,7 @@ "required": true, "schema": { "type": "string"} } - ], - "responses": { - "200": {"$ref": "#/components/responses/200"} - } + ] } } } diff --git a/signal-composer-binding/signal-composer-binding.cpp b/signal-composer-binding/signal-composer-binding.cpp index d9f1f01..9afed5a 100644 --- a/signal-composer-binding/signal-composer-binding.cpp +++ b/signal-composer-binding/signal-composer-binding.cpp @@ -168,7 +168,7 @@ void unsubscribe(afb_req request) } /// @brief verb that loads JSON configuration (old SigComp.json file now) -void loadConf(afb_req request) +void addObjects(afb_req request) { Composer& composer = Composer::instance(); json_object *sourcesJ = nullptr, @@ -178,6 +178,13 @@ void loadConf(afb_req request) if(filepath) { json_object *fileJ = json_object_from_file(filepath); + if(!fileJ) + { + json_object* responseJ = ScanForConfig(CONTROL_CONFIG_PATH, CTL_SCAN_RECURSIVE, filepath, ".json"); + filepath = ConfigSearch(nullptr, responseJ); + if(filepath) + {fileJ = json_object_from_file(filepath);} + } json_object_object_get_ex(fileJ, "sources", &sourcesJ); json_object_object_get_ex(fileJ, "signals", &signalsJ); diff --git a/signal-composer-binding/signal-composer.cpp b/signal-composer-binding/signal-composer.cpp index 7ba9c27..17ba16f 100644 --- a/signal-composer-binding/signal-composer.cpp +++ b/signal-composer-binding/signal-composer.cpp @@ -264,7 +264,6 @@ int Composer::pluginsLoad(AFB_ApiT apiHandle, CtlSectionT *section, json_object } else { - completePluginsJ = json_object_new_array(); json_object_array_add(completePluginsJ, pluginsJ); json_object_array_add(completePluginsJ, builtinJ); @@ -343,6 +342,7 @@ int Composer::loadSourcesAPI(AFB_ApiT apihandle, CtlSectionT* section, json_obje if(sourcesJ) { + int count = 1; json_object *sigCompJ = nullptr; // add the signal composer itself as source wrap_json_pack(&sigCompJ, "{ss,ss,ss}", @@ -355,7 +355,7 @@ int Composer::loadSourcesAPI(AFB_ApiT apihandle, CtlSectionT* section, json_obje if (json_object_get_type(sourcesJ) == json_type_array) { - int count = json_object_array_length(sourcesJ); + count = json_object_array_length(sourcesJ); for (int idx = 0; idx < count; idx++) { @@ -369,6 +369,7 @@ int Composer::loadSourcesAPI(AFB_ApiT apihandle, CtlSectionT* section, json_obje if ((err = composer.loadOneSourceAPI(sourcesJ))) return err; if (sigCompJ && (err = composer.loadOneSourceAPI(sigCompJ))) return err; } + AFB_NOTICE("%d new sources added to service", count); } else {Composer::instance().initSourcesAPI();} @@ -480,6 +481,7 @@ int Composer::loadOneSignal(json_object* signalJ) // Overwrite uid to the signal one instead of the default if(onReceivedCtl) {onReceivedCtl->uid = uid;} + int count = 1; } else {onReceivedCtl = convert2Action(uid, onReceivedJ);} @@ -498,10 +500,10 @@ int Composer::loadSignals(AFB_ApiT apihandle, CtlSectionT* section, json_object if(signalsJ) { + int count = 1; if (json_object_get_type(signalsJ) == json_type_array) { - int count = json_object_array_length(signalsJ); - + count = json_object_array_length(signalsJ); for (int idx = 0; idx < count; idx++) { json_object *signalJ = json_object_array_get_idx(signalsJ, idx); @@ -510,6 +512,7 @@ int Composer::loadSignals(AFB_ApiT apihandle, CtlSectionT* section, json_object } else {err = composer.loadOneSignal(signalsJ);} + AFB_NOTICE("%d new signals added to service", count); } return err; -- cgit 1.2.3-korg