commit 422b314

grunfink  ·  2023-06-11 07:05:07 +0000 UTC
parents ab470e9, fb5f34b
Merge pull request 'Mastodon API private timeline fixes' (#44) from poesty/snac2:master into master

Reviewed-on: https://codeberg.org/grunfink/snac2/pulls/44
1 files changed,  +112, -99
+112, -99
  1@@ -1172,7 +1172,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
  2 
  3                 /* only return entries older that max_id */
  4                 if (max_id) {
  5-                    if (strcmp(v, max_id) == 0)
  6+                    if (strcmp(v, MID_TO_MD5(max_id)) == 0)
  7                         max_id = NULL;
  8 
  9                     continue;
 10@@ -1180,14 +1180,14 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
 11 
 12                 /* only returns entries newer than since_id */
 13                 if (since_id) {
 14-                    if (strcmp(v, since_id) == 0)
 15+                    if (strcmp(v, MID_TO_MD5(since_id)) == 0)
 16                         break;
 17                 }
 18 
 19                 /* only returns entries newer than min_id */
 20                 /* what does really "Return results immediately newer than ID" mean? */
 21                 if (min_id) {
 22-                    if (strcmp(v, min_id) == 0)
 23+                    if (strcmp(v, MID_TO_MD5(min_id)) == 0)
 24                         break;
 25                 }
 26 
 27@@ -1200,6 +1200,11 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
 28                 if (strcmp(type, "Note") != 0 && strcmp(type, "Question") != 0)
 29                     continue;
 30 
 31+                /* discard notes from people we don't follow with no boosts */
 32+                if (!following_check(&snac1, xs_dict_get(msg, "attributedTo")) &&
 33+                    object_announces_len(xs_dict_get(msg, "id")) == 0)
 34+                    continue;
 35+
 36                 /* discard notes from muted morons */
 37                 if (is_muted(&snac1, xs_dict_get(msg, "attributedTo")))
 38                     continue;
 39@@ -1505,102 +1510,106 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
 40     else
 41     if (xs_startswith(cmd, "/v1/statuses/")) { /** **/
 42         /* information about a status */
 43-        xs *l = xs_split(cmd, "/");
 44-        const char *id = xs_list_get(l, 3);
 45-        const char *op = xs_list_get(l, 4);
 46+        if (logged_in) {
 47+            xs *l = xs_split(cmd, "/");
 48+            const char *id = xs_list_get(l, 3);
 49+            const char *op = xs_list_get(l, 4);
 50 
 51-        if (!xs_is_null(id)) {
 52-            xs *msg = NULL;
 53-            xs *out = NULL;
 54+            if (!xs_is_null(id)) {
 55+                xs *msg = NULL;
 56+                xs *out = NULL;
 57 
 58-            /* skip the 'fake' part of the id */
 59-            id = MID_TO_MD5(id);
 60+                /* skip the 'fake' part of the id */
 61+                id = MID_TO_MD5(id);
 62 
 63-            if (valid_status(object_get_by_md5(id, &msg))) {
 64-                if (op == NULL) {
 65-                    if (!is_muted(&snac1, xs_dict_get(msg, "attributedTo"))) {
 66-                        /* return the status itself */
 67-                        out = mastoapi_status(&snac1, msg);
 68+                if (valid_status(object_get_by_md5(id, &msg))) {
 69+                    if (op == NULL) {
 70+                        if (!is_muted(&snac1, xs_dict_get(msg, "attributedTo"))) {
 71+                            /* return the status itself */
 72+                            out = mastoapi_status(&snac1, msg);
 73+                        }
 74                     }
 75-                }
 76-                else
 77-                if (strcmp(op, "context") == 0) { /** **/
 78-                    /* return ancestors and children */
 79-                    xs *anc = xs_list_new();
 80-                    xs *des = xs_list_new();
 81-                    xs_list *p;
 82-                    xs_str *v;
 83-                    char pid[64];
 84+                    else
 85+                    if (strcmp(op, "context") == 0) { /** **/
 86+                        /* return ancestors and children */
 87+                        xs *anc = xs_list_new();
 88+                        xs *des = xs_list_new();
 89+                        xs_list *p;
 90+                        xs_str *v;
 91+                        char pid[64];
 92 
 93-                    /* build the [grand]parent list, moving up */
 94-                    strncpy(pid, id, sizeof(pid));
 95+                        /* build the [grand]parent list, moving up */
 96+                        strncpy(pid, id, sizeof(pid));
 97 
 98-                    while (object_parent(pid, pid, sizeof(pid))) {
 99-                        xs *m2 = NULL;
100+                        while (object_parent(pid, pid, sizeof(pid))) {
101+                            xs *m2 = NULL;
102 
103-                        if (valid_status(timeline_get_by_md5(&snac1, pid, &m2))) {
104-                            xs *st = mastoapi_status(&snac1, m2);
105-                            anc = xs_list_insert(anc, 0, st);
106+                            if (valid_status(timeline_get_by_md5(&snac1, pid, &m2))) {
107+                                xs *st = mastoapi_status(&snac1, m2);
108+                                anc = xs_list_insert(anc, 0, st);
109+                            }
110+                            else
111+                                break;
112                         }
113-                        else
114-                            break;
115-                    }
116 
117-                    /* build the children list */
118-                    xs *children = object_children(xs_dict_get(msg, "id"));
119-                    p = children;
120+                        /* build the children list */
121+                        xs *children = object_children(xs_dict_get(msg, "id"));
122+                        p = children;
123 
124-                    while (xs_list_iter(&p, &v)) {
125-                        xs *m2 = NULL;
126+                        while (xs_list_iter(&p, &v)) {
127+                            xs *m2 = NULL;
128 
129-                        if (valid_status(timeline_get_by_md5(&snac1, v, &m2))) {
130-                            if (xs_is_null(xs_dict_get(m2, "name"))) {
131-                                xs *st = mastoapi_status(&snac1, m2);
132-                                des = xs_list_append(des, st);
133+                            if (valid_status(timeline_get_by_md5(&snac1, v, &m2))) {
134+                                if (xs_is_null(xs_dict_get(m2, "name"))) {
135+                                    xs *st = mastoapi_status(&snac1, m2);
136+                                    des = xs_list_append(des, st);
137+                                }
138                             }
139                         }
140-                    }
141 
142-                    out = xs_dict_new();
143-                    out = xs_dict_append(out, "ancestors",   anc);
144-                    out = xs_dict_append(out, "descendants", des);
145-                }
146-                else
147-                if (strcmp(op, "reblogged_by") == 0 || /** **/
148-                    strcmp(op, "favourited_by") == 0) { /** **/
149-                    /* return the list of people who liked or boosted this */
150-                    out = xs_list_new();
151+                        out = xs_dict_new();
152+                        out = xs_dict_append(out, "ancestors",   anc);
153+                        out = xs_dict_append(out, "descendants", des);
154+                    }
155+                    else
156+                    if (strcmp(op, "reblogged_by") == 0 || /** **/
157+                        strcmp(op, "favourited_by") == 0) { /** **/
158+                        /* return the list of people who liked or boosted this */
159+                        out = xs_list_new();
160 
161-                    xs *l = NULL;
162+                        xs *l = NULL;
163 
164-                    if (op[0] == 'r')
165-                        l = object_announces(xs_dict_get(msg, "id"));
166-                    else
167-                        l = object_likes(xs_dict_get(msg, "id"));
168+                        if (op[0] == 'r')
169+                            l = object_announces(xs_dict_get(msg, "id"));
170+                        else
171+                            l = object_likes(xs_dict_get(msg, "id"));
172 
173-                    xs_list *p = l;
174-                    xs_str *v;
175+                        xs_list *p = l;
176+                        xs_str *v;
177 
178-                    while (xs_list_iter(&p, &v)) {
179-                        xs *actor2 = NULL;
180+                        while (xs_list_iter(&p, &v)) {
181+                            xs *actor2 = NULL;
182 
183-                        if (valid_status(object_get_by_md5(v, &actor2))) {
184-                            xs *acct2 = mastoapi_account(actor2);
185+                            if (valid_status(object_get_by_md5(v, &actor2))) {
186+                                xs *acct2 = mastoapi_account(actor2);
187 
188-                            out = xs_list_append(out, acct2);
189+                                out = xs_list_append(out, acct2);
190+                            }
191                         }
192                     }
193                 }
194-            }
195-            else
196-                srv_debug(1, xs_fmt("mastoapi status: bad id %s", id));
197+                else
198+                    srv_debug(1, xs_fmt("mastoapi status: bad id %s", id));
199 
200-            if (out != NULL) {
201-                *body  = xs_json_dumps_pp(out, 4);
202-                *ctype = "application/json";
203-                status = 200;
204+                if (out != NULL) {
205+                    *body  = xs_json_dumps_pp(out, 4);
206+                    *ctype = "application/json";
207+                    status = 200;
208+                }
209             }
210         }
211+        else
212+            status = 401;
213     }
214     else
215     if (strcmp(cmd, "/v1/preferences") == 0) { /** **/
216@@ -1622,43 +1631,47 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
217     }
218     else
219     if (strcmp(cmd, "/v2/search") == 0) { /** **/
220-        const char *q      = xs_dict_get(args, "q");
221-        const char *type   = xs_dict_get(args, "type");
222-        const char *offset = xs_dict_get(args, "offset");
223+        if (logged_in) {
224+            const char *q      = xs_dict_get(args, "q");
225+            const char *type   = xs_dict_get(args, "type");
226+            const char *offset = xs_dict_get(args, "offset");
227 
228-        xs *acl = xs_list_new();
229-        xs *stl = xs_list_new();
230-        xs *htl = xs_list_new();
231-        xs *res = xs_dict_new();
232+            xs *acl = xs_list_new();
233+            xs *stl = xs_list_new();
234+            xs *htl = xs_list_new();
235+            xs *res = xs_dict_new();
236 
237-        if (xs_is_null(offset) || strcmp(offset, "0") == 0) {
238-            /* reply something only for offset 0; otherwise,
239-               apps like Tusky keep asking again and again */
240+            if (xs_is_null(offset) || strcmp(offset, "0") == 0) {
241+                /* reply something only for offset 0; otherwise,
242+                   apps like Tusky keep asking again and again */
243 
244-            if (!xs_is_null(q) && !xs_is_null(type) && strcmp(type, "accounts") == 0) {
245-                /* do a webfinger query */
246-                char *actor = NULL;
247-                char *user  = NULL;
248+                if (!xs_is_null(q) && !xs_is_null(type) && strcmp(type, "accounts") == 0) {
249+                    /* do a webfinger query */
250+                    char *actor = NULL;
251+                    char *user  = NULL;
252 
253-                if (valid_status(webfinger_request(q, &actor, &user))) {
254-                    xs *actor_o = NULL;
255+                    if (valid_status(webfinger_request(q, &actor, &user))) {
256+                        xs *actor_o = NULL;
257 
258-                    if (valid_status(actor_request(&snac1, actor, &actor_o))) {
259-                        xs *acct = mastoapi_account(actor_o);
260+                        if (valid_status(actor_request(&snac1, actor, &actor_o))) {
261+                            xs *acct = mastoapi_account(actor_o);
262 
263-                        acl = xs_list_append(acl, acct);
264+                            acl = xs_list_append(acl, acct);
265+                        }
266                     }
267                 }
268             }
269-        }
270 
271-        res = xs_dict_append(res, "accounts", acl);
272-        res = xs_dict_append(res, "statuses", stl);
273-        res = xs_dict_append(res, "hashtags", htl);
274+            res = xs_dict_append(res, "accounts", acl);
275+            res = xs_dict_append(res, "statuses", stl);
276+            res = xs_dict_append(res, "hashtags", htl);
277 
278-        *body  = xs_json_dumps_pp(res, 4);
279-        *ctype = "application/json";
280-        status = 200;
281+            *body  = xs_json_dumps_pp(res, 4);
282+            *ctype = "application/json";
283+            status = 200;
284+        }
285+        else
286+            status = 401;
287     }
288 
289     /* user cleanup */