summaryrefslogtreecommitdiff
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,
1038} 1038}
1039 1039
1040 1040
1041xs_dict *msg_collection(snac *snac, const char *id) 1041xs_dict *msg_collection(snac *snac, const char *id, int items)
1042/* creates an empty OrderedCollection message */ 1042/* creates an empty OrderedCollection message */
1043{ 1043{
1044 xs_dict *msg = msg_base(snac, "OrderedCollection", id, NULL, NULL, NULL); 1044 xs_dict *msg = msg_base(snac, "OrderedCollection", id, NULL, NULL, NULL);
1045 xs *ol = xs_list_new(); 1045 xs *n = xs_number_new(items);
1046 1046
1047 msg = xs_dict_append(msg, "attributedTo", snac->actor); 1047 msg = xs_dict_append(msg, "attributedTo", snac->actor);
1048 msg = xs_dict_append(msg, "orderedItems", ol); 1048 msg = xs_dict_append(msg, "totalItems", n);
1049 msg = xs_dict_append(msg, "totalItems", xs_stock(0));
1050 1049
1051 return msg; 1050 return msg;
1052} 1051}
@@ -1218,7 +1217,30 @@ xs_dict *msg_actor(snac *snac)
1218 } 1217 }
1219 1218
1220 /* add the metadata as attachments of PropertyValue */ 1219 /* add the metadata as attachments of PropertyValue */
1221 const xs_dict *metadata = xs_dict_get(snac->config, "metadata"); 1220 xs *metadata = NULL;
1221 const xs_dict *md = xs_dict_get(snac->config, "metadata");
1222
1223 if (xs_type(md) == XSTYPE_DICT)
1224 metadata = xs_dup(md);
1225 else
1226 if (xs_type(md) == XSTYPE_STRING) {
1227 metadata = xs_dict_new();
1228 xs *l = xs_split(md, "\n");
1229 const char *ll;
1230
1231 xs_list_foreach(l, ll) {
1232 xs *kv = xs_split_n(ll, "=", 1);
1233 const char *k = xs_list_get(kv, 0);
1234 const char *v = xs_list_get(kv, 1);
1235
1236 if (k && v) {
1237 xs *kk = xs_strip_i(xs_dup(k));
1238 xs *vv = xs_strip_i(xs_dup(v));
1239 metadata = xs_dict_set(metadata, kk, vv);
1240 }
1241 }
1242 }
1243
1222 if (xs_type(metadata) == XSTYPE_DICT) { 1244 if (xs_type(metadata) == XSTYPE_DICT) {
1223 xs *attach = xs_list_new(); 1245 xs *attach = xs_list_new();
1224 const xs_str *k; 1246 const xs_str *k;
@@ -1264,6 +1286,10 @@ xs_dict *msg_actor(snac *snac)
1264 msg = xs_dict_set(msg, "alsoKnownAs", loaka); 1286 msg = xs_dict_set(msg, "alsoKnownAs", loaka);
1265 } 1287 }
1266 1288
1289 const xs_val *manually = xs_dict_get(snac->config, "approve_followers");
1290 msg = xs_dict_set(msg, "manuallyApprovesFollowers",
1291 xs_stock(xs_is_true(manually) ? XSTYPE_TRUE : XSTYPE_FALSE));
1292
1267 return msg; 1293 return msg;
1268} 1294}
1269 1295
@@ -1900,22 +1926,31 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req)
1900 object_add(actor, actor_obj); 1926 object_add(actor, actor_obj);
1901 } 1927 }
1902 1928
1903 xs *f_msg = xs_dup(msg); 1929 if (xs_is_true(xs_dict_get(snac->config, "approve_followers"))) {
1904 xs *reply = msg_accept(snac, f_msg, actor); 1930 pending_add(snac, actor, msg);
1905 1931
1906 post_message(snac, actor, reply); 1932 snac_log(snac, xs_fmt("new pending follower approval %s", actor));
1907
1908 if (xs_is_null(xs_dict_get(f_msg, "published"))) {
1909 /* add a date if it doesn't include one (Mastodon) */
1910 xs *date = xs_str_utctime(0, ISO_DATE_SPEC);
1911 f_msg = xs_dict_set(f_msg, "published", date);
1912 } 1933 }
1934 else {
1935 /* automatic following */
1936 xs *f_msg = xs_dup(msg);
1937 xs *reply = msg_accept(snac, f_msg, actor);
1938
1939 post_message(snac, actor, reply);
1940
1941 if (xs_is_null(xs_dict_get(f_msg, "published"))) {
1942 /* add a date if it doesn't include one (Mastodon) */
1943 xs *date = xs_str_utctime(0, ISO_DATE_SPEC);
1944 f_msg = xs_dict_set(f_msg, "published", date);
1945 }
1946
1947 timeline_add(snac, id, f_msg);
1913 1948
1914 timeline_add(snac, id, f_msg); 1949 follower_add(snac, actor);
1915 1950
1916 follower_add(snac, actor); 1951 snac_log(snac, xs_fmt("new follower %s", actor));
1952 }
1917 1953
1918 snac_log(snac, xs_fmt("new follower %s", actor));
1919 do_notify = 1; 1954 do_notify = 1;
1920 } 1955 }
1921 else 1956 else
@@ -1937,6 +1972,11 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req)
1937 do_notify = 1; 1972 do_notify = 1;
1938 } 1973 }
1939 else 1974 else
1975 if (pending_check(snac, actor)) {
1976 pending_del(snac, actor);
1977 snac_log(snac, xs_fmt("cancelled pending follow from %s", actor));
1978 }
1979 else
1940 snac_log(snac, xs_fmt("error deleting follower %s", actor)); 1980 snac_log(snac, xs_fmt("error deleting follower %s", actor));
1941 } 1981 }
1942 } 1982 }
@@ -2796,6 +2836,8 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path,
2796 2836
2797 *ctype = "application/activity+json"; 2837 *ctype = "application/activity+json";
2798 2838
2839 int show_contact_metrics = xs_is_true(xs_dict_get(snac.config, "show_contact_metrics"));
2840
2799 if (p_path == NULL) { 2841 if (p_path == NULL) {
2800 /* if there was no component after the user, it's an actor request */ 2842 /* if there was no component after the user, it's an actor request */
2801 msg = msg_actor(&snac); 2843 msg = msg_actor(&snac);
@@ -2809,7 +2851,6 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path,
2809 if (strcmp(p_path, "outbox") == 0 || strcmp(p_path, "featured") == 0) { 2851 if (strcmp(p_path, "outbox") == 0 || strcmp(p_path, "featured") == 0) {
2810 xs *id = xs_fmt("%s/%s", snac.actor, p_path); 2852 xs *id = xs_fmt("%s/%s", snac.actor, p_path);
2811 xs *list = xs_list_new(); 2853 xs *list = xs_list_new();
2812 msg = msg_collection(&snac, id);
2813 const char *v; 2854 const char *v;
2814 int tc = 0; 2855 int tc = 0;
2815 2856
@@ -2831,14 +2872,32 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path,
2831 } 2872 }
2832 2873
2833 /* replace the 'orderedItems' with the latest posts */ 2874 /* replace the 'orderedItems' with the latest posts */
2834 xs *items = xs_number_new(xs_list_len(list)); 2875 msg = msg_collection(&snac, id, xs_list_len(list));
2835 msg = xs_dict_set(msg, "orderedItems", list); 2876 msg = xs_dict_set(msg, "orderedItems", list);
2836 msg = xs_dict_set(msg, "totalItems", items);
2837 } 2877 }
2838 else 2878 else
2839 if (strcmp(p_path, "followers") == 0 || strcmp(p_path, "following") == 0) { 2879 if (strcmp(p_path, "followers") == 0) {
2880 int total = 0;
2881
2882 if (show_contact_metrics) {
2883 xs *l = follower_list(&snac);
2884 total = xs_list_len(l);
2885 }
2886
2887 xs *id = xs_fmt("%s/%s", snac.actor, p_path);
2888 msg = msg_collection(&snac, id, total);
2889 }
2890 else
2891 if (strcmp(p_path, "following") == 0) {
2892 int total = 0;
2893
2894 if (show_contact_metrics) {
2895 xs *l = following_list(&snac);
2896 total = xs_list_len(l);
2897 }
2898
2840 xs *id = xs_fmt("%s/%s", snac.actor, p_path); 2899 xs *id = xs_fmt("%s/%s", snac.actor, p_path);
2841 msg = msg_collection(&snac, id); 2900 msg = msg_collection(&snac, id, total);
2842 } 2901 }
2843 else 2902 else
2844 if (xs_startswith(p_path, "p/")) { 2903 if (xs_startswith(p_path, "p/")) {