diff options
| author | 2024-04-29 09:26:37 +0200 | |
|---|---|---|
| committer | 2024-04-29 09:26:37 +0200 | |
| commit | 29fb43079761796e34209611ec93bd651b871cab (patch) | |
| tree | 92032b2b28cf51dcc534124334b6ff8561724441 | |
| parent | More work in lists. (diff) | |
| download | penes-snac2-29fb43079761796e34209611ec93bd651b871cab.tar.gz penes-snac2-29fb43079761796e34209611ec93bd651b871cab.tar.xz penes-snac2-29fb43079761796e34209611ec93bd651b871cab.zip | |
More work in lists.
| -rw-r--r-- | data.c | 38 | ||||
| -rw-r--r-- | httpd.c | 2 | ||||
| -rw-r--r-- | mastoapi.c | 110 | ||||
| -rw-r--r-- | snac.h | 6 |
4 files changed, 141 insertions, 15 deletions
| @@ -1732,6 +1732,7 @@ xs_list *tag_search(char *tag, int skip, int show) | |||
| 1732 | /** lists **/ | 1732 | /** lists **/ |
| 1733 | 1733 | ||
| 1734 | xs_val *list_maint(snac *user, const char *list, int op) | 1734 | xs_val *list_maint(snac *user, const char *list, int op) |
| 1735 | /* list maintenance */ | ||
| 1735 | { | 1736 | { |
| 1736 | xs_val *l = NULL; | 1737 | xs_val *l = NULL; |
| 1737 | 1738 | ||
| @@ -1810,15 +1811,48 @@ xs_val *list_maint(snac *user, const char *list, int op) | |||
| 1810 | fn = xs_replace_i(fn, ".id", ".lst"); | 1811 | fn = xs_replace_i(fn, ".id", ".lst"); |
| 1811 | unlink(fn); | 1812 | unlink(fn); |
| 1812 | 1813 | ||
| 1813 | fn = xs_replace_i(fn, ".list", ".idx"); | 1814 | fn = xs_replace_i(fn, ".lst", ".idx"); |
| 1814 | unlink(fn); | 1815 | unlink(fn); |
| 1815 | } | 1816 | } |
| 1816 | } | 1817 | } |
| 1817 | 1818 | ||
| 1818 | break; | 1819 | break; |
| 1820 | } | ||
| 1821 | |||
| 1822 | return l; | ||
| 1823 | } | ||
| 1824 | |||
| 1825 | |||
| 1826 | xs_val *list_content(snac *user, const char *list, const char *actor_md5, int op) | ||
| 1827 | /* list content management */ | ||
| 1828 | { | ||
| 1829 | xs_val *l = NULL; | ||
| 1830 | |||
| 1831 | if (!xs_is_hex(list)) | ||
| 1832 | return NULL; | ||
| 1833 | |||
| 1834 | if (actor_md5 != NULL && !xs_is_hex(actor_md5)) | ||
| 1835 | return NULL; | ||
| 1836 | |||
| 1837 | xs *fn = xs_fmt("%s/list/%s.lst", user->basedir, list); | ||
| 1838 | |||
| 1839 | switch (op) { | ||
| 1840 | case 0: /** list content **/ | ||
| 1841 | l = index_list(fn, XS_ALL); | ||
| 1819 | 1842 | ||
| 1820 | case 3: /** list content (list is the id) **/ | ||
| 1821 | break; | 1843 | break; |
| 1844 | |||
| 1845 | case 1: /** append actor to list **/ | ||
| 1846 | if (actor_md5 != NULL) { | ||
| 1847 | if (!index_in(fn, actor_md5)) | ||
| 1848 | index_add_md5(fn, actor_md5); | ||
| 1849 | } | ||
| 1850 | |||
| 1851 | break; | ||
| 1852 | |||
| 1853 | case 2: /** delete actor from list **/ | ||
| 1854 | if (actor_md5 != NULL) | ||
| 1855 | index_del_md5(fn, actor_md5); | ||
| 1822 | } | 1856 | } |
| 1823 | 1857 | ||
| 1824 | return l; | 1858 | return l; |
| @@ -360,7 +360,7 @@ void httpd_connection(FILE *f) | |||
| 360 | #ifndef NO_MASTODON_API | 360 | #ifndef NO_MASTODON_API |
| 361 | if (status == 0) | 361 | if (status == 0) |
| 362 | status = mastoapi_delete_handler(req, q_path, | 362 | status = mastoapi_delete_handler(req, q_path, |
| 363 | &body, &b_size, &ctype); | 363 | payload, p_size, &body, &b_size, &ctype); |
| 364 | #endif | 364 | #endif |
| 365 | } | 365 | } |
| 366 | 366 | ||
| @@ -1765,7 +1765,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, | |||
| 1765 | status = 200; | 1765 | status = 200; |
| 1766 | } | 1766 | } |
| 1767 | else | 1767 | else |
| 1768 | if (strcmp(cmd, "/v1/lists") == 0) { /** **/ | 1768 | if (strcmp(cmd, "/v1/lists") == 0) { /** list of lists **/ |
| 1769 | if (logged_in) { | 1769 | if (logged_in) { |
| 1770 | xs *lol = list_maint(&snac1, NULL, 0); | 1770 | xs *lol = list_maint(&snac1, NULL, 0); |
| 1771 | xs *l = xs_list_new(); | 1771 | xs *l = xs_list_new(); |
| @@ -1789,6 +1789,36 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, | |||
| 1789 | } | 1789 | } |
| 1790 | } | 1790 | } |
| 1791 | else | 1791 | else |
| 1792 | if (xs_startswith(cmd, "/v1/lists/")) { /** list information **/ | ||
| 1793 | if (logged_in) { | ||
| 1794 | xs *l = xs_split(cmd, "/"); | ||
| 1795 | char *op = xs_list_get(l, -1); | ||
| 1796 | char *id = xs_list_get(l, -2); | ||
| 1797 | |||
| 1798 | if (op && id && xs_is_hex(id)) { | ||
| 1799 | if (strcmp(op, "accounts") == 0) { | ||
| 1800 | xs *actors = list_content(&snac1, id, NULL, 0); | ||
| 1801 | xs *out = xs_list_new(); | ||
| 1802 | int c = 0; | ||
| 1803 | char *v; | ||
| 1804 | |||
| 1805 | while (xs_list_next(actors, &v, &c)) { | ||
| 1806 | xs *actor = NULL; | ||
| 1807 | |||
| 1808 | if (valid_status(object_get_by_md5(v, &actor))) { | ||
| 1809 | xs *acct = mastoapi_account(actor); | ||
| 1810 | out = xs_list_append(out, acct); | ||
| 1811 | } | ||
| 1812 | } | ||
| 1813 | |||
| 1814 | *body = xs_json_dumps(out, 4); | ||
| 1815 | *ctype = "application/json"; | ||
| 1816 | status = 200; | ||
| 1817 | } | ||
| 1818 | } | ||
| 1819 | } | ||
| 1820 | } | ||
| 1821 | else | ||
| 1792 | if (strcmp(cmd, "/v1/scheduled_statuses") == 0) { /** **/ | 1822 | if (strcmp(cmd, "/v1/scheduled_statuses") == 0) { /** **/ |
| 1793 | /* snac does not schedule notes */ | 1823 | /* snac does not schedule notes */ |
| 1794 | *body = xs_dup("[]"); | 1824 | *body = xs_dup("[]"); |
| @@ -2676,6 +2706,29 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path, | |||
| 2676 | status = 422; | 2706 | status = 422; |
| 2677 | } | 2707 | } |
| 2678 | } | 2708 | } |
| 2709 | if (xs_startswith(cmd, "/v1/lists/")) { /** list maintenance **/ | ||
| 2710 | if (logged_in) { | ||
| 2711 | xs *l = xs_split(cmd, "/"); | ||
| 2712 | char *op = xs_list_get(l, -1); | ||
| 2713 | char *id = xs_list_get(l, -2); | ||
| 2714 | |||
| 2715 | if (op && id && xs_is_hex(id)) { | ||
| 2716 | if (strcmp(op, "accounts") == 0) { | ||
| 2717 | xs_list *accts = xs_dict_get(args, "account_ids[]"); | ||
| 2718 | int c = 0; | ||
| 2719 | char *v; | ||
| 2720 | |||
| 2721 | while (xs_list_next(accts, &v, &c)) { | ||
| 2722 | list_content(&snac, id, v, 1); | ||
| 2723 | } | ||
| 2724 | |||
| 2725 | status = 200; | ||
| 2726 | } | ||
| 2727 | } | ||
| 2728 | } | ||
| 2729 | else | ||
| 2730 | status = 422; | ||
| 2731 | } | ||
| 2679 | 2732 | ||
| 2680 | /* user cleanup */ | 2733 | /* user cleanup */ |
| 2681 | if (logged_in) | 2734 | if (logged_in) |
| @@ -2688,18 +2741,39 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path, | |||
| 2688 | 2741 | ||
| 2689 | 2742 | ||
| 2690 | int mastoapi_delete_handler(const xs_dict *req, const char *q_path, | 2743 | int mastoapi_delete_handler(const xs_dict *req, const char *q_path, |
| 2691 | char **body, int *b_size, char **ctype) { | 2744 | const char *payload, int p_size, |
| 2692 | 2745 | char **body, int *b_size, char **ctype) | |
| 2693 | (void)req; | 2746 | { |
| 2747 | (void)p_size; | ||
| 2694 | (void)body; | 2748 | (void)body; |
| 2695 | (void)b_size; | 2749 | (void)b_size; |
| 2696 | (void)ctype; | 2750 | (void)ctype; |
| 2697 | 2751 | ||
| 2698 | int status = 404; | ||
| 2699 | |||
| 2700 | if (!xs_startswith(q_path, "/api/v1/") && !xs_startswith(q_path, "/api/v2/")) | 2752 | if (!xs_startswith(q_path, "/api/v1/") && !xs_startswith(q_path, "/api/v2/")) |
| 2701 | return 0; | 2753 | return 0; |
| 2702 | 2754 | ||
| 2755 | int status = 404; | ||
| 2756 | xs *args = NULL; | ||
| 2757 | char *i_ctype = xs_dict_get(req, "content-type"); | ||
| 2758 | |||
| 2759 | if (i_ctype && xs_startswith(i_ctype, "application/json")) { | ||
| 2760 | if (!xs_is_null(payload)) | ||
| 2761 | args = xs_json_loads(payload); | ||
| 2762 | } | ||
| 2763 | else if (i_ctype && xs_startswith(i_ctype, "application/x-www-form-urlencoded")) | ||
| 2764 | { | ||
| 2765 | // Some apps send form data instead of json so we should cater for those | ||
| 2766 | if (!xs_is_null(payload)) { | ||
| 2767 | xs *upl = xs_url_dec(payload); | ||
| 2768 | args = xs_url_vars(upl); | ||
| 2769 | } | ||
| 2770 | } | ||
| 2771 | else | ||
| 2772 | args = xs_dup(xs_dict_get(req, "p_vars")); | ||
| 2773 | |||
| 2774 | if (args == NULL) | ||
| 2775 | return 400; | ||
| 2776 | |||
| 2703 | snac snac = {0}; | 2777 | snac snac = {0}; |
| 2704 | int logged_in = process_auth_token(&snac, req); | 2778 | int logged_in = process_auth_token(&snac, req); |
| 2705 | 2779 | ||
| @@ -2713,10 +2787,26 @@ int mastoapi_delete_handler(const xs_dict *req, const char *q_path, | |||
| 2713 | if (xs_startswith(cmd, "/v1/lists/")) { | 2787 | if (xs_startswith(cmd, "/v1/lists/")) { |
| 2714 | if (logged_in) { | 2788 | if (logged_in) { |
| 2715 | xs *l = xs_split(cmd, "/"); | 2789 | xs *l = xs_split(cmd, "/"); |
| 2716 | char *id = xs_list_get(l, -1); | 2790 | char *p = xs_list_get(l, -1); |
| 2717 | 2791 | ||
| 2718 | if (xs_is_hex(id)) { | 2792 | if (p) { |
| 2719 | list_maint(&snac, id, 2); | 2793 | if (strcmp(p, "accounts") == 0) { |
| 2794 | /* delete account from list */ | ||
| 2795 | p = xs_list_get(l, -2); | ||
| 2796 | xs_list *accts = xs_dict_get(args, "account_ids[]"); | ||
| 2797 | int c = 0; | ||
| 2798 | char *v; | ||
| 2799 | |||
| 2800 | while (xs_list_next(accts, &v, &c)) { | ||
| 2801 | list_content(&snac, p, v, 2); | ||
| 2802 | } | ||
| 2803 | } | ||
| 2804 | else { | ||
| 2805 | /* delete list */ | ||
| 2806 | if (xs_is_hex(p)) { | ||
| 2807 | list_maint(&snac, p, 2); | ||
| 2808 | } | ||
| 2809 | } | ||
| 2720 | } | 2810 | } |
| 2721 | 2811 | ||
| 2722 | status = 200; | 2812 | status = 200; |
| @@ -175,6 +175,7 @@ void tag_index(const char *id, const xs_dict *obj); | |||
| 175 | xs_list *tag_search(char *tag, int skip, int show); | 175 | xs_list *tag_search(char *tag, int skip, int show); |
| 176 | 176 | ||
| 177 | xs_val *list_maint(snac *user, const char *list, int op); | 177 | xs_val *list_maint(snac *user, const char *list, int op); |
| 178 | xs_val *list_content(snac *user, const char *list_id, const char *actor_md5, int op); | ||
| 178 | 179 | ||
| 179 | int actor_add(const char *actor, xs_dict *msg); | 180 | int actor_add(const char *actor, xs_dict *msg); |
| 180 | int actor_get(const char *actor, xs_dict **data); | 181 | int actor_get(const char *actor, xs_dict **data); |
| @@ -339,11 +340,12 @@ int oauth_post_handler(const xs_dict *req, const char *q_path, | |||
| 339 | char **body, int *b_size, char **ctype); | 340 | char **body, int *b_size, char **ctype); |
| 340 | int mastoapi_get_handler(const xs_dict *req, const char *q_path, | 341 | int mastoapi_get_handler(const xs_dict *req, const char *q_path, |
| 341 | char **body, int *b_size, char **ctype); | 342 | char **body, int *b_size, char **ctype); |
| 342 | int mastoapi_delete_handler(const xs_dict *req, const char *q_path, | ||
| 343 | char **body, int *b_size, char **ctype); | ||
| 344 | int mastoapi_post_handler(const xs_dict *req, const char *q_path, | 343 | int mastoapi_post_handler(const xs_dict *req, const char *q_path, |
| 345 | const char *payload, int p_size, | 344 | const char *payload, int p_size, |
| 346 | char **body, int *b_size, char **ctype); | 345 | char **body, int *b_size, char **ctype); |
| 346 | int mastoapi_delete_handler(const xs_dict *req, const char *q_path, | ||
| 347 | const char *payload, int p_size, | ||
| 348 | char **body, int *b_size, char **ctype); | ||
| 347 | int mastoapi_put_handler(const xs_dict *req, const char *q_path, | 349 | int mastoapi_put_handler(const xs_dict *req, const char *q_path, |
| 348 | const char *payload, int p_size, | 350 | const char *payload, int p_size, |
| 349 | char **body, int *b_size, char **ctype); | 351 | char **body, int *b_size, char **ctype); |