+// verify the person, the machine and the URL exist in our DB
+PERSON_URL *registry_verify_request(char *person_guid, char *machine_guid, char *url, PERSON **pp, MACHINE **mm) {
+ char pbuf[36 + 1], mbuf[36 + 1];
+
+ if(!person_guid || !*person_guid || !machine_guid || !*machine_guid || !url || !*url) {
+ info("Registry Request Verification: invalid request! person: '%s', machine '%s', url '%s'", person_guid?person_guid:"UNSET", machine_guid?machine_guid:"UNSET", url?url:"UNSET");
+ return NULL;
+ }
+
+ // normalize the url
+ url = registry_fix_url(url, NULL);
+
+ // make sure the person GUID is valid
+ if(registry_regenerate_guid(person_guid, pbuf) == -1) {
+ info("Registry Request Verification: invalid person GUID, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
+ return NULL;
+ }
+ person_guid = pbuf;
+
+ // make sure the machine GUID is valid
+ if(registry_regenerate_guid(machine_guid, mbuf) == -1) {
+ info("Registry Request Verification: invalid machine GUID, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
+ return NULL;
+ }
+ machine_guid = mbuf;
+
+ // make sure the machine exists
+ MACHINE *m = registry_machine_find(machine_guid);
+ if(!m) {
+ info("Registry Request Verification: machine not found, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
+ return NULL;
+ }
+ if(mm) *mm = m;
+
+ // make sure the person exist
+ PERSON *p = registry_person_find(person_guid);
+ if(!p) {
+ info("Registry Request Verification: person not found, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
+ return NULL;
+ }
+ if(pp) *pp = p;
+
+ PERSON_URL *pu = dictionary_get(p->urls, url);
+ if(!pu) {
+ info("Registry Request Verification: URL not found for person, person: '%s', machine '%s', url '%s'", person_guid, machine_guid, url);
+ return NULL;
+ }
+ return pu;
+}
+
+PERSON *registry_request_delete(char *person_guid, char *machine_guid, char *url, char *delete_url, time_t when) {
+ (void)when;
+
+ PERSON *p = NULL;
+ MACHINE *m = NULL;
+ PERSON_URL *pu = registry_verify_request(person_guid, machine_guid, url, &p, &m);
+ if(!pu || !p || !m) return NULL;
+
+ // normalize the url
+ delete_url = registry_fix_url(delete_url, NULL);
+
+ // make sure the user is not deleting the url it uses
+ if(!strcmp(delete_url, pu->url->url)) {
+ info("Registry Delete Request: delete URL is the one currently accessing, person: '%s', machine '%s', url '%s', delete url '%s'", p->guid, m->guid, pu->url->url, delete_url);
+ return NULL;
+ }
+
+ registry_person_urls_lock(p);
+
+ PERSON_URL *dpu = dictionary_get(p->urls, delete_url);
+ if(!dpu) {
+ info("Registry Delete Request: URL not found for person, person: '%s', machine '%s', url '%s', delete url '%s'", p->guid, m->guid, pu->url->url, delete_url);
+ registry_person_urls_unlock(p);
+ return NULL;
+ }
+
+ registry_log('D', p, m, pu->url, dpu->url->url);
+
+ dictionary_del(p->urls, dpu->url->url);
+ registry_url_unlink_nolock(dpu->url);
+ free(dpu);
+
+ registry_person_urls_unlock(p);
+ return p;
+}
+
+MACHINE *registry_request_machine(char *person_guid, char *machine_guid, char *url, char *request_machine, time_t when) {
+ (void)when;
+
+ char mbuf[36 + 1];
+
+ PERSON *p = NULL;
+ MACHINE *m = NULL;
+ PERSON_URL *pu = registry_verify_request(person_guid, machine_guid, url, &p, &m);
+ if(!pu || !p || !m) return NULL;
+
+ // make sure the machine GUID is valid
+ if(registry_regenerate_guid(request_machine, mbuf) == -1) {
+ info("Registry Machine URLs request: invalid machine GUID, person: '%s', machine '%s', url '%s', request machine '%s'", p->guid, m->guid, pu->url->url, request_machine);
+ return NULL;
+ }
+ request_machine = mbuf;
+
+ // make sure the machine exists
+ m = registry_machine_find(request_machine);
+ if(!m) {
+ info("Registry Machine URLs request: machine not found, person: '%s', machine '%s', url '%s', request machine '%s'", p->guid, m->guid, pu->url->url, request_machine);
+ return NULL;
+ }
+
+ // Verify the user has in the past accessed this machine
+ // We will walk through the PERSON_URLs to find the machine
+ // linking to our machine
+
+ // C magic !
+
+ // a structure to pass to the dictionary_get_all() callback handler
+ struct machine_request_callback_data {
+ MACHINE *find_this_machine;
+ PERSON_URL *result;
+ } rdata = { m, NULL };
+
+ // the callback function
+ // this will be run for every PERSON_URL of this PERSON
+ int machine_request_callback(void *entry, void *data) {
+ PERSON_URL *mypu = (PERSON_URL *)entry;
+ struct machine_request_callback_data *myrdata = (struct machine_request_callback_data *)data;
+
+ if(mypu->machine == myrdata->find_this_machine) {
+ myrdata->result = mypu;
+ return -1; // this will also stop the walk through
+ }
+
+ return 0; // continue
+ }
+
+ // request a walk through on the dictionary
+ // no need for locking here, the underlying dictionary has its own
+ dictionary_get_all(p->urls, machine_request_callback, &rdata);
+
+ if(rdata.result)
+ return m;
+
+ return NULL;
+}
+
+
+// ----------------------------------------------------------------------------
+// REGISTRY JSON generation
+
+#ifndef REGISTRY_STANDALONE_TESTS
+
+static inline void registry_json_header(struct web_client *w, int status) {
+ buffer_flush(w->response.data);
+ buffer_sprintf(w->response.data, "{\n\"success\": %s", status?"true":"false");
+}
+
+static inline void registry_json_footer(struct web_client *w) {
+ buffer_strcat(w->response.data, "\n}\n");
+}
+
+static inline int registry_json_redirect(struct web_client *w) {
+ registry_json_header(w, 0);
+ buffer_sprintf(w->response.data, "\"registries\": \"%s\"", config_get("global", "users registries", "reg1.mynetdata.io reg2.mynetdata.io reg3.mynetdata.io"));
+ registry_json_footer(w);
+ return 200;
+}
+
+int registry_request_access_json(struct web_client *w, char *person_guid, char *machine_guid, char *url, char *name, time_t when) {
+ if(!registry.enabled)
+ return registry_json_redirect(w);
+
+ PERSON *p = registry_request_access(person_guid, machine_guid, url, name, when);
+ if(!p) {
+ registry_json_header(w, 0);
+ registry_json_footer(w);
+ return 400;
+ }
+
+ // FIXME -- make this a permanent cookie
+ strncpy(w->cookie, p->guid, COOKIE_MAX);
+ w->cookie[COOKIE_MAX] = '\0';
+
+ registry_json_header(w, 1);
+
+ // FIXME - print an array of all URLs / Machines / Names
+
+ buffer_strcat(w->response.data, "\n}\n");
+ return 200;
+}
+
+int registry_request_delete_json(struct web_client *w, char *person_guid, char *machine_guid, char *url, char *delete_url, time_t when) {
+ if(!registry.enabled)
+ return registry_json_redirect(w);
+
+ PERSON *p = registry_request_delete(person_guid, machine_guid, url, delete_url, when);
+ if(!p) {
+ registry_json_header(w, 0);
+ registry_json_footer(w);
+ return 400;
+ }
+
+ registry_json_header(w, 1);
+ registry_json_footer(w);
+ return 200;
+}
+
+int registry_request_search_json(struct web_client *w, char *person_guid, char *machine_guid, char *url, char *request_machine, time_t when) {
+ if(!registry.enabled)
+ return registry_json_redirect(w);
+
+ MACHINE *m = registry_request_machine(person_guid, machine_guid, url, request_machine, when);
+ if(!m) {
+ registry_json_header(w, 0);
+ registry_json_footer(w);
+ return 400;
+ }
+
+ registry_json_header(w, 1);
+
+ // FIXME - print an array of all URLs the machine is accessible
+
+ registry_json_footer(w);
+ return 200;
+}
+
+#endif /* REGISTRY_STANDALONE_TESTS */
+