summaryrefslogtreecommitdiffstats
path: root/src/agl-identity-binding.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/agl-identity-binding.c')
-rw-r--r--src/agl-identity-binding.c245
1 files changed, 148 insertions, 97 deletions
diff --git a/src/agl-identity-binding.c b/src/agl-identity-binding.c
index 70c195c..f246ea9 100644
--- a/src/agl-identity-binding.c
+++ b/src/agl-identity-binding.c
@@ -16,6 +16,7 @@
*/
#define _GNU_SOURCE
+#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
@@ -29,15 +30,21 @@
#include "agl-forgerock.h"
+static afb_api_t this_api;
static afb_event_t event;
+
static json_object *current_identity;
/* default vin corresponds to Toyota Camry 2016, 429 */
static const char default_vin[] = "4T1BF1FK5GU260429";
static char *vin;
-/***** configuration ********************************************/
+afb_api_t get_local_api(void)
+{
+ return this_api;
+}
+/***** configuration from file **********************************/
static struct json_object *readjson(int fd)
{
char *buffer;
@@ -50,12 +57,7 @@ static struct json_object *readjson(int fd)
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_API_NOTICE(afbBindingV3root, "Config file: %s", buffer);
result = json_tokener_parse(buffer);
- //if (!result)
- //{
- // AFB_API_ERROR(afbBindingV3root, "Config file is not a valid JSON: %s", json_tokener_error_desc(json_tokener_get_error(NULL)));
- //}
}
}
close(fd);
@@ -66,7 +68,7 @@ static struct json_object *readjson(int fd)
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_API_ERROR(afbBindingV3root, "Config file not found: %s", name);
+ if (fd < 0) AFB_API_ERROR(this_api, "Config file not found: %s", name);
return fd < 0 ? NULL : readjson(fd);
}
@@ -83,7 +85,8 @@ static void confsetstr(struct json_object *conf, const char *name,
const char *s;
char *p;
- s = conf && json_object_object_get_ex(conf, name, &v) ? json_object_get_string(v) : def;
+ 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);
@@ -108,11 +111,16 @@ static void readconfig()
/****************************************************************/
-static struct json_object *make_event_object(const char *name, const char *id, const char *nick)
+static struct json_object *make_event_object(const char *name,
+ const char *id,
+ const char *nick)
{
- struct json_object *object = json_object_new_object();
+ struct json_object *object;
- /* TODO: errors */
+ if (!name || !id )
+ return NULL;
+
+ object = json_object_new_object();
json_object_object_add(object, "eventName", json_object_new_string(name));
json_object_object_add(object, "accountid", json_object_new_string(id));
if (nick)
@@ -127,39 +135,44 @@ static int send_event_object(const char *name, const char *id, const char *nick)
static void do_login(struct json_object *desc)
{
- if (current_identity == NULL && desc == NULL) return; // Switching from NULL to NULL -> do nothing
+ /* if switching from NULL to NULL -> do nothing */
+ if (current_identity == NULL && desc == NULL) return;
+
+ /* if switching from one user to the same user -> 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_API_NOTICE(afbBindingV3root, "Reloging of the same user.");
- return; // Switching from one user to the same user -> do nothing
+ AFB_API_NOTICE(this_api, "re-logging the same user!");
+ return;
}
}
struct json_object *object;
- /* switching the user */
- AFB_API_INFO(afbBindingV3root, "Switching to user %s",
+ /* switching to a different user */
+ AFB_API_INFO(this_api, "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);
+ object = NULL;
+ send_event_object("login",
+ !object ? "null" : json_object_get_string(object)? : "?",
+ 0);
}
static void do_logout()
{
struct json_object *object;
- AFB_API_INFO(afbBindingV3root, "Switching to no user");
+ AFB_API_INFO(this_api, "Switching to no user");
object = current_identity;
- current_identity = 0;
+ current_identity = NULL;
json_object_put(object);
send_event_object("logout", "null", 0);
@@ -168,50 +181,12 @@ static void do_logout()
static void on_forgerock_data(struct json_object *data, const char *error)
{
if (error) {
- AFB_API_ERROR(afbBindingV3root, "Can't get data: %s", error);
+ AFB_API_ERROR(this_api, "Can't get data: %s", error);
} else {
do_login(data);
}
}
-/****************************************************************/
-
-static void subscribe (afb_req_t request)
-{
- if (afb_req_subscribe(request, event)) {
- AFB_REQ_ERROR(request, "subscribe error");
- afb_req_reply(request, NULL, "failed", "subscribtion failed");
- }
- else
- afb_req_reply(request, NULL, NULL, NULL);
-}
-
-static void unsubscribe (afb_req_t request)
-{
- afb_req_unsubscribe(request, event);
- afb_req_reply(request, NULL, NULL, NULL);
-}
-
-static void logout (afb_req_t request)
-{
- do_logout();
- afb_req_reply(request, NULL, NULL, NULL);
-}
-
-static void fake_login (afb_req_t request)
-{
- struct json_object *desc = afb_req_json(request);
- do_logout();
- if (desc)
- do_login(desc);
- afb_req_reply(request, NULL, NULL, NULL);
-}
-
-static void get (afb_req_t request)
-{
- afb_req_reply(request, json_object_get(current_identity), NULL, NULL);
-}
-
static void on_nfc_subscribed(void *closure, struct json_object *result,
const char *error, const char *info,
afb_api_t api)
@@ -225,48 +200,77 @@ static void on_nfc_subscribed(void *closure, struct json_object *result,
static int service_init(afb_api_t api)
{
struct json_object *jrequest = NULL;
+ int ret;
- agl_forgerock_setcb(on_forgerock_data);
+ this_api = api;
- event = afb_api_make_event(api, "event");
- if (!afb_event_is_valid(event)) {
- AFB_API_ERROR(api, "Failed to create event");
- return -1;
+ ret = afb_api_require_api(this_api, "nfc", 1);
+ if (ret < 0) {
+ AFB_API_ERROR(this_api, "nfc api not available");
+ goto out;
}
-
- readconfig();
- if (afb_api_require_api(api, "nfc", 1))
- return -1;
+ ret = afb_api_require_api(this_api, "persistence", 1);
+ if (ret < 0) {
+ AFB_API_ERROR(this_api, "persistence api not available");
+ goto out;
+ }
- if (afb_api_require_api(api, "persistence", 1))
- return -1;
+ event = afb_api_make_event(this_api, "event");
+ if (!afb_event_is_valid(event)) {
+ AFB_API_ERROR(this_api, "Failed to create event");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ readconfig();
+ agl_forgerock_setcb(on_forgerock_data);
jrequest = json_object_new_object();
json_object_object_add(jrequest, "value", json_object_new_string("presence"));
-
afb_api_call(api, "nfc", "subscribe", jrequest, on_nfc_subscribed, NULL);
- return 0;
+out:
+ return ret;
}
static void on_nfc_target_add(struct json_object *object)
{
- struct json_object * json_uid;
+ struct json_object *json_status;
+ struct json_object *json_uid;
const char *uid;
+
+ if (!object) {
+ AFB_API_ERROR(this_api, "nfc/presence empty args");
+ goto out;
+ }
+
+ if (!json_object_object_get_ex(object, "status", &json_status)) {
+ AFB_API_ERROR(this_api, "nfc/presence missing status");
+ goto out;
+ }
+
+ if (strncmp(json_object_get_string(json_status), "detected", 8)) {
+ AFB_API_WARNING(this_api, "Not a tag detected event!");
+ goto out;
+ }
+
if (json_object_object_get_ex(object, "uid", &json_uid))
{
uid = json_object_get_string(json_uid);
- AFB_API_NOTICE(afbBindingV3root,
+ AFB_API_NOTICE(this_api,
"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_API_ERROR(afbBindingV3root,
- "nfc target add event is received but no UID found: %s",
- json_object_to_json_string(object));
+ else
+ AFB_API_ERROR(this_api,
+ "nfc tag detected event but no UID found: %s",
+ json_object_to_json_string(object));
+out:
+ return;
}
static void onevent(afb_api_t api, const char *event, struct json_object *object)
@@ -277,9 +281,61 @@ static void onevent(afb_api_t api, const char *event, struct json_object *object
on_nfc_target_add(object);
return;
}
+
AFB_API_WARNING(api, "Unhandled event: %s", event);
}
+/****************************************************************/
+
+static void subscribe (afb_req_t request)
+{
+ if (afb_req_subscribe(request, event)) {
+ AFB_REQ_ERROR(request, "subscribe to identity event failed");
+ afb_req_reply(request, NULL, "failed", "subscribe error");
+ return;
+ }
+
+ afb_req_reply(request, NULL, NULL, NULL);
+}
+
+static void unsubscribe (afb_req_t request)
+{
+ if (afb_req_unsubscribe(request, event)) {
+ AFB_REQ_ERROR(request, "unsubscribe to identity event failed");
+ afb_req_reply(request, NULL, "failed", "unsubscribe error");
+ return;
+ }
+
+ afb_req_reply(request, NULL, NULL, NULL);
+}
+
+static void logout (afb_req_t request)
+{
+ do_logout();
+ afb_req_reply(request, NULL, NULL, NULL);
+}
+
+/*
+ * verb "fake_login" intended for testing: force sending a login event
+ */
+static void fake_login (afb_req_t request)
+{
+ struct json_object *desc = afb_req_json(request);
+ do_logout();
+ if (desc)
+ do_login(desc);
+ afb_req_reply(request, NULL, NULL, NULL);
+}
+
+static void get (afb_req_t request)
+{
+ afb_req_reply(request, json_object_get(current_identity), NULL, NULL);
+}
+
+/*
+ * verb "fake_auth" intended for testing: trigger authentication on the
+ * provided data (e.g same args as per the "nfc/presence" event)
+ */
static void fake_auth(afb_req_t req)
{
struct json_object* req_object;
@@ -294,18 +350,15 @@ static void fake_auth(afb_req_t req)
AFB_REQ_ERROR(req, "bad request: %s",
json_object_get_string(req_object));
afb_req_reply(req, NULL, "Missing arg", NULL);
+ return;
}
- else {
- const char* kind = json_object_get_string(kind_object);
- const char* key = json_object_get_string(key_object);
- AFB_REQ_NOTICE(req, "kind: %s, key: %s", kind, key);
-
- send_event_object("incoming", key, key);
- agl_forgerock_download_request(vin ? vin : default_vin, kind, key);
+ const char* kind = json_object_get_string(kind_object);
+ const char* key = json_object_get_string(key_object);
- afb_req_reply(req, NULL, NULL, "fake auth success!");
- }
+ AFB_REQ_NOTICE(req, "kind: %s, key: %s", kind, key);
+ agl_forgerock_download_request(vin ? vin : default_vin, kind, key);
+ afb_req_reply(req, NULL, NULL, "fake auth success!");
}
/*
@@ -314,31 +367,29 @@ static void fake_auth(afb_req_t req)
*/
const afb_verb_t verbs[]=
{
- {.verb = "subscribe" , .callback = subscribe , .auth = NULL,
+ {.verb = "subscribe" , .callback = subscribe ,
.info = "subscribe to events" , .session = AFB_SESSION_NONE },
- {.verb = "unsubscribe", .callback = unsubscribe , .auth = NULL,
+ {.verb = "unsubscribe", .callback = unsubscribe ,
.info = "unsubscribe to events" , .session = AFB_SESSION_NONE },
- {.verb = "fake-login" , .callback = fake_login , .auth = NULL,
+ {.verb = "fake-login" , .callback = fake_login ,
.info = "fake a login" , .session = AFB_SESSION_NONE },
- {.verb = "logout" , .callback = logout , .auth = NULL,
+ {.verb = "logout" , .callback = logout ,
.info = "log the current user out", .session = AFB_SESSION_NONE },
- {.verb = "get" , .callback = get , .auth = NULL,
+ {.verb = "get" , .callback = get ,
.info = "get data" , .session = AFB_SESSION_NONE },
- {.verb = "fake-auth" , .callback = fake_auth , .auth = NULL,
+ {.verb = "fake-auth" , .callback = fake_auth ,
.info = "fake an authentication" , .session = AFB_SESSION_NONE },
- {NULL}
+ { }
};
const afb_binding_t afbBindingExport =
{
.api = "identity",
- .specification = NULL,
+ .specification = "Identity-agent API",
.info = "AGL identity service",
.verbs = verbs,
- .preinit = NULL,
.init = service_init,
.onevent = onevent,
- .noconcurrency = 0
};
/* vim: set colorcolumn=80: */