aboutsummaryrefslogtreecommitdiff
path: root/activitypub.c
diff options
context:
space:
mode:
Diffstat (limited to 'activitypub.c')
-rw-r--r--activitypub.c101
1 files changed, 80 insertions, 21 deletions
diff --git a/activitypub.c b/activitypub.c
index 473675d..773df78 100644
--- a/activitypub.c
+++ b/activitypub.c
@@ -1038,15 +1038,14 @@ xs_dict *msg_base(snac *snac, const char *type, const char *id,
}
-xs_dict *msg_collection(snac *snac, const char *id)
+xs_dict *msg_collection(snac *snac, const char *id, int items)
/* creates an empty OrderedCollection message */
{
xs_dict *msg = msg_base(snac, "OrderedCollection", id, NULL, NULL, NULL);
- xs *ol = xs_list_new();
+ xs *n = xs_number_new(items);
msg = xs_dict_append(msg, "attributedTo", snac->actor);
- msg = xs_dict_append(msg, "orderedItems", ol);
- msg = xs_dict_append(msg, "totalItems", xs_stock(0));
+ msg = xs_dict_append(msg, "totalItems", n);
return msg;
}
@@ -1218,7 +1217,30 @@ xs_dict *msg_actor(snac *snac)
}
/* add the metadata as attachments of PropertyValue */
- const xs_dict *metadata = xs_dict_get(snac->config, "metadata");
+ xs *metadata = NULL;
+ const xs_dict *md = xs_dict_get(snac->config, "metadata");
+
+ if (xs_type(md) == XSTYPE_DICT)
+ metadata = xs_dup(md);
+ else
+ if (xs_type(md) == XSTYPE_STRING) {
+ metadata = xs_dict_new();
+ xs *l = xs_split(md, "\n");
+ const char *ll;
+
+ xs_list_foreach(l, ll) {
+ xs *kv = xs_split_n(ll, "=", 1);
+ const char *k = xs_list_get(kv, 0);
+ const char *v = xs_list_get(kv, 1);
+
+ if (k && v) {
+ xs *kk = xs_strip_i(xs_dup(k));
+ xs *vv = xs_strip_i(xs_dup(v));
+ metadata = xs_dict_set(metadata, kk, vv);
+ }
+ }
+ }
+
if (xs_type(metadata) == XSTYPE_DICT) {
xs *attach = xs_list_new();
const xs_str *k;
@@ -1264,6 +1286,10 @@ xs_dict *msg_actor(snac *snac)
msg = xs_dict_set(msg, "alsoKnownAs", loaka);
}
+ const xs_val *manually = xs_dict_get(snac->config, "approve_followers");
+ msg = xs_dict_set(msg, "manuallyApprovesFollowers",
+ xs_stock(xs_is_true(manually) ? XSTYPE_TRUE : XSTYPE_FALSE));
+
return msg;
}
@@ -1900,22 +1926,31 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req)
object_add(actor, actor_obj);
}
- xs *f_msg = xs_dup(msg);
- xs *reply = msg_accept(snac, f_msg, actor);
+ if (xs_is_true(xs_dict_get(snac->config, "approve_followers"))) {
+ pending_add(snac, actor, msg);
- post_message(snac, actor, reply);
-
- if (xs_is_null(xs_dict_get(f_msg, "published"))) {
- /* add a date if it doesn't include one (Mastodon) */
- xs *date = xs_str_utctime(0, ISO_DATE_SPEC);
- f_msg = xs_dict_set(f_msg, "published", date);
+ snac_log(snac, xs_fmt("new pending follower approval %s", actor));
}
+ else {
+ /* automatic following */
+ xs *f_msg = xs_dup(msg);
+ xs *reply = msg_accept(snac, f_msg, actor);
+
+ post_message(snac, actor, reply);
+
+ if (xs_is_null(xs_dict_get(f_msg, "published"))) {
+ /* add a date if it doesn't include one (Mastodon) */
+ xs *date = xs_str_utctime(0, ISO_DATE_SPEC);
+ f_msg = xs_dict_set(f_msg, "published", date);
+ }
- timeline_add(snac, id, f_msg);
+ timeline_add(snac, id, f_msg);
- follower_add(snac, actor);
+ follower_add(snac, actor);
+
+ snac_log(snac, xs_fmt("new follower %s", actor));
+ }
- snac_log(snac, xs_fmt("new follower %s", actor));
do_notify = 1;
}
else
@@ -1937,6 +1972,11 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req)
do_notify = 1;
}
else
+ if (pending_check(snac, actor)) {
+ pending_del(snac, actor);
+ snac_log(snac, xs_fmt("cancelled pending follow from %s", actor));
+ }
+ else
snac_log(snac, xs_fmt("error deleting follower %s", actor));
}
}
@@ -2796,6 +2836,8 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path,
*ctype = "application/activity+json";
+ int show_contact_metrics = xs_is_true(xs_dict_get(snac.config, "show_contact_metrics"));
+
if (p_path == NULL) {
/* if there was no component after the user, it's an actor request */
msg = msg_actor(&snac);
@@ -2809,7 +2851,6 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path,
if (strcmp(p_path, "outbox") == 0 || strcmp(p_path, "featured") == 0) {
xs *id = xs_fmt("%s/%s", snac.actor, p_path);
xs *list = xs_list_new();
- msg = msg_collection(&snac, id);
const char *v;
int tc = 0;
@@ -2831,14 +2872,32 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path,
}
/* replace the 'orderedItems' with the latest posts */
- xs *items = xs_number_new(xs_list_len(list));
+ msg = msg_collection(&snac, id, xs_list_len(list));
msg = xs_dict_set(msg, "orderedItems", list);
- msg = xs_dict_set(msg, "totalItems", items);
}
else
- if (strcmp(p_path, "followers") == 0 || strcmp(p_path, "following") == 0) {
+ if (strcmp(p_path, "followers") == 0) {
+ int total = 0;
+
+ if (show_contact_metrics) {
+ xs *l = follower_list(&snac);
+ total = xs_list_len(l);
+ }
+
+ xs *id = xs_fmt("%s/%s", snac.actor, p_path);
+ msg = msg_collection(&snac, id, total);
+ }
+ else
+ if (strcmp(p_path, "following") == 0) {
+ int total = 0;
+
+ if (show_contact_metrics) {
+ xs *l = following_list(&snac);
+ total = xs_list_len(l);
+ }
+
xs *id = xs_fmt("%s/%s", snac.actor, p_path);
- msg = msg_collection(&snac, id);
+ msg = msg_collection(&snac, id, total);
}
else
if (xs_startswith(p_path, "p/")) {