summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--httpd.c6
-rw-r--r--mastoapi.c162
2 files changed, 138 insertions, 30 deletions
diff --git a/httpd.c b/httpd.c
index d5de87c..7f6a428 100644
--- a/httpd.c
+++ b/httpd.c
@@ -188,15 +188,15 @@ void httpd_connection(FILE *f)
else
if (strcmp(method, "POST") == 0) {
if (status == 0)
- status = activitypub_post_handler(req, q_path,
+ status = oauth_post_handler(req, q_path,
payload, p_size, &body, &b_size, &ctype);
if (status == 0)
- status = oauth_post_handler(req, q_path,
+ status = mastoapi_post_handler(req, q_path,
payload, p_size, &body, &b_size, &ctype);
if (status == 0)
- status = mastoapi_post_handler(req, q_path,
+ status = activitypub_post_handler(req, q_path,
payload, p_size, &body, &b_size, &ctype);
if (status == 0)
diff --git a/mastoapi.c b/mastoapi.c
index e1d0c9d..842b97f 100644
--- a/mastoapi.c
+++ b/mastoapi.c
@@ -596,25 +596,11 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
}
-int mastoapi_get_handler(const xs_dict *req, const char *q_path,
- char **body, int *b_size, char **ctype)
+int process_auth_token(snac *snac, const xs_dict *req)
+/* processes an authorization token, if there is one */
{
- if (!xs_startswith(q_path, "/api/v1/"))
- return 0;
-
- srv_debug(0, xs_fmt("mastoapi_get_handler %s", q_path));
-/* {
- xs *j = xs_json_dumps_pp(req, 4);
- printf("mastoapi get:\n%s\n", j);
- }*/
-
- int status = 404;
- xs_dict *args = xs_dict_get(req, "q_vars");
- xs *cmd = xs_replace(q_path, "/api/v1", "");
- char *v;
-
- snac snac = {0};
int logged_in = 0;
+ char *v;
/* if there is an authorization field, try to validate it */
if (!xs_is_null(v = xs_dict_get(req, "authorization")) && xs_startswith(v, "Bearer ")) {
@@ -624,7 +610,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
if (token != NULL) {
const char *uid = xs_dict_get(token, "uid");
- if (!xs_is_null(uid) && user_open(&snac, uid)) {
+ if (!xs_is_null(uid) && user_open(snac, uid)) {
logged_in = 1;
srv_debug(0, xs_fmt("mastoapi auth: valid token for user %s", uid));
}
@@ -635,6 +621,29 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
srv_log(xs_fmt("mastoapi auth: invalid token %s", tokid));
}
+ return logged_in;
+}
+
+
+int mastoapi_get_handler(const xs_dict *req, const char *q_path,
+ char **body, int *b_size, char **ctype)
+{
+ if (!xs_startswith(q_path, "/api/v1/"))
+ return 0;
+
+ srv_debug(0, xs_fmt("mastoapi_get_handler %s", q_path));
+/* {
+ xs *j = xs_json_dumps_pp(req, 4);
+ printf("mastoapi get:\n%s\n", j);
+ }*/
+
+ int status = 404;
+ xs_dict *args = xs_dict_get(req, "q_vars");
+ xs *cmd = xs_replace(q_path, "/api/v1", "");
+
+ snac snac = {0};
+ int logged_in = process_auth_token(&snac, req);;
+
if (strcmp(cmd, "/accounts/verify_credentials") == 0) {
if (logged_in) {
xs *acct = xs_dict_new();
@@ -946,28 +955,31 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
}
int status = 404;
- xs *msg = NULL;
+ xs *args = NULL;
char *i_ctype = xs_dict_get(req, "content-type");
- if (xs_startswith(i_ctype, "application/json"))
- msg = xs_json_loads(payload);
+ if (i_ctype && xs_startswith(i_ctype, "application/json"))
+ args = xs_json_loads(payload);
else
- msg = xs_dup(xs_dict_get(req, "p_vars"));
+ args = xs_dup(xs_dict_get(req, "p_vars"));
- if (msg == NULL)
+ if (args == NULL)
return 400;
{
- xs *j = xs_json_dumps_pp(msg, 4);
+ xs *j = xs_json_dumps_pp(args, 4);
printf("%s\n", j);
}
xs *cmd = xs_replace(q_path, "/api/v1", "");
+ snac snac = {0};
+ int logged_in = process_auth_token(&snac, req);;
+
if (strcmp(cmd, "/apps") == 0) {
- const char *name = xs_dict_get(msg, "client_name");
- const char *ruri = xs_dict_get(msg, "redirect_uris");
- const char *scope = xs_dict_get(msg, "scope");
+ const char *name = xs_dict_get(args, "client_name");
+ const char *ruri = xs_dict_get(args, "redirect_uris");
+ const char *scope = xs_dict_get(args, "scope");
if (xs_type(ruri) == XSTYPE_LIST)
ruri = xs_dict_get(ruri, 0);
@@ -1000,6 +1012,102 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
srv_debug(0, xs_fmt("mastoapi apps: new app %s", cid));
}
}
+ else
+ if (strcmp(cmd, "/statuses") == 0) {
+ if (logged_in) {
+ /* post a new Note */
+ /* TBD */
+ }
+ else
+ status = 401;
+ }
+ else
+ if (xs_startswith(cmd, "/statuses")) {
+ if (logged_in) {
+ /* operations on a status */
+ xs *l = xs_split(cmd, "/");
+ const char *mid = xs_list_get(l, 2);
+ const char *op = xs_list_get(l, 3);
+
+ if (!xs_is_null(mid)) {
+ xs *msg = NULL;
+ xs *out = NULL;
+
+ /* skip the fake part of the id (the date) */
+ mid += 14;
+
+ if (valid_status(timeline_get_by_md5(&snac, mid, &msg))) {
+ char *id = xs_dict_get(msg, "id");
+
+ if (op == NULL) {
+ /* no operation (?) */
+ }
+ else
+ if (strcmp(op, "favourite") == 0) {
+ xs *n_msg = msg_admiration(&snac, id, "Like");
+
+ if (n_msg != NULL) {
+ enqueue_message(&snac, n_msg);
+ timeline_admire(&snac, xs_dict_get(n_msg, "object"), snac.actor, 1);
+
+ out = mastoapi_status(&snac, msg);
+ }
+ }
+ else
+ if (strcmp(op, "unfavourite") == 0) {
+ /* snac does not support Undo+Like */
+ }
+ else
+ if (strcmp(op, "reblog") == 0) {
+ xs *n_msg = msg_admiration(&snac, id, "Announce");
+
+ if (n_msg != NULL) {
+ enqueue_message(&snac, n_msg);
+ timeline_admire(&snac, xs_dict_get(n_msg, "object"), snac.actor, 0);
+
+ out = mastoapi_status(&snac, msg);
+ }
+ }
+ else
+ if (strcmp(op, "unreblog") == 0) {
+ /* snac does not support Undo+Announce */
+ }
+ else
+ if (strcmp(op, "bookmark") == 0) {
+ /* snac does not support bookmarks */
+ }
+ else
+ if (strcmp(op, "unbookmark") == 0) {
+ /* snac does not support bookmarks */
+ }
+ else
+ if (strcmp(op, "pin") == 0) {
+ /* snac does not support pinning */
+ }
+ else
+ if (strcmp(op, "unpin") == 0) {
+ /* snac does not support pinning */
+ }
+ else
+ if (strcmp(op, "mute") == 0) {
+ /* Mastodon's mute is snac's hide */
+ }
+ else
+ if (strcmp(op, "unmute") == 0) {
+ /* Mastodon's unmute is snac's unhide */
+ }
+ }
+
+ if (out != NULL) {
+ *body = xs_json_dumps_pp(out, 4);
+ *ctype = "application/json";
+ status = 200;
+ }
+ }
+ }
+ else
+ status = 401;
+ }
return status;
}