commit c0a48f1

default  ·  2023-04-11 19:07:47 +0000 UTC
parent 036be9d
Added support for likes and boosts.
2 files changed,  +138, -30
+3, -3
 1@@ -188,15 +188,15 @@ void httpd_connection(FILE *f)
 2     else
 3     if (strcmp(method, "POST") == 0) {
 4         if (status == 0)
 5-            status = activitypub_post_handler(req, q_path,
 6+            status = oauth_post_handler(req, q_path,
 7                         payload, p_size, &body, &b_size, &ctype);
 8 
 9         if (status == 0)
10-            status = oauth_post_handler(req, q_path,
11+            status = mastoapi_post_handler(req, q_path,
12                         payload, p_size, &body, &b_size, &ctype);
13 
14         if (status == 0)
15-            status = mastoapi_post_handler(req, q_path,
16+            status = activitypub_post_handler(req, q_path,
17                         payload, p_size, &body, &b_size, &ctype);
18 
19         if (status == 0)
+135, -27
  1@@ -596,25 +596,11 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
  2 }
  3 
  4 
  5-int mastoapi_get_handler(const xs_dict *req, const char *q_path,
  6-                         char **body, int *b_size, char **ctype)
  7+int process_auth_token(snac *snac, const xs_dict *req)
  8+/* processes an authorization token, if there is one */
  9 {
 10-    if (!xs_startswith(q_path, "/api/v1/"))
 11-        return 0;
 12-
 13-    srv_debug(0, xs_fmt("mastoapi_get_handler %s", q_path));
 14-/*    {
 15-        xs *j = xs_json_dumps_pp(req, 4);
 16-        printf("mastoapi get:\n%s\n", j);
 17-    }*/
 18-
 19-    int status    = 404;
 20-    xs_dict *args = xs_dict_get(req, "q_vars");
 21-    xs *cmd       = xs_replace(q_path, "/api/v1", "");
 22-    char *v;
 23-
 24-    snac snac = {0};
 25     int logged_in = 0;
 26+    char *v;
 27 
 28     /* if there is an authorization field, try to validate it */
 29     if (!xs_is_null(v = xs_dict_get(req, "authorization")) && xs_startswith(v, "Bearer ")) {
 30@@ -624,7 +610,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
 31         if (token != NULL) {
 32             const char *uid = xs_dict_get(token, "uid");
 33 
 34-            if (!xs_is_null(uid) && user_open(&snac, uid)) {
 35+            if (!xs_is_null(uid) && user_open(snac, uid)) {
 36                 logged_in = 1;
 37                 srv_debug(0, xs_fmt("mastoapi auth: valid token for user %s", uid));
 38             }
 39@@ -635,6 +621,29 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
 40             srv_log(xs_fmt("mastoapi auth: invalid token %s", tokid));
 41     }
 42 
 43+    return logged_in;
 44+}
 45+
 46+
 47+int mastoapi_get_handler(const xs_dict *req, const char *q_path,
 48+                         char **body, int *b_size, char **ctype)
 49+{
 50+    if (!xs_startswith(q_path, "/api/v1/"))
 51+        return 0;
 52+
 53+    srv_debug(0, xs_fmt("mastoapi_get_handler %s", q_path));
 54+/*    {
 55+        xs *j = xs_json_dumps_pp(req, 4);
 56+        printf("mastoapi get:\n%s\n", j);
 57+    }*/
 58+
 59+    int status    = 404;
 60+    xs_dict *args = xs_dict_get(req, "q_vars");
 61+    xs *cmd       = xs_replace(q_path, "/api/v1", "");
 62+
 63+    snac snac = {0};
 64+    int logged_in = process_auth_token(&snac, req);;
 65+
 66     if (strcmp(cmd, "/accounts/verify_credentials") == 0) {
 67         if (logged_in) {
 68             xs *acct = xs_dict_new();
 69@@ -946,28 +955,31 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
 70     }
 71 
 72     int status    = 404;
 73-    xs *msg       = NULL;
 74+    xs *args      = NULL;
 75     char *i_ctype = xs_dict_get(req, "content-type");
 76 
 77-    if (xs_startswith(i_ctype, "application/json"))
 78-        msg = xs_json_loads(payload);
 79+    if (i_ctype && xs_startswith(i_ctype, "application/json"))
 80+        args = xs_json_loads(payload);
 81     else
 82-        msg = xs_dup(xs_dict_get(req, "p_vars"));
 83+        args = xs_dup(xs_dict_get(req, "p_vars"));
 84 
 85-    if (msg == NULL)
 86+    if (args == NULL)
 87         return 400;
 88 
 89     {
 90-        xs *j = xs_json_dumps_pp(msg, 4);
 91+        xs *j = xs_json_dumps_pp(args, 4);
 92         printf("%s\n", j);
 93     }
 94 
 95     xs *cmd = xs_replace(q_path, "/api/v1", "");
 96 
 97+    snac snac = {0};
 98+    int logged_in = process_auth_token(&snac, req);;
 99+
100     if (strcmp(cmd, "/apps") == 0) {
101-        const char *name  = xs_dict_get(msg, "client_name");
102-        const char *ruri  = xs_dict_get(msg, "redirect_uris");
103-        const char *scope = xs_dict_get(msg, "scope");
104+        const char *name  = xs_dict_get(args, "client_name");
105+        const char *ruri  = xs_dict_get(args, "redirect_uris");
106+        const char *scope = xs_dict_get(args, "scope");
107 
108         if (xs_type(ruri) == XSTYPE_LIST)
109             ruri = xs_dict_get(ruri, 0);
110@@ -1000,6 +1012,102 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
111             srv_debug(0, xs_fmt("mastoapi apps: new app %s", cid));
112         }
113     }
114+    else
115+    if (strcmp(cmd, "/statuses") == 0) {
116+        if (logged_in) {
117+            /* post a new Note */
118+            /* TBD */
119+        }
120+        else
121+            status = 401;
122+    }
123+    else
124+    if (xs_startswith(cmd, "/statuses")) {
125+        if (logged_in) {
126+            /* operations on a status */
127+            xs *l = xs_split(cmd, "/");
128+            const char *mid = xs_list_get(l, 2);
129+            const char *op  = xs_list_get(l, 3);
130+
131+            if (!xs_is_null(mid)) {
132+                xs *msg = NULL;
133+                xs *out = NULL;
134+
135+                /* skip the fake part of the id (the date) */
136+                mid += 14;
137+
138+                if (valid_status(timeline_get_by_md5(&snac, mid, &msg))) {
139+                    char *id = xs_dict_get(msg, "id");
140+
141+                    if (op == NULL) {
142+                        /* no operation (?) */
143+                    }
144+                    else
145+                    if (strcmp(op, "favourite") == 0) {
146+                        xs *n_msg = msg_admiration(&snac, id, "Like");
147+
148+                        if (n_msg != NULL) {
149+                            enqueue_message(&snac, n_msg);
150+                            timeline_admire(&snac, xs_dict_get(n_msg, "object"), snac.actor, 1);
151+
152+                            out = mastoapi_status(&snac, msg);
153+                        }
154+                    }
155+                    else
156+                    if (strcmp(op, "unfavourite") == 0) {
157+                        /* snac does not support Undo+Like */
158+                    }
159+                    else
160+                    if (strcmp(op, "reblog") == 0) {
161+                        xs *n_msg = msg_admiration(&snac, id, "Announce");
162+
163+                        if (n_msg != NULL) {
164+                            enqueue_message(&snac, n_msg);
165+                            timeline_admire(&snac, xs_dict_get(n_msg, "object"), snac.actor, 0);
166+
167+                            out = mastoapi_status(&snac, msg);
168+                        }
169+                    }
170+                    else
171+                    if (strcmp(op, "unreblog") == 0) {
172+                        /* snac does not support Undo+Announce */
173+                    }
174+                    else
175+                    if (strcmp(op, "bookmark") == 0) {
176+                        /* snac does not support bookmarks */
177+                    }
178+                    else
179+                    if (strcmp(op, "unbookmark") == 0) {
180+                        /* snac does not support bookmarks */
181+                    }
182+                    else
183+                    if (strcmp(op, "pin") == 0) {
184+                        /* snac does not support pinning */
185+                    }
186+                    else
187+                    if (strcmp(op, "unpin") == 0) {
188+                        /* snac does not support pinning */
189+                    }
190+                    else
191+                    if (strcmp(op, "mute") == 0) {
192+                        /* Mastodon's mute is snac's hide */
193+                    }
194+                    else
195+                    if (strcmp(op, "unmute") == 0) {
196+                        /* Mastodon's unmute is snac's unhide */
197+                    }
198+                }
199+
200+                if (out != NULL) {
201+                    *body  = xs_json_dumps_pp(out, 4);
202+                    *ctype = "application/json";
203+                    status = 200;
204+                }
205+            }
206+        }
207+        else
208+            status = 401;
209+    }
210 
211     return status;
212 }