commit 28d21ff

grunfink  ·  2026-02-07 16:04:00 +0000 UTC
parents f0d6f2b, 8c959fc
Merge pull request 'Bug fix: Poll voting in mastoapi: Check global object store + Prevent voting when not allowed' (#552) from davidrv00/snac2-fork:vote-fix into master

Reviewed-on: https://codeberg.org/grunfink/snac2/pulls/552
1 files changed,  +46, -25
+46, -25
 1@@ -3713,44 +3713,65 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
 2                 /* skip the 'fake' part of the id */
 3                 mid = MID_TO_MD5(mid);
 4 
 5-                if (valid_status(timeline_get_by_md5(&snac, mid, &msg))) {
 6+                /* try timeline first, then global object store for remote posts */
 7+                int found = valid_status(timeline_get_by_md5(&snac, mid, &msg));
 8+                if (!found)
 9+                    found = valid_status(object_get_by_md5(mid, &msg));
10+
11+                if (found) {
12                     const char *id   = xs_dict_get(msg, "id");
13                     const char *atto = get_atto(msg);
14+                    int closed = 0;
15+                    const char *f_closed = NULL;
16 
17-                    const xs_list *opts = xs_dict_get(msg, "oneOf");
18-                    if (opts == NULL)
19-                        opts = xs_dict_get(msg, "anyOf");
20+                    if ((f_closed = xs_dict_get(msg, "closed")) != NULL) {
21+                        /* it has a closed date... but is it in the past? */
22+                        time_t t0 = time(NULL);
23+                        time_t t1 = xs_parse_iso_date(f_closed, 0);
24 
25-                    if (op == NULL) {
26+                        if (t1 < t0)
27+                            closed = 1;
28                     }
29-                    else
30-                    if (strcmp(op, "votes") == 0) {
31-                        const xs_list *choices = xs_dict_get(args, "choices[]");
32 
33-                        if (xs_is_null(choices))
34-                            choices = xs_dict_get(args, "choices");
35+                    if (closed || was_question_voted(&snac, id))
36+                        status = HTTP_STATUS_UNPROCESSABLE_CONTENT;
37+                    else {
38+                        const xs_list *opts = xs_dict_get(msg, "oneOf");
39+                        if (opts == NULL)
40+                            opts = xs_dict_get(msg, "anyOf");
41 
42-                        if (xs_type(choices) == XSTYPE_LIST) {
43-                            const xs_str *v;
44+                        if (op == NULL) {
45+                        }
46+                        else {
47+                            if (strcmp(op, "votes") == 0) {
48+                                const xs_list *choices = xs_dict_get(args, "choices[]");
49+
50+                                if (xs_is_null(choices))
51+                                    choices = xs_dict_get(args, "choices");
52+
53+                                if (xs_type(choices) == XSTYPE_LIST) {
54+                                    const xs_str *v;
55 
56-                            int c = 0;
57-                            while (xs_list_next(choices, &v, &c)) {
58-                                int io           = atoi(v);
59-                                const xs_dict *o = xs_list_get(opts, io);
60+                                    int c = 0;
61+                                    while (xs_list_next(choices, &v, &c)) {
62+                                        int io           = atoi(v);
63+                                        const xs_dict *o = xs_list_get(opts, io);
64 
65-                                if (o) {
66-                                    const char *name = xs_dict_get(o, "name");
67+                                        if (o) {
68+                                            const char *name = xs_dict_get(o, "name");
69 
70-                                    xs *msg = msg_note(&snac, "", atto, (char *)id, NULL, 1, NULL, NULL);
71-                                    msg = xs_dict_append(msg, "name", name);
72+                                            xs *msg = msg_note(&snac, "", atto, (char *)id, NULL, 1, NULL, NULL);
73+                                            msg = xs_dict_append(msg, "name", name);
74 
75-                                    xs *c_msg = msg_create(&snac, msg);
76-                                    enqueue_message(&snac, c_msg);
77-                                    timeline_add(&snac, xs_dict_get(msg, "id"), msg);
78+                                            xs *c_msg = msg_create(&snac, msg);
79+                                            enqueue_message(&snac, c_msg);
80+                                            timeline_add(&snac, xs_dict_get(msg, "id"), msg);
81+                                        }
82+                                    }
83+
84+                                    out = mastoapi_poll(&snac, msg);
85                                 }
86                             }
87-
88-                            out = mastoapi_poll(&snac, msg);
89                         }
90                     }
91                 }