diff options
| author | 2023-04-11 21:07:47 +0200 | |
|---|---|---|
| committer | 2023-04-11 21:07:47 +0200 | |
| commit | c0a48f1f4e690cfe63b57e287fe917b5e27bfb87 (patch) | |
| tree | 54fe55a2ef86851f9ebe007f34b2811179439241 | |
| parent | Added some comments. (diff) | |
| download | snac2-c0a48f1f4e690cfe63b57e287fe917b5e27bfb87.tar.gz snac2-c0a48f1f4e690cfe63b57e287fe917b5e27bfb87.tar.xz snac2-c0a48f1f4e690cfe63b57e287fe917b5e27bfb87.zip | |
Added support for likes and boosts.
| -rw-r--r-- | httpd.c | 6 | ||||
| -rw-r--r-- | mastoapi.c | 162 |
2 files changed, 138 insertions, 30 deletions
| @@ -188,15 +188,15 @@ void httpd_connection(FILE *f) | |||
| 188 | else | 188 | else |
| 189 | if (strcmp(method, "POST") == 0) { | 189 | if (strcmp(method, "POST") == 0) { |
| 190 | if (status == 0) | 190 | if (status == 0) |
| 191 | status = activitypub_post_handler(req, q_path, | 191 | status = oauth_post_handler(req, q_path, |
| 192 | payload, p_size, &body, &b_size, &ctype); | 192 | payload, p_size, &body, &b_size, &ctype); |
| 193 | 193 | ||
| 194 | if (status == 0) | 194 | if (status == 0) |
| 195 | status = oauth_post_handler(req, q_path, | 195 | status = mastoapi_post_handler(req, q_path, |
| 196 | payload, p_size, &body, &b_size, &ctype); | 196 | payload, p_size, &body, &b_size, &ctype); |
| 197 | 197 | ||
| 198 | if (status == 0) | 198 | if (status == 0) |
| 199 | status = mastoapi_post_handler(req, q_path, | 199 | status = activitypub_post_handler(req, q_path, |
| 200 | payload, p_size, &body, &b_size, &ctype); | 200 | payload, p_size, &body, &b_size, &ctype); |
| 201 | 201 | ||
| 202 | if (status == 0) | 202 | if (status == 0) |
| @@ -596,25 +596,11 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg) | |||
| 596 | } | 596 | } |
| 597 | 597 | ||
| 598 | 598 | ||
| 599 | int mastoapi_get_handler(const xs_dict *req, const char *q_path, | 599 | int process_auth_token(snac *snac, const xs_dict *req) |
| 600 | char **body, int *b_size, char **ctype) | 600 | /* processes an authorization token, if there is one */ |
| 601 | { | 601 | { |
| 602 | if (!xs_startswith(q_path, "/api/v1/")) | ||
| 603 | return 0; | ||
| 604 | |||
| 605 | srv_debug(0, xs_fmt("mastoapi_get_handler %s", q_path)); | ||
| 606 | /* { | ||
| 607 | xs *j = xs_json_dumps_pp(req, 4); | ||
| 608 | printf("mastoapi get:\n%s\n", j); | ||
| 609 | }*/ | ||
| 610 | |||
| 611 | int status = 404; | ||
| 612 | xs_dict *args = xs_dict_get(req, "q_vars"); | ||
| 613 | xs *cmd = xs_replace(q_path, "/api/v1", ""); | ||
| 614 | char *v; | ||
| 615 | |||
| 616 | snac snac = {0}; | ||
| 617 | int logged_in = 0; | 602 | int logged_in = 0; |
| 603 | char *v; | ||
| 618 | 604 | ||
| 619 | /* if there is an authorization field, try to validate it */ | 605 | /* if there is an authorization field, try to validate it */ |
| 620 | if (!xs_is_null(v = xs_dict_get(req, "authorization")) && xs_startswith(v, "Bearer ")) { | 606 | 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, | |||
| 624 | if (token != NULL) { | 610 | if (token != NULL) { |
| 625 | const char *uid = xs_dict_get(token, "uid"); | 611 | const char *uid = xs_dict_get(token, "uid"); |
| 626 | 612 | ||
| 627 | if (!xs_is_null(uid) && user_open(&snac, uid)) { | 613 | if (!xs_is_null(uid) && user_open(snac, uid)) { |
| 628 | logged_in = 1; | 614 | logged_in = 1; |
| 629 | srv_debug(0, xs_fmt("mastoapi auth: valid token for user %s", uid)); | 615 | srv_debug(0, xs_fmt("mastoapi auth: valid token for user %s", uid)); |
| 630 | } | 616 | } |
| @@ -635,6 +621,29 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, | |||
| 635 | srv_log(xs_fmt("mastoapi auth: invalid token %s", tokid)); | 621 | srv_log(xs_fmt("mastoapi auth: invalid token %s", tokid)); |
| 636 | } | 622 | } |
| 637 | 623 | ||
| 624 | return logged_in; | ||
| 625 | } | ||
| 626 | |||
| 627 | |||
| 628 | int mastoapi_get_handler(const xs_dict *req, const char *q_path, | ||
| 629 | char **body, int *b_size, char **ctype) | ||
| 630 | { | ||
| 631 | if (!xs_startswith(q_path, "/api/v1/")) | ||
| 632 | return 0; | ||
| 633 | |||
| 634 | srv_debug(0, xs_fmt("mastoapi_get_handler %s", q_path)); | ||
| 635 | /* { | ||
| 636 | xs *j = xs_json_dumps_pp(req, 4); | ||
| 637 | printf("mastoapi get:\n%s\n", j); | ||
| 638 | }*/ | ||
| 639 | |||
| 640 | int status = 404; | ||
| 641 | xs_dict *args = xs_dict_get(req, "q_vars"); | ||
| 642 | xs *cmd = xs_replace(q_path, "/api/v1", ""); | ||
| 643 | |||
| 644 | snac snac = {0}; | ||
| 645 | int logged_in = process_auth_token(&snac, req);; | ||
| 646 | |||
| 638 | if (strcmp(cmd, "/accounts/verify_credentials") == 0) { | 647 | if (strcmp(cmd, "/accounts/verify_credentials") == 0) { |
| 639 | if (logged_in) { | 648 | if (logged_in) { |
| 640 | xs *acct = xs_dict_new(); | 649 | xs *acct = xs_dict_new(); |
| @@ -946,28 +955,31 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path, | |||
| 946 | } | 955 | } |
| 947 | 956 | ||
| 948 | int status = 404; | 957 | int status = 404; |
| 949 | xs *msg = NULL; | 958 | xs *args = NULL; |
| 950 | char *i_ctype = xs_dict_get(req, "content-type"); | 959 | char *i_ctype = xs_dict_get(req, "content-type"); |
| 951 | 960 | ||
| 952 | if (xs_startswith(i_ctype, "application/json")) | 961 | if (i_ctype && xs_startswith(i_ctype, "application/json")) |
| 953 | msg = xs_json_loads(payload); | 962 | args = xs_json_loads(payload); |
| 954 | else | 963 | else |
| 955 | msg = xs_dup(xs_dict_get(req, "p_vars")); | 964 | args = xs_dup(xs_dict_get(req, "p_vars")); |
| 956 | 965 | ||
| 957 | if (msg == NULL) | 966 | if (args == NULL) |
| 958 | return 400; | 967 | return 400; |
| 959 | 968 | ||
| 960 | { | 969 | { |
| 961 | xs *j = xs_json_dumps_pp(msg, 4); | 970 | xs *j = xs_json_dumps_pp(args, 4); |
| 962 | printf("%s\n", j); | 971 | printf("%s\n", j); |
| 963 | } | 972 | } |
| 964 | 973 | ||
| 965 | xs *cmd = xs_replace(q_path, "/api/v1", ""); | 974 | xs *cmd = xs_replace(q_path, "/api/v1", ""); |
| 966 | 975 | ||
| 976 | snac snac = {0}; | ||
| 977 | int logged_in = process_auth_token(&snac, req);; | ||
| 978 | |||
| 967 | if (strcmp(cmd, "/apps") == 0) { | 979 | if (strcmp(cmd, "/apps") == 0) { |
| 968 | const char *name = xs_dict_get(msg, "client_name"); | 980 | const char *name = xs_dict_get(args, "client_name"); |
| 969 | const char *ruri = xs_dict_get(msg, "redirect_uris"); | 981 | const char *ruri = xs_dict_get(args, "redirect_uris"); |
| 970 | const char *scope = xs_dict_get(msg, "scope"); | 982 | const char *scope = xs_dict_get(args, "scope"); |
| 971 | 983 | ||
| 972 | if (xs_type(ruri) == XSTYPE_LIST) | 984 | if (xs_type(ruri) == XSTYPE_LIST) |
| 973 | ruri = xs_dict_get(ruri, 0); | 985 | ruri = xs_dict_get(ruri, 0); |
| @@ -1000,6 +1012,102 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path, | |||
| 1000 | srv_debug(0, xs_fmt("mastoapi apps: new app %s", cid)); | 1012 | srv_debug(0, xs_fmt("mastoapi apps: new app %s", cid)); |
| 1001 | } | 1013 | } |
| 1002 | } | 1014 | } |
| 1015 | else | ||
| 1016 | if (strcmp(cmd, "/statuses") == 0) { | ||
| 1017 | if (logged_in) { | ||
| 1018 | /* post a new Note */ | ||
| 1019 | /* TBD */ | ||
| 1020 | } | ||
| 1021 | else | ||
| 1022 | status = 401; | ||
| 1023 | } | ||
| 1024 | else | ||
| 1025 | if (xs_startswith(cmd, "/statuses")) { | ||
| 1026 | if (logged_in) { | ||
| 1027 | /* operations on a status */ | ||
| 1028 | xs *l = xs_split(cmd, "/"); | ||
| 1029 | const char *mid = xs_list_get(l, 2); | ||
| 1030 | const char *op = xs_list_get(l, 3); | ||
| 1031 | |||
| 1032 | if (!xs_is_null(mid)) { | ||
| 1033 | xs *msg = NULL; | ||
| 1034 | xs *out = NULL; | ||
| 1035 | |||
| 1036 | /* skip the fake part of the id (the date) */ | ||
| 1037 | mid += 14; | ||
| 1038 | |||
| 1039 | if (valid_status(timeline_get_by_md5(&snac, mid, &msg))) { | ||
| 1040 | char *id = xs_dict_get(msg, "id"); | ||
| 1041 | |||
| 1042 | if (op == NULL) { | ||
| 1043 | /* no operation (?) */ | ||
| 1044 | } | ||
| 1045 | else | ||
| 1046 | if (strcmp(op, "favourite") == 0) { | ||
| 1047 | xs *n_msg = msg_admiration(&snac, id, "Like"); | ||
| 1048 | |||
| 1049 | if (n_msg != NULL) { | ||
| 1050 | enqueue_message(&snac, n_msg); | ||
| 1051 | timeline_admire(&snac, xs_dict_get(n_msg, "object"), snac.actor, 1); | ||
| 1052 | |||
| 1053 | out = mastoapi_status(&snac, msg); | ||
| 1054 | } | ||
| 1055 | } | ||
| 1056 | else | ||
| 1057 | if (strcmp(op, "unfavourite") == 0) { | ||
| 1058 | /* snac does not support Undo+Like */ | ||
| 1059 | } | ||
| 1060 | else | ||
| 1061 | if (strcmp(op, "reblog") == 0) { | ||
| 1062 | xs *n_msg = msg_admiration(&snac, id, "Announce"); | ||
| 1063 | |||
| 1064 | if (n_msg != NULL) { | ||
| 1065 | enqueue_message(&snac, n_msg); | ||
| 1066 | timeline_admire(&snac, xs_dict_get(n_msg, "object"), snac.actor, 0); | ||
| 1067 | |||
| 1068 | out = mastoapi_status(&snac, msg); | ||
| 1069 | } | ||
| 1070 | } | ||
| 1071 | else | ||
| 1072 | if (strcmp(op, "unreblog") == 0) { | ||
| 1073 | /* snac does not support Undo+Announce */ | ||
| 1074 | } | ||
| 1075 | else | ||
| 1076 | if (strcmp(op, "bookmark") == 0) { | ||
| 1077 | /* snac does not support bookmarks */ | ||
| 1078 | } | ||
| 1079 | else | ||
| 1080 | if (strcmp(op, "unbookmark") == 0) { | ||
| 1081 | /* snac does not support bookmarks */ | ||
| 1082 | } | ||
| 1083 | else | ||
| 1084 | if (strcmp(op, "pin") == 0) { | ||
| 1085 | /* snac does not support pinning */ | ||
| 1086 | } | ||
| 1087 | else | ||
| 1088 | if (strcmp(op, "unpin") == 0) { | ||
| 1089 | /* snac does not support pinning */ | ||
| 1090 | } | ||
| 1091 | else | ||
| 1092 | if (strcmp(op, "mute") == 0) { | ||
| 1093 | /* Mastodon's mute is snac's hide */ | ||
| 1094 | } | ||
| 1095 | else | ||
| 1096 | if (strcmp(op, "unmute") == 0) { | ||
| 1097 | /* Mastodon's unmute is snac's unhide */ | ||
| 1098 | } | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | if (out != NULL) { | ||
| 1102 | *body = xs_json_dumps_pp(out, 4); | ||
| 1103 | *ctype = "application/json"; | ||
| 1104 | status = 200; | ||
| 1105 | } | ||
| 1106 | } | ||
| 1107 | } | ||
| 1108 | else | ||
| 1109 | status = 401; | ||
| 1110 | } | ||
| 1003 | 1111 | ||
| 1004 | return status; | 1112 | return status; |
| 1005 | } | 1113 | } |