diff options
Diffstat (limited to 'activitypub.c')
| -rw-r--r-- | activitypub.c | 101 |
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 | ||
| 1041 | xs_dict *msg_collection(snac *snac, const char *id) | 1041 | xs_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/")) { |