فهرست منبع

Implemented Mastodon-like /authorize_interaction.

default 3 ماه پیش
والد
کامیت
b993e26346
2فایلهای تغییر یافته به همراه103 افزوده شده و 0 حذف شده
  1. 61 0
      html.c
  2. 42 0
      httpd.c

+ 61 - 0
html.c

@@ -3124,6 +3124,21 @@ int html_get_handler(const xs_dict *req, const char *q_path,
         else
             return HTTP_STATUS_NOT_FOUND;
     }
+    else
+    if (strcmp(v, "auth-int-bridge") == 0) {
+        const char *login  = xs_dict_get(q_vars, "login");
+        const char *id     = xs_dict_get(q_vars, "id");
+        const char *action = xs_dict_get(q_vars, "action");
+
+        if (xs_is_string(login) && xs_is_string(id) && xs_is_string(action)) {
+            *body = xs_fmt("%s/%s/authorize_interaction?action=%s&id=%s",
+                srv_baseurl, login, action, id);
+
+            return HTTP_STATUS_SEE_OTHER;
+        }
+        else
+            return HTTP_STATUS_NOT_FOUND;
+    }
 
     uid = xs_dup(v);
 
@@ -3695,6 +3710,52 @@ int html_get_handler(const xs_dict *req, const char *q_path,
             status  = HTTP_STATUS_SEE_OTHER;
         }
     }
+    else
+    if (strcmp(p_path, "authorize_interaction") == 0) { /** follow, like or boost from Mastodon **/
+        if (!login(&snac, req)) {
+            *body  = xs_dup(uid);
+            status = HTTP_STATUS_UNAUTHORIZED;
+        }
+        else {
+            status = HTTP_STATUS_NOT_FOUND;
+
+            const char *id     = xs_dict_get(q_vars, "id");
+            const char *action = xs_dict_get(q_vars, "action");
+
+            if (xs_is_string(id) && xs_is_string(action)) {
+                if (strcmp(action, "Follow") == 0) {
+                    xs *msg = msg_follow(&snac, id);
+
+                    if (msg != NULL) {
+                        const char *actor = xs_dict_get(msg, "object");
+
+                        following_add(&snac, actor, msg);
+
+                        enqueue_output_by_actor(&snac, msg, actor, 0);
+
+                        status = HTTP_STATUS_SEE_OTHER;
+                    }
+                }
+                else
+                if (xs_match(action, "Like|Boost|Announce")) {
+                    /* bring the post */
+                    xs *msg = msg_admiration(&snac, id, *action == 'L' ? "Like" : "Announce");
+
+                    if (msg != NULL) {
+                        enqueue_message(&snac, msg);
+                        timeline_admire(&snac, xs_dict_get(msg, "object"), snac.actor, *action == 'L' ? 1 : 0);
+
+                        status = HTTP_STATUS_SEE_OTHER;
+                    }
+                }
+            }
+
+            if (status == HTTP_STATUS_SEE_OTHER) {
+                *body   = xs_fmt("%s/admin", snac.actor);
+                *b_size = strlen(*body);
+            }
+        }
+    }
     else
         status = HTTP_STATUS_NOT_FOUND;
 

+ 42 - 0
httpd.c

@@ -182,6 +182,29 @@ const char *share_page = ""
 "";
 
 
+const char *authorize_interaction_page = ""
+"<!DOCTYPE html>\n"
+"<html>\n"
+"<head>\n"
+"<title>%s - snac</title>\n"
+"<meta content=\"width=device-width, initial-scale=1, minimum-scale=1, user-scalable=no\" name=\"viewport\">\n"
+"<link rel=\"stylesheet\" type=\"text/css\" href=\"%s/style.css\"/>\n"
+"<style>:root {color-scheme: light dark}</style>\n"
+"</head>\n"
+"<body><h1>%s authorize interaction</h1>\n"
+"<form method=\"get\" action=\"%s/auth-int-bridge\">\n"
+"<select name=\"action\">\n"
+"<option value=\"Follow\">Follow</option>\n"
+"<option value=\"Like\">Like</option>\n"
+"<option value=\"Boost\">Boost</option>\n"
+"</select> %s\n"
+"<input type=\"hidden\" name=\"id\" value=\"%s\">\n"
+"<p>Login: <input type=\"text\" name=\"login\" autocapitalize=\"off\" required=\"required\"></p>\n"
+"<input type=\"submit\" value=\"OK\">\n"
+"</form><p>%s</p></body></html>\n"
+"";
+
+
 int server_get_handler(xs_dict *req, const char *q_path,
                        char **body, int *b_size, char **ctype)
 /* basic server services */
@@ -318,6 +341,25 @@ int server_get_handler(xs_dict *req, const char *q_path,
             USER_AGENT
         );
     }
+    else
+    if (strcmp(q_path, "/authorize_interaction") == 0) {
+        const xs_dict *q_vars = xs_dict_get(req, "q_vars");
+        const char *uri  = xs_dict_get(q_vars, "uri");
+
+        if (xs_is_string(uri)) {
+            status = HTTP_STATUS_OK;
+            *ctype = "text/html; charset=utf-8";
+            *body  = xs_fmt(authorize_interaction_page,
+                xs_dict_get(srv_config, "host"),
+                srv_baseurl,
+                xs_dict_get(srv_config, "host"),
+                srv_baseurl,
+                uri,
+                uri,
+                USER_AGENT
+            );
+        }
+    }
 
     if (status != 0)
         srv_debug(1, xs_fmt("server_get_handler serving '%s' %d", q_path, status));