From 28a7ca12adefd4a4db25ad0534638e085a9f0e12 Mon Sep 17 00:00:00 2001 From: Chip Black Date: Sat, 26 Feb 2011 03:45:36 -0600 Subject: [PATCH] Add /feedinfo endpoint --- common/app.h | 1 + database/subscription.c | 14 ++++++++++ database/subscription.h | 1 + http/canned_responses.c | 7 ++++- http/canned_responses.h | 1 + http/http_blerg.c | 57 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 80 insertions(+), 1 deletion(-) diff --git a/common/app.h b/common/app.h index b45f472..8156274 100644 --- a/common/app.h +++ b/common/app.h @@ -11,6 +11,7 @@ #define REALM "Blerg" #define CONTENT_401 "401 Unauthorized

401 Unauthorized

DENIED" +#define CONTENT_403 "403 Forbidden

403 Forbidden

Go away." #define CONTENT_404 "404 Not Found

404 Not Found

I couldn't find that." #define CONTENT_405 "405 Method Not Allowed

405 Method Not Allowed

I'm sorry, Dave. I'm afraid I can't do that." #define JSON_SUCCESS "{\"status\": \"success\"}" diff --git a/database/subscription.c b/database/subscription.c index d67d31f..d3686ad 100644 --- a/database/subscription.c +++ b/database/subscription.c @@ -128,3 +128,17 @@ subscription_list_open_failed: *count = 0; return NULL; } + +int is_subscribed(const char *from, const char *to) { + char filename[512]; + struct stringbucket * sb; + int ret = 0; + + snprintf(filename, 512, "%s/%s/subscriptions", DATA_PATH, from); + sb = stringbucket_open(filename); + if (stringbucket_find(sb, to) != -1) + ret = 1; + stringbucket_close(sb); + + return ret; +} diff --git a/database/subscription.h b/database/subscription.h index a7cf567..c07fc6d 100644 --- a/database/subscription.h +++ b/database/subscription.h @@ -11,5 +11,6 @@ int subscription_add(const char *from, const char *to); int subscription_remove(const char *from, const char *to); int subscription_notify(const char *author, uint64_t record); struct blergref * subscription_list(const char *author, uint64_t offset, int *count, int direction); +int is_subscribed(const char *from, const char *to); #endif /* _SUBSCRIPTION_H */ diff --git a/http/canned_responses.c b/http/canned_responses.c index ee26799..3537907 100644 --- a/http/canned_responses.c +++ b/http/canned_responses.c @@ -7,7 +7,8 @@ #include "canned_responses.h" void init_responses() { - response_401 = MHD_create_response_from_data(strlen (CONTENT_401), CONTENT_401, MHD_NO, MHD_NO); + response_401 = MHD_create_response_from_data(strlen(CONTENT_401), CONTENT_401, MHD_NO, MHD_NO); + response_403 = MHD_create_response_from_data(strlen(CONTENT_403), CONTENT_403, MHD_NO, MHD_NO); response_404 = MHD_create_response_from_data(strlen(CONTENT_404), CONTENT_404, MHD_NO, MHD_NO); response_405 = MHD_create_response_from_data(strlen(CONTENT_405), CONTENT_405, MHD_NO, MHD_NO); response_JSON_Success = MHD_create_response_from_data(strlen(JSON_SUCCESS), JSON_SUCCESS, MHD_NO, MHD_NO); @@ -19,6 +20,10 @@ int respond_401(struct MHD_Connection *connection, int signal_stale) { return MHD_queue_auth_fail_response(connection, REALM, OPAQUE, response_401, signal_stale); } +int respond_403(struct MHD_Connection *connection) { + return MHD_queue_response(connection, MHD_HTTP_FORBIDDEN, response_403); +} + int respond_404(struct MHD_Connection *connection) { return MHD_queue_response(connection, MHD_HTTP_NOT_FOUND, response_404); } diff --git a/http/canned_responses.h b/http/canned_responses.h index 7b3a0f5..3bb079f 100644 --- a/http/canned_responses.h +++ b/http/canned_responses.h @@ -5,6 +5,7 @@ #define _CANNED_RESPONSES struct MHD_Response *response_401; +struct MHD_Response *response_403; struct MHD_Response *response_404; struct MHD_Response *response_405; struct MHD_Response *response_JSON_Success; diff --git a/http/http_blerg.c b/http/http_blerg.c index e205749..65a63d2 100644 --- a/http/http_blerg.c +++ b/http/http_blerg.c @@ -266,6 +266,32 @@ struct MHD_Response *create_blergref_response(struct blergref *results, uint64_t return MHD_create_response_from_callback(-1, 262144, &GET_generate_blergref_list, bs, &GET_generate_blergref_list_free); } +int check_auth(struct MHD_Connection *connection, const char *method, const char *upload_data, size_t *upload_data_size, void **ptr) { + struct auth_state *as = (struct auth_state *) *ptr; + if (as == NULL) { + if (strcmp(method, MHD_HTTP_METHOD_POST) != 0) + return respond_405(connection); + + as = malloc(sizeof(struct auth_state)); + as->username[0] = as->password[0] = 0; + as->pp = MHD_create_post_processor(connection, 1024, &POST_auth_iterator, as); + *ptr = as; + return MHD_YES; + } + + if (*upload_data_size) { + MHD_post_process(as->pp, upload_data, *upload_data_size); + *upload_data_size = 0; + return MHD_YES; + } + + const char *given_token = MHD_lookup_connection_value(connection, MHD_COOKIE_KIND, "auth"); + if (!auth_check_token(as->username, given_token)) + return respond_403(connection); + + return MHD_NO; +} + static int ahc_derp (void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **ptr) { @@ -632,6 +658,37 @@ ahc_derp (void *cls, struct MHD_Connection *connection, const char *url, const c } else { return respond_JSON_Failure(connection); } + } else if (strncmp(url, "/feedinfo", 9) == 0) { + ret = check_auth(connection, method, upload_data, upload_data_size, ptr); + if (ret == MHD_YES) + return MHD_YES; + + struct auth_state *as = (struct auth_state *) *ptr; + + if (url[9] != '/') + return respond_404(connection); + + ret = parse_url_info(url + 10, &info); + if ((ret & URL_INFO_NAME) == 0) + return respond_404(connection); + + yajl_gen g = yajl_gen_alloc(&yajl_c, NULL); + yajl_gen_map_open(g); + yajl_gen_string(g, "subscribed", 10); + yajl_gen_bool(g, is_subscribed(as->username, info.name)); + yajl_gen_map_close(g); + + const unsigned char *ybuf; + yajl_gen_get_buf(g, &ybuf, &len); + + response = MHD_create_response_from_data(len, (void *)ybuf, MHD_NO, MHD_YES); + ret = MHD_queue_response(connection, MHD_HTTP_OK, response); + MHD_destroy_response(response); + + yajl_gen_free(g); + free(as); + + return ret; } else { return respond_404(connection); } -- 2.25.1