summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar default2025-01-16 14:20:07 +0100
committerGravatar default2025-01-16 14:20:07 +0100
commitb993e26346f885586ff0533a3b309ed7d1e910cf (patch)
tree53c78a997b8231aea0353dfcf7d0391dd3c2f63c
parentUpdated RELEASE_NOTES. (diff)
downloadpenes-snac2-b993e26346f885586ff0533a3b309ed7d1e910cf.tar.gz
penes-snac2-b993e26346f885586ff0533a3b309ed7d1e910cf.tar.xz
penes-snac2-b993e26346f885586ff0533a3b309ed7d1e910cf.zip
Implemented Mastodon-like /authorize_interaction.
-rw-r--r--html.c61
-rw-r--r--httpd.c42
2 files changed, 103 insertions, 0 deletions
diff --git a/html.c b/html.c
index c55937d..aad2f31 100644
--- a/html.c
+++ b/html.c
@@ -3124,6 +3124,21 @@ int html_get_handler(const xs_dict *req, const char *q_path,
3124 else 3124 else
3125 return HTTP_STATUS_NOT_FOUND; 3125 return HTTP_STATUS_NOT_FOUND;
3126 } 3126 }
3127 else
3128 if (strcmp(v, "auth-int-bridge") == 0) {
3129 const char *login = xs_dict_get(q_vars, "login");
3130 const char *id = xs_dict_get(q_vars, "id");
3131 const char *action = xs_dict_get(q_vars, "action");
3132
3133 if (xs_is_string(login) && xs_is_string(id) && xs_is_string(action)) {
3134 *body = xs_fmt("%s/%s/authorize_interaction?action=%s&id=%s",
3135 srv_baseurl, login, action, id);
3136
3137 return HTTP_STATUS_SEE_OTHER;
3138 }
3139 else
3140 return HTTP_STATUS_NOT_FOUND;
3141 }
3127 3142
3128 uid = xs_dup(v); 3143 uid = xs_dup(v);
3129 3144
@@ -3696,6 +3711,52 @@ int html_get_handler(const xs_dict *req, const char *q_path,
3696 } 3711 }
3697 } 3712 }
3698 else 3713 else
3714 if (strcmp(p_path, "authorize_interaction") == 0) { /** follow, like or boost from Mastodon **/
3715 if (!login(&snac, req)) {
3716 *body = xs_dup(uid);
3717 status = HTTP_STATUS_UNAUTHORIZED;
3718 }
3719 else {
3720 status = HTTP_STATUS_NOT_FOUND;
3721
3722 const char *id = xs_dict_get(q_vars, "id");
3723 const char *action = xs_dict_get(q_vars, "action");
3724
3725 if (xs_is_string(id) && xs_is_string(action)) {
3726 if (strcmp(action, "Follow") == 0) {
3727 xs *msg = msg_follow(&snac, id);
3728
3729 if (msg != NULL) {
3730 const char *actor = xs_dict_get(msg, "object");
3731
3732 following_add(&snac, actor, msg);
3733
3734 enqueue_output_by_actor(&snac, msg, actor, 0);
3735
3736 status = HTTP_STATUS_SEE_OTHER;
3737 }
3738 }
3739 else
3740 if (xs_match(action, "Like|Boost|Announce")) {
3741 /* bring the post */
3742 xs *msg = msg_admiration(&snac, id, *action == 'L' ? "Like" : "Announce");
3743
3744 if (msg != NULL) {
3745 enqueue_message(&snac, msg);
3746 timeline_admire(&snac, xs_dict_get(msg, "object"), snac.actor, *action == 'L' ? 1 : 0);
3747
3748 status = HTTP_STATUS_SEE_OTHER;
3749 }
3750 }
3751 }
3752
3753 if (status == HTTP_STATUS_SEE_OTHER) {
3754 *body = xs_fmt("%s/admin", snac.actor);
3755 *b_size = strlen(*body);
3756 }
3757 }
3758 }
3759 else
3699 status = HTTP_STATUS_NOT_FOUND; 3760 status = HTTP_STATUS_NOT_FOUND;
3700 3761
3701 user_free(&snac); 3762 user_free(&snac);
diff --git a/httpd.c b/httpd.c
index dda40b9..74628e3 100644
--- a/httpd.c
+++ b/httpd.c
@@ -182,6 +182,29 @@ const char *share_page = ""
182""; 182"";
183 183
184 184
185const char *authorize_interaction_page = ""
186"<!DOCTYPE html>\n"
187"<html>\n"
188"<head>\n"
189"<title>%s - snac</title>\n"
190"<meta content=\"width=device-width, initial-scale=1, minimum-scale=1, user-scalable=no\" name=\"viewport\">\n"
191"<link rel=\"stylesheet\" type=\"text/css\" href=\"%s/style.css\"/>\n"
192"<style>:root {color-scheme: light dark}</style>\n"
193"</head>\n"
194"<body><h1>%s authorize interaction</h1>\n"
195"<form method=\"get\" action=\"%s/auth-int-bridge\">\n"
196"<select name=\"action\">\n"
197"<option value=\"Follow\">Follow</option>\n"
198"<option value=\"Like\">Like</option>\n"
199"<option value=\"Boost\">Boost</option>\n"
200"</select> %s\n"
201"<input type=\"hidden\" name=\"id\" value=\"%s\">\n"
202"<p>Login: <input type=\"text\" name=\"login\" autocapitalize=\"off\" required=\"required\"></p>\n"
203"<input type=\"submit\" value=\"OK\">\n"
204"</form><p>%s</p></body></html>\n"
205"";
206
207
185int server_get_handler(xs_dict *req, const char *q_path, 208int server_get_handler(xs_dict *req, const char *q_path,
186 char **body, int *b_size, char **ctype) 209 char **body, int *b_size, char **ctype)
187/* basic server services */ 210/* basic server services */
@@ -318,6 +341,25 @@ int server_get_handler(xs_dict *req, const char *q_path,
318 USER_AGENT 341 USER_AGENT
319 ); 342 );
320 } 343 }
344 else
345 if (strcmp(q_path, "/authorize_interaction") == 0) {
346 const xs_dict *q_vars = xs_dict_get(req, "q_vars");
347 const char *uri = xs_dict_get(q_vars, "uri");
348
349 if (xs_is_string(uri)) {
350 status = HTTP_STATUS_OK;
351 *ctype = "text/html; charset=utf-8";
352 *body = xs_fmt(authorize_interaction_page,
353 xs_dict_get(srv_config, "host"),
354 srv_baseurl,
355 xs_dict_get(srv_config, "host"),
356 srv_baseurl,
357 uri,
358 uri,
359 USER_AGENT
360 );
361 }
362 }
321 363
322 if (status != 0) 364 if (status != 0)
323 srv_debug(1, xs_fmt("server_get_handler serving '%s' %d", q_path, status)); 365 srv_debug(1, xs_fmt("server_get_handler serving '%s' %d", q_path, status));