#include "tags.h"
#include "auth.h"
#include "canned_responses.h"
-#include "http.h"
+#include "app.h"
#include "config.h"
-#define URL_INFO_AUTHOR 0x1
-#define URL_INFO_RECORD 0x2
-#define URL_INFO_RECORD_TO 0x4
-#define DERP "DERP DERP DERP"
-
yajl_gen_config yajl_c = { 0, 0 };
-struct create_state {
+struct auth_state {
struct MHD_PostProcessor *pp;
char username[33];
char password[33];
int done;
};
-int parse_url_info(const char *url, struct url_info *info) {
- const char *c;
- int len;
- info->contents = 0;
-
- c = strchr(url, '/');
- if (c == NULL) {
- len = strlen(url);
- } else {
- len = c - url;
- }
- if (len == 0)
- return 0;
- memcpy(info->author, url, len);
- info->author[len] = 0;
- info->contents |= URL_INFO_AUTHOR;
-
- if (c == NULL || c[1] == 0)
- return info->contents;
-
- info->record = strtoull(c + 1, NULL, 10);
- info->contents |= URL_INFO_RECORD;
-
- c = strchr(c, '-');
- if (c == NULL || c[1] == 0)
- return info->contents;
-
- info->record_to = strtoull(c + 1, NULL, 10);
- info->contents |= URL_INFO_RECORD_TO;
-
- return info->contents;
-}
-
-uint64_t *make_sequential_list(uint64_t from, uint64_t to) {
- uint64_t len = to - from + 1;
- uint64_t *list = malloc(len * sizeof(uint64_t));
- uint64_t i;
-
- for (i = 0; i < len; i++) {
- list[i] = from + i;
- }
-
- return list;
-}
-
-void json_generate_one_record(yajl_gen g, const char *author, struct blerg *b, uint64_t record) {
- char *data;
- char number[21];
- int len;
-
- if (!blerg_fetch(b, record, &data, &len)) {
- fprintf(stderr, "Could not fetch record\n");
- return;
- }
-
- yajl_gen_map_open(g);
- if (author != NULL) {
- yajl_gen_string(g, "author", 6);
- yajl_gen_string(g, author, strlen(author));
- }
- yajl_gen_string(g, "record", 6);
- snprintf(number, 21, "%llu", record);
- yajl_gen_string(g, number, strlen(number));
- yajl_gen_string(g, "timestamp", 9);
- yajl_gen_integer(g, blerg_get_timestamp(b, record));
- yajl_gen_string(g, "data", 4);
- yajl_gen_string(g, data, len);
- yajl_gen_map_close(g);
-
- free(data);
-}
-
ssize_t GET_generate_list(void *cls, uint64_t pos, char *buf, size_t max) {
struct get_state *gs = cls;
const unsigned char *ybuf;
/* Snarf one record */
b = blerg_open(ts->results[ts->i].author);
- if (b == NULL)
- goto skip_bad_blerg;
-
- json_generate_one_record(ts->g, ts->results[ts->i].author, b, ts->results[ts->i].record);
-
- blerg_close(b);
+ if (b != NULL) {
+ json_generate_one_record(ts->g, ts->results[ts->i].author, b, ts->results[ts->i].record);
+ blerg_close(b);
+ }
-skip_bad_blerg:
if (ts->i == 0) {
yajl_gen_array_close(ts->g);
ts->done = 1;
free(ts);
}
-int POST_create_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size) {
- struct create_state *cs = cls;
+int POST_auth_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size) {
+ struct auth_state *as = cls;
if (strncmp(key, "username", 9) == 0) {
if (size > 32) size = 32;
- memcpy(cs->username, data, size);
- cs->username[size] = 0;
+ memcpy(as->username, data, size);
+ as->username[size] = 0;
} else if (strncmp(key, "password", 9) == 0) {
if (size > 32) size = 32;
- memcpy(cs->password, data, size);
- cs->password[size] = 0;
+ memcpy(as->password, data, size);
+ as->password[size] = 0;
}
return MHD_YES;
if (!tag_exists(info.author))
return respond_404(connection);
- uint64_t recs = 50;
+ int recs = 50;
struct tag *taglist = tag_list(info.author, 0, &recs, -1);
if (recs == 0) {
return ret;
} else if (strncmp(url, "/create", 8) == 0) {
- struct create_state *cs = (struct create_state *) *ptr;
+ struct auth_state *as = (struct auth_state *) *ptr;
- if (cs == NULL) {
+ if (as == NULL) {
if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
return respond_405(connection);
- struct create_state *cs = malloc(sizeof(struct create_state));
- cs->username[0] = cs->password[0] = 0;
- cs->pp = MHD_create_post_processor(connection, 1024, &POST_create_iterator, cs);
- *ptr = cs;
+ struct auth_state *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(cs->pp, upload_data, *upload_data_size);
+ MHD_post_process(as->pp, upload_data, *upload_data_size);
*upload_data_size = 0;
return MHD_YES;
}
- if (cs->username[0] == 0 || cs->password[0] == 0)
+ if (as->username[0] == 0 || as->password[0] == 0)
return respond_JSON_Failure(connection);
- if (blerg_exists(cs->username))
+ if (blerg_exists(as->username))
return respond_JSON_Failure(connection);
- struct blerg *b = blerg_open(cs->username);
+ struct blerg *b = blerg_open(as->username);
blerg_close(b);
- auth_set_password(cs->username, cs->password);
+ auth_set_password(as->username, as->password);
- MHD_destroy_post_processor(cs->pp);
- free(cs);
+ MHD_destroy_post_processor(as->pp);
+ free(as);
*ptr = NULL;
return respond_JSON_Success(connection);
+ } else if (strncmp(url, "/login", 7) == 0) {
+ struct auth_state *as = (struct auth_state *) *ptr;
+
+ if (as == NULL) {
+ if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
+ return respond_405(connection);
+
+ struct auth_state *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;
+ }
+
+ if (as->username[0] == 0 || as->password[0] == 0)
+ return respond_JSON_Failure(connection);
+
+ if (!auth_login(as->username, as->password))
+ return respond_JSON_Failure(connection);
+
+ response = MHD_create_response_from_data(strlen(JSON_SUCCESS), JSON_SUCCESS, MHD_NO, MHD_NO);
+
+ char *token = auth_get_token(as->username);
+ data = malloc(512);
+ snprintf(data, 512, "auth=%s", token);
+ MHD_add_response_header(response, "Set-Cookie", data);
+ free(token);
+ free(data);
+
+ MHD_destroy_post_processor(as->pp);
+ free(as);
+ *ptr = NULL;
+
+ ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
+ MHD_destroy_response(response);
+
+ return ret;
+ } else if (strncmp(url, "/logout", 8) == 0) {
+ struct auth_state *as = (struct auth_state *) *ptr;
+
+ if (as == NULL) {
+ if (strcmp(method, MHD_HTTP_METHOD_POST) != 0)
+ return respond_405(connection);
+
+ struct auth_state *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 (given_token != NULL && auth_check_token(as->username, given_token)) {
+ auth_logout(as->username);
+ return respond_JSON_Success(connection);
+ } else {
+ return respond_JSON_Failure(connection);
+ }
} else {
return respond_404(connection);
}