Browse Source

New function msg_actor().

default 2 years ago
parent
commit
e132ce5076
6 changed files with 110 additions and 2 deletions
  1. 55 0
      activitypub.c
  2. 0 2
      data.c
  3. 1 0
      http.c
  4. 1 0
      main.c
  5. 1 0
      snac.c
  6. 52 0
      xs_mime.h

+ 55 - 0
activitypub.c

@@ -5,6 +5,7 @@
 #include "xs_encdec.h"
 #include "xs_json.h"
 #include "xs_curl.h"
+#include "xs_mime.h"
 
 #include "snac.h"
 
@@ -195,6 +196,59 @@ d_char *msg_update(snac *snac, char *object)
 }
 
 
+d_char *msg_actor(snac *snac)
+/* create a Person message for this actor */
+{
+    xs *ctxt = xs_list_new();
+    xs *icon = xs_dict_new();
+    xs *keys = xs_dict_new();
+    xs *avtr = NULL;
+    xs *kid  = NULL;
+    d_char *msg = msg_base(snac, "Person", snac->actor, NULL, NULL);
+    char *p;
+    int n;
+
+    /* change the @context (is this really necessary?) */
+    ctxt = xs_list_append(ctxt, "https:/" "/www.w3.org/ns/activitystreams");
+    ctxt = xs_list_append(ctxt, "https:/" "/w3id.org/security/v1");
+    msg = xs_dict_set(msg, "@context",          ctxt);
+
+    msg = xs_dict_set(msg, "url",               snac->actor);
+    msg = xs_dict_set(msg, "name",              xs_dict_get(snac->config, "name"));
+    msg = xs_dict_set(msg, "preferredUsername", snac->uid);
+    msg = xs_dict_set(msg, "published",         xs_dict_get(snac->config, "published"));
+    msg = xs_dict_set(msg, "summary",           xs_dict_get(snac->config, "bio"));
+
+    char *folders[] = { "inbox", "outbox", "followers", "following", NULL };
+
+    for (n = 0; folders[n]; n++) {
+        xs *f = xs_fmt("%s/%s", snac->actor, folders[n]);
+        msg = xs_dict_set(msg, folders[n], f);
+    }
+
+    p = xs_dict_get(snac->config, "avatar");
+
+    if (*p == '\0')
+        avtr = xs_fmt("%s/susie.png", srv_baseurl);
+    else
+        avtr = xs_dup(p);
+
+    icon = xs_dict_append(icon, "type",         "Image");
+    icon = xs_dict_append(icon, "mediaType",    xs_mime_by_ext(avtr));
+    icon = xs_dict_append(icon, "url",          avtr);
+    msg = xs_dict_set(msg, "icon", icon);
+
+    kid = xs_fmt("%s#main-key", snac->actor);
+
+    keys = xs_dict_append(keys, "id",           kid);
+    keys = xs_dict_append(keys, "owner",        snac->actor);
+    keys = xs_dict_append(keys, "publicKeyPem", xs_dict_get(snac->key, "public"));
+    msg = xs_dict_set(msg, "publicKey", keys);
+
+    return msg;
+}
+
+
 /** queues **/
 
 void process_message(snac *snac, char *msg, char *req)
@@ -356,6 +410,7 @@ int activitypub_get_handler(d_char *req, char *q_path,
 
     if (p_path == NULL) {
         /* if there was no component after the user, it's an actor request */
+        msg = msg_actor(&snac);
     }
     else
     if (strcmp(p_path, "outbox") == 0) {

+ 0 - 2
data.c

@@ -601,8 +601,6 @@ void timeline_admire(snac *snac, char *id, char *admirer, int like)
 
             msg = xs_dict_set(msg, "_snac", meta);
 
-            xs *j1 = xs_json_dumps_pp(msg, 4);
-
             unlink(ofn);
 
             _timeline_write(snac, id, msg, xs_dict_get(meta, "parent"));

+ 1 - 0
http.c

@@ -86,6 +86,7 @@ d_char *http_signed_request(snac *snac, char *method, char *url,
     hdrs = xs_dict_append(hdrs, "date",         date);
     hdrs = xs_dict_append(hdrs, "signature",    signature);
     hdrs = xs_dict_append(hdrs, "digest",       digest);
+    hdrs = xs_dict_append(hdrs, "host",         xs_dict_get(srv_config, "host"));
     hdrs = xs_dict_append(hdrs, "user-agent",   "snac/2.x");
 
     response = xs_http_request(method, url, hdrs,

+ 1 - 0
main.c

@@ -50,6 +50,7 @@ char *get_argv(int *argi, int argc, char *argv[])
 
 #define GET_ARGV() get_argv(&argi, argc, argv)
 
+
 int main(int argc, char *argv[])
 {
     char *cmd;

+ 1 - 0
snac.c

@@ -11,6 +11,7 @@
 #include "xs_openssl.h"
 #include "xs_socket.h"
 #include "xs_httpd.h"
+#include "xs_mime.h"
 
 #include "snac.h"
 

+ 52 - 0
xs_mime.h

@@ -0,0 +1,52 @@
+/* copyright (c) 2022 grunfink - MIT license */
+
+#ifndef _XS_MIME
+
+#define _XS_MIME
+
+char *xs_mime_by_ext(char *file);
+
+#ifdef XS_IMPLEMENTATION
+
+/* intentionally brain-dead simple */
+struct _mime_info {
+    char *type;
+    char *ext;
+} mime_info[] = {
+    { "application/json",   ".json" },
+    { "image/gif",          ".gif" },
+    { "image/jpeg",         ".jpeg" },
+    { "image/jpeg",         ".jpg" },
+    { "image/png",          ".png" },
+    { "image/webp",         ".webp" },
+    { "text/css",           ".css" },
+    { "text/html",          ".html" },
+    { "text/plain",         ".txt" },
+    { "text/xml",           ".xml" },
+    { NULL, NULL }
+};
+
+
+char *xs_mime_by_ext(char *file)
+/* returns the MIME type by file extension */
+{
+    struct _mime_info *mi = mime_info;
+    char *p = NULL;
+
+    while (p == NULL && mi->type != NULL) {
+        if (xs_endswith(file, mi->ext))
+            p = mi->type;
+
+        mi++;
+    }
+
+    if (p == NULL)
+        p = "application/octet-stream";
+
+    return p;
+}
+
+
+#endif /* XS_IMPLEMENTATION */
+
+#endif /* XS_MIME */