diff options
author | Loïc Collignon <loic.collignon@iot.bzh> | 2018-01-11 14:41:57 +0100 |
---|---|---|
committer | Loïc Collignon <loic.collignon@iot.bzh> | 2018-01-26 07:36:21 +0100 |
commit | b13719ee11e8ef5cb14e2310a12e9f790ecc7809 (patch) | |
tree | 47acdd6ccb02acdfa685b7635ef8b2d3abfabb0a /src/agl-identity-binding.c | |
parent | 786a2a295fd452aab5078ce4923cd5fcc2c1b464 (diff) |
removed unused files and useless subdirectories
Change-Id: Ie0ebe0104589ff99ae24c7410a484eeef18821e7
Signed-off-by: Loïc Collignon <loic.collignon@iot.bzh>
Diffstat (limited to 'src/agl-identity-binding.c')
-rw-r--r-- | src/agl-identity-binding.c | 333 |
1 files changed, 333 insertions, 0 deletions
diff --git a/src/agl-identity-binding.c b/src/agl-identity-binding.c new file mode 100644 index 0000000..12f43bd --- /dev/null +++ b/src/agl-identity-binding.c @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2015, 2016, 2017 "IoT.bzh" + * Author: José Bollo <jose.bollo@iot.bzh> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define _GNU_SOURCE + +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include <json-c/json.h> + +#define AFB_BINDING_VERSION 2 +#include <afb/afb-binding.h> + +#include "agl-forgerock.h" + +#ifndef NULL +#define NULL 0 +#endif + +static struct afb_event event; + +static struct json_object *current_identity; + +static const char default_vin[] = "4T1BF1FK5GU260429"; +static char *vin; + +/***** configuration ********************************************/ + +static struct json_object *readjson(int fd) +{ + char *buffer; + struct stat s; + struct json_object *result = NULL; + int rc; + + rc = fstat(fd, &s); + if (rc == 0 && S_ISREG(s.st_mode)) { + buffer = alloca((size_t)(s.st_size)+1); + if (read(fd, buffer, (size_t)s.st_size) == (ssize_t)s.st_size) { + buffer[s.st_size] = 0; + //AFB_NOTICE("Config file: %s", buffer); + result = json_tokener_parse(buffer); + //if (!result) + //{ + // AFB_ERROR("Config file is not a valid JSON: %s", json_tokener_error_desc(json_tokener_get_error(NULL))); + //} + } + } + close(fd); + + return result; +} + +static struct json_object *get_global_config(const char *name, const char *locale) +{ + int fd = afb_daemon_rootdir_open_locale(name, O_RDONLY, locale); + if (fd < 0) AFB_ERROR("Config file not found: %s", name); + return fd < 0 ? NULL : readjson(fd); +} + +static struct json_object *get_local_config(const char *name) +{ + int fd = openat(AT_FDCWD, name, O_RDONLY, 0); + return fd < 0 ? NULL : readjson(fd); +} + +static void confsetstr(struct json_object *conf, const char *name, char **value, const char *def) +{ + struct json_object *v; + const char *s; + char *p; + + s = conf && json_object_object_get_ex(conf, name, &v) ? json_object_get_string(v) : def; + p = *value; + if (s && p != s) { + *value = strdup(s); + free(p); + } +} + +static void setconfig(struct json_object *conf) +{ + if (conf) { + confsetstr(conf, "vin", &vin, vin ? : default_vin); + agl_forgerock_setconfig(conf); + } +} + +static void readconfig() +{ + setconfig(get_global_config("etc/config.json", NULL)); + setconfig(get_local_config("/etc/agl/identity-agent-config.json")); + setconfig(get_local_config("config.json")); +} + +/****************************************************************/ + +static struct json_object *make_event_object(const char *name, const char *id, const char *nick) +{ + struct json_object *object = json_object_new_object(); + + /* TODO: errors */ + json_object_object_add(object, "eventName", json_object_new_string(name)); + json_object_object_add(object, "accountid", json_object_new_string(id)); + if (nick) + json_object_object_add(object, "nickname", json_object_new_string(nick)); + return object; +} + +static int send_event_object(const char *name, const char *id, const char *nick) +{ + return afb_event_push(event, make_event_object(name, id, nick)); +} + +static void do_login(struct json_object *desc) +{ + if (current_identity == NULL && desc == NULL) return; // Switching from NULL to NULL -> do nothing + if (current_identity && desc) + { + const char* a = json_object_to_json_string(current_identity); + const char* b = json_object_to_json_string(desc); + if (strcmp(a, b) == 0) + { + AFB_NOTICE("Reloging of the same user."); + return; // Switching from one user to the same user -> do nothing + } + } + + struct json_object *object; + + /* switching the user */ + AFB_INFO("Switching to user %s", desc ? json_object_to_json_string(desc) : "null"); + object = current_identity; + current_identity = json_object_get(desc); + json_object_put(object); + + if (!json_object_object_get_ex(desc, "name", &object)) + object = 0; + send_event_object("login", !object ? "null" : json_object_get_string(object)? : "?", 0); +} + +static void do_logout() +{ + struct json_object *object; + + AFB_INFO("Switching to no user"); + object = current_identity; + current_identity = 0; + json_object_put(object); + + send_event_object("logout", "null", 0); +} + +static void on_forgerock_data(struct json_object *data, const char *error) +{ + if (error) { + AFB_ERROR("Can't get data: %s", error); + } else { + do_login(data); + } +} + +/****************************************************************/ + +static void subscribe (struct afb_req request) +{ + int rc; + + rc = afb_req_subscribe(request, event); + if (rc < 0) + afb_req_fail(request, "failed", "subscribtion failed"); + else + afb_req_success(request, NULL, NULL); +} + +static void unsubscribe (struct afb_req request) +{ + afb_req_unsubscribe(request, event); + afb_req_success(request, NULL, NULL); +} + +static void logout (struct afb_req request) +{ + do_logout(); + afb_req_success(request, NULL, NULL); +} + +static void fake_login (struct afb_req request) +{ + struct json_object *desc = afb_req_json(request); + do_logout(); + if (desc) + do_login(desc); + afb_req_success(request, NULL, NULL); +} + +static void get (struct afb_req request) +{ + afb_req_success(request, json_object_get(current_identity), NULL); +} + +static void on_nfc_subscribed(void *closure, int status, struct json_object *result) +{ + if(status) + AFB_ERROR("Failed to subscribe to nfc events."); +} + +static void on_nfc_started(void *closure, int status, struct json_object *result) +{ + if (!status) { + afb_service_call("nfc", "subscribe", NULL, on_nfc_subscribed, NULL); + } + else + AFB_ERROR("Failed to start nfc polling."); +} + +static int service_init() +{ + agl_forgerock_setcb(on_forgerock_data); + event = afb_daemon_make_event("event"); + if (!afb_event_is_valid(event)) + return -1; + + readconfig(); + + if (afb_daemon_require_api("nfc", 1)) + return -1; + + if (afb_daemon_require_api("persistence", 1)) + return -1; + + afb_service_call("nfc", "start", NULL, on_nfc_started, NULL); + + return 0; +} + +static void on_nfc_target_add(struct json_object *object) +{ + struct json_object * json_uid; + const char *uid; + + if (json_object_object_get_ex(object, "UID", &json_uid)) + { + uid = json_object_get_string(json_uid); + AFB_NOTICE("nfc tag detected, call forgerock with vincode=%s and key=%s", vin ? vin : default_vin, uid); + send_event_object("incoming", uid, uid); + agl_forgerock_download_request(vin ? vin : default_vin, "nfc", uid); + } + else AFB_ERROR("nfc target add event is received but no UID found: %s", json_object_to_json_string(object)); +} + +static void onevent(const char *event, struct json_object *object) +{ + AFB_NOTICE("Received event: %s", event); + if (!strcmp("nfc/on-nfc-target-add", event)) + { + on_nfc_target_add(object); + return; + } + AFB_WARNING("Unhandled event: %s", event); +} + +static void fake_auth(struct afb_req req) +{ + struct json_object* req_object; + struct json_object* kind_object; + struct json_object* key_object; + + req_object = afb_req_json(req); + + if (!json_object_object_get_ex(req_object, "kind", &kind_object)) + { + afb_req_fail(req, "Missing arg: kind", NULL); + return; + } + + if (!json_object_object_get_ex(req_object, "key", &key_object)) + { + afb_req_fail(req, "Missing arg: key", NULL); + return; + } + + const char* kind = json_object_get_string(kind_object); + const char* key = json_object_get_string(key_object); + + send_event_object("incoming", key, key); + agl_forgerock_download_request(vin ? vin : default_vin, kind, key); + + afb_req_success(req, NULL, "fake auth success!"); +} + +// NOTE: this sample does not use session to keep test a basic as possible +// in real application most APIs should be protected with AFB_SESSION_CHECK +static const struct afb_verb_v2 verbs[]= +{ + {"subscribe" , subscribe , NULL, "subscribe to events" , AFB_SESSION_NONE }, + {"unsubscribe", unsubscribe , NULL, "unsubscribe to events" , AFB_SESSION_NONE }, + {"fake-login" , fake_login , NULL, "fake a login" , AFB_SESSION_NONE }, + {"logout" , logout , NULL, "log the current user out", AFB_SESSION_NONE }, + {"get" , get , NULL, "get data" , AFB_SESSION_NONE }, + {"fake-auth" , fake_auth , NULL, "fake an authentication" , AFB_SESSION_NONE }, + {NULL} +}; + +const struct afb_binding_v2 afbBindingV2 = +{ + .api = "identity", + .specification = NULL, + .info = "AGL identity service", + .verbs = verbs, + .preinit = NULL, + .init = service_init, + .onevent = onevent, + .noconcurrency = 0 +}; + +/* vim: set colorcolumn=80: */ |