summaryrefslogtreecommitdiff
path: root/activitypub.c
diff options
context:
space:
mode:
Diffstat (limited to 'activitypub.c')
-rw-r--r--activitypub.c146
1 files changed, 119 insertions, 27 deletions
diff --git a/activitypub.c b/activitypub.c
index 73fbbc6..53f102e 100644
--- a/activitypub.c
+++ b/activitypub.c
@@ -125,10 +125,10 @@ int actor_request(snac *user, const char *actor, xs_dict **data)
125 *data = NULL; 125 *data = NULL;
126 126
127 /* get from disk first */ 127 /* get from disk first */
128 status = actor_get(actor, data); 128 status = actor_get_refresh(user, actor, data);
129 129
130 if (status != 200) { 130 if (!valid_status(status)) {
131 /* actor data non-existent or stale: get from the net */ 131 /* actor data non-existent: get from the net */
132 status = activitypub_request(user, actor, &payload); 132 status = activitypub_request(user, actor, &payload);
133 133
134 if (valid_status(status)) { 134 if (valid_status(status)) {
@@ -149,8 +149,6 @@ int actor_request(snac *user, const char *actor, xs_dict **data)
149 if (valid_status(status) && data && *data) 149 if (valid_status(status) && data && *data)
150 inbox_add_by_actor(*data); 150 inbox_add_by_actor(*data);
151 } 151 }
152 else
153 srv_debug(2, xs_fmt("NOT collected"));
154 152
155 return status; 153 return status;
156} 154}
@@ -313,6 +311,12 @@ int timeline_request(snac *snac, char **id, xs_str **wrk, int level)
313 if (level < MAX_CONVERSATION_LEVELS && !xs_is_null(*id)) { 311 if (level < MAX_CONVERSATION_LEVELS && !xs_is_null(*id)) {
314 xs *msg = NULL; 312 xs *msg = NULL;
315 313
314 /* from a blocked instance? discard and break */
315 if (is_instance_blocked(*id)) {
316 snac_debug(snac, 1, xs_fmt("timeline_request blocked instance %s", *id));
317 return status;
318 }
319
316 /* is the object already there? */ 320 /* is the object already there? */
317 if (!valid_status(object_get(*id, &msg))) { 321 if (!valid_status(object_get(*id, &msg))) {
318 /* no; download it */ 322 /* no; download it */
@@ -354,18 +358,22 @@ int timeline_request(snac *snac, char **id, xs_str **wrk, int level)
354 if (xs_match(type, "Note|Page|Article|Video")) { 358 if (xs_match(type, "Note|Page|Article|Video")) {
355 const char *actor = get_atto(object); 359 const char *actor = get_atto(object);
356 360
357 /* request (and drop) the actor for this entry */ 361 if (content_check("filter_reject.txt", object))
358 if (!xs_is_null(actor)) 362 snac_log(snac, xs_fmt("timeline_request rejected by content %s", nid));
359 actor_request(snac, actor, NULL); 363 else {
364 /* request (and drop) the actor for this entry */
365 if (!xs_is_null(actor))
366 actor_request(snac, actor, NULL);
360 367
361 /* does it have an ancestor? */ 368 /* does it have an ancestor? */
362 char *in_reply_to = xs_dict_get(object, "inReplyTo"); 369 char *in_reply_to = xs_dict_get(object, "inReplyTo");
363 370
364 /* store */ 371 /* store */
365 timeline_add(snac, nid, object); 372 timeline_add(snac, nid, object);
366 373
367 /* recurse! */ 374 /* recurse! */
368 timeline_request(snac, &in_reply_to, NULL, level + 1); 375 timeline_request(snac, &in_reply_to, NULL, level + 1);
376 }
369 } 377 }
370 } 378 }
371 } 379 }
@@ -623,6 +631,12 @@ int is_msg_for_me(snac *snac, const xs_dict *c_msg)
623 const char *type = xs_dict_get(c_msg, "type"); 631 const char *type = xs_dict_get(c_msg, "type");
624 const char *actor = xs_dict_get(c_msg, "actor"); 632 const char *actor = xs_dict_get(c_msg, "actor");
625 633
634 if (strcmp(actor, snac->actor) == 0) {
635 /* message by myself? (most probably via the shared-inbox) reject */
636 snac_debug(snac, 1, xs_fmt("ignoring message by myself"));
637 return 0;
638 }
639
626 if (xs_match(type, "Like|Announce")) { 640 if (xs_match(type, "Like|Announce")) {
627 const char *object = xs_dict_get(c_msg, "object"); 641 const char *object = xs_dict_get(c_msg, "object");
628 642
@@ -657,6 +671,12 @@ int is_msg_for_me(snac *snac, const xs_dict *c_msg)
657 return !xs_is_null(object) && strcmp(snac->actor, object) == 0; 671 return !xs_is_null(object) && strcmp(snac->actor, object) == 0;
658 } 672 }
659 673
674 /* only accept Ping directed to us */
675 if (xs_match(type, "Ping")) {
676 char *dest = xs_dict_get(c_msg, "to");
677 return !xs_is_null(dest) && strcmp(snac->actor, dest) == 0;
678 }
679
660 /* if it's not a Create or Update, allow as is */ 680 /* if it's not a Create or Update, allow as is */
661 if (!xs_match(type, "Create|Update")) { 681 if (!xs_match(type, "Create|Update")) {
662 return 1; 682 return 1;
@@ -1072,7 +1092,7 @@ xs_dict *msg_collection(snac *snac, char *id)
1072 1092
1073 msg = xs_dict_append(msg, "attributedTo", snac->actor); 1093 msg = xs_dict_append(msg, "attributedTo", snac->actor);
1074 msg = xs_dict_append(msg, "orderedItems", ol); 1094 msg = xs_dict_append(msg, "orderedItems", ol);
1075 msg = xs_dict_append(msg, "totalItems", xs_stock_0); 1095 msg = xs_dict_append(msg, "totalItems", xs_stock(0));
1076 1096
1077 return msg; 1097 return msg;
1078} 1098}
@@ -1129,8 +1149,10 @@ xs_dict *msg_admiration(snac *snac, char *object, char *type)
1129 1149
1130 if (valid_status(object_get(object, &a_msg))) { 1150 if (valid_status(object_get(object, &a_msg))) {
1131 xs *rcpts = xs_list_new(); 1151 xs *rcpts = xs_list_new();
1152 xs *o_md5 = xs_md5_hex(object, strlen(object));
1153 xs *id = xs_fmt("%s/%s/%s", snac->actor, *type == 'L' ? "l" : "a", o_md5);
1132 1154
1133 msg = msg_base(snac, type, "@dummy", snac->actor, "@now", object); 1155 msg = msg_base(snac, type, id, snac->actor, "@now", object);
1134 1156
1135 if (is_msg_public(a_msg)) 1157 if (is_msg_public(a_msg))
1136 rcpts = xs_list_append(rcpts, public_address); 1158 rcpts = xs_list_append(rcpts, public_address);
@@ -1146,6 +1168,33 @@ xs_dict *msg_admiration(snac *snac, char *object, char *type)
1146} 1168}
1147 1169
1148 1170
1171xs_dict *msg_repulsion(snac *user, char *id, char *type)
1172/* creates an Undo + admiration message */
1173{
1174 xs *a_msg = NULL;
1175 xs_dict *msg = NULL;
1176
1177 if (valid_status(object_get(id, &a_msg))) {
1178 /* create a clone of the original admiration message */
1179 xs *object = msg_admiration(user, id, type);
1180
1181 /* delete the published date */
1182 object = xs_dict_del(object, "published");
1183
1184 /* create an undo message for this object */
1185 msg = msg_undo(user, object);
1186
1187 /* copy the 'to' field */
1188 msg = xs_dict_set(msg, "to", xs_dict_get(object, "to"));
1189 }
1190
1191 /* now we despise this */
1192 object_unadmire(id, user->actor, *type == 'L' ? 1 : 0);
1193
1194 return msg;
1195}
1196
1197
1149xs_dict *msg_actor(snac *snac) 1198xs_dict *msg_actor(snac *snac)
1150/* create a Person message for this actor */ 1199/* create a Person message for this actor */
1151{ 1200{
@@ -1170,7 +1219,7 @@ xs_dict *msg_actor(snac *snac)
1170 msg = xs_dict_set(msg, "preferredUsername", snac->uid); 1219 msg = xs_dict_set(msg, "preferredUsername", snac->uid);
1171 msg = xs_dict_set(msg, "published", xs_dict_get(snac->config, "published")); 1220 msg = xs_dict_set(msg, "published", xs_dict_get(snac->config, "published"));
1172 1221
1173 xs *f_bio_2 = not_really_markdown(xs_dict_get(snac->config, "bio"), NULL); 1222 xs *f_bio_2 = not_really_markdown(xs_dict_get(snac->config, "bio"), NULL, NULL);
1174 f_bio = process_tags(snac, f_bio_2, &tags); 1223 f_bio = process_tags(snac, f_bio_2, &tags);
1175 msg = xs_dict_set(msg, "summary", f_bio); 1224 msg = xs_dict_set(msg, "summary", f_bio);
1176 msg = xs_dict_set(msg, "tag", tags); 1225 msg = xs_dict_set(msg, "tag", tags);
@@ -1378,7 +1427,7 @@ xs_dict *msg_note(snac *snac, const xs_str *content, const xs_val *rcpts,
1378 } 1427 }
1379 1428
1380 /* format the content */ 1429 /* format the content */
1381 fc2 = not_really_markdown(content, &atls); 1430 fc2 = not_really_markdown(content, &atls, &tag);
1382 1431
1383 if (in_reply_to != NULL && *in_reply_to) { 1432 if (in_reply_to != NULL && *in_reply_to) {
1384 xs *p_msg = NULL; 1433 xs *p_msg = NULL;
@@ -1556,6 +1605,7 @@ xs_dict *msg_question(snac *user, const char *content, xs_list *attach,
1556 } 1605 }
1557 1606
1558 if (xs_set_add(&seen, v2) == 1) { 1607 if (xs_set_add(&seen, v2) == 1) {
1608 d = xs_dict_append(d, "type", "Note");
1559 d = xs_dict_append(d, "name", v2); 1609 d = xs_dict_append(d, "name", v2);
1560 d = xs_dict_append(d, "replies", replies); 1610 d = xs_dict_append(d, "replies", replies);
1561 o = xs_list_append(o, d); 1611 o = xs_list_append(o, d);
@@ -1608,7 +1658,7 @@ int update_question(snac *user, const char *id)
1608 const char *name = xs_dict_get(v, "name"); 1658 const char *name = xs_dict_get(v, "name");
1609 if (name) { 1659 if (name) {
1610 lopts = xs_list_append(lopts, name); 1660 lopts = xs_list_append(lopts, name);
1611 rcnt = xs_dict_set(rcnt, name, xs_stock_0); 1661 rcnt = xs_dict_set(rcnt, name, xs_stock(0));
1612 } 1662 }
1613 } 1663 }
1614 1664
@@ -1891,6 +1941,8 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1891 } 1941 }
1892 else 1942 else
1893 if (strcmp(type, "Undo") == 0) { /** **/ 1943 if (strcmp(type, "Undo") == 0) { /** **/
1944 char *id = xs_dict_get(object, "object");
1945
1894 if (xs_type(object) != XSTYPE_DICT) 1946 if (xs_type(object) != XSTYPE_DICT)
1895 utype = "Follow"; 1947 utype = "Follow";
1896 1948
@@ -1903,6 +1955,23 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1903 snac_log(snac, xs_fmt("error deleting follower %s", actor)); 1955 snac_log(snac, xs_fmt("error deleting follower %s", actor));
1904 } 1956 }
1905 else 1957 else
1958 if (strcmp(utype, "Like") == 0) { /** **/
1959 int status = object_unadmire(id, actor, 1);
1960
1961 snac_log(snac, xs_fmt("Unlike for %s %d", id, status));
1962 }
1963 else
1964 if (strcmp(utype, "Announce") == 0) { /** **/
1965 int status = 200;
1966
1967 /* commented out: if a followed user boosts something that
1968 is requested and then unboosts, the post remains here,
1969 but with no apparent reason, and that is confusing */
1970 //status = object_unadmire(id, actor, 0);
1971
1972 snac_log(snac, xs_fmt("Unboost for %s %d", id, status));
1973 }
1974 else
1906 snac_debug(snac, 1, xs_fmt("ignored 'Undo' for object type '%s'", utype)); 1975 snac_debug(snac, 1, xs_fmt("ignored 'Undo' for object type '%s'", utype));
1907 } 1976 }
1908 else 1977 else
@@ -1912,7 +1981,7 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1912 return 1; 1981 return 1;
1913 } 1982 }
1914 1983
1915 if (strcmp(utype, "Note") == 0) { /** **/ 1984 if (xs_match(utype, "Note|Article")) { /** **/
1916 char *id = xs_dict_get(object, "id"); 1985 char *id = xs_dict_get(object, "id");
1917 char *in_reply_to = xs_dict_get(object, "inReplyTo"); 1986 char *in_reply_to = xs_dict_get(object, "inReplyTo");
1918 xs *wrk = NULL; 1987 xs *wrk = NULL;
@@ -1921,10 +1990,15 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1921 snac_debug(snac, 0, xs_fmt("dropped reply %s to hidden post %s", id, in_reply_to)); 1990 snac_debug(snac, 0, xs_fmt("dropped reply %s to hidden post %s", id, in_reply_to));
1922 } 1991 }
1923 else { 1992 else {
1993 if (content_check("filter_reject.txt", object)) {
1994 snac_log(snac, xs_fmt("rejected by content %s", id));
1995 return 1;
1996 }
1997
1924 timeline_request(snac, &in_reply_to, &wrk, 0); 1998 timeline_request(snac, &in_reply_to, &wrk, 0);
1925 1999
1926 if (timeline_add(snac, id, object)) { 2000 if (timeline_add(snac, id, object)) {
1927 snac_log(snac, xs_fmt("new 'Note' %s %s", actor, id)); 2001 snac_log(snac, xs_fmt("new '%s' %s %s", utype, actor, id));
1928 do_notify = 1; 2002 do_notify = 1;
1929 } 2003 }
1930 2004
@@ -1988,12 +2062,12 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
1988 if (xs_type(object) == XSTYPE_DICT) 2062 if (xs_type(object) == XSTYPE_DICT)
1989 object = xs_dict_get(object, "id"); 2063 object = xs_dict_get(object, "id");
1990 2064
1991 if (timeline_admire(snac, object, actor, 1) == 201) { 2065 if (timeline_admire(snac, object, actor, 1) == 201)
1992 snac_log(snac, xs_fmt("new 'Like' %s %s", actor, object)); 2066 snac_log(snac, xs_fmt("new 'Like' %s %s", actor, object));
1993 do_notify = 1;
1994 }
1995 else 2067 else
1996 snac_log(snac, xs_fmt("repeated 'Like' from %s to %s", actor, object)); 2068 snac_log(snac, xs_fmt("repeated 'Like' from %s to %s", actor, object));
2069
2070 do_notify = 1;
1997 } 2071 }
1998 else 2072 else
1999 if (strcmp(type, "Announce") == 0) { /** **/ 2073 if (strcmp(type, "Announce") == 0) { /** **/
@@ -2019,13 +2093,13 @@ int process_input_message(snac *snac, xs_dict *msg, xs_dict *req)
2019 xs *who_o = NULL; 2093 xs *who_o = NULL;
2020 2094
2021 if (valid_status(actor_request(snac, who, &who_o))) { 2095 if (valid_status(actor_request(snac, who, &who_o))) {
2022 if (timeline_admire(snac, object, actor, 0) == 201) { 2096 if (timeline_admire(snac, object, actor, 0) == 201)
2023 snac_log(snac, xs_fmt("new 'Announce' %s %s", actor, object)); 2097 snac_log(snac, xs_fmt("new 'Announce' %s %s", actor, object));
2024 do_notify = 1;
2025 }
2026 else 2098 else
2027 snac_log(snac, xs_fmt("repeated 'Announce' from %s to %s", 2099 snac_log(snac, xs_fmt("repeated 'Announce' from %s to %s",
2028 actor, object)); 2100 actor, object));
2101
2102 do_notify = 1;
2029 } 2103 }
2030 else 2104 else
2031 snac_debug(snac, 1, xs_fmt("dropped 'Announce' on actor request error %s", who)); 2105 snac_debug(snac, 1, xs_fmt("dropped 'Announce' on actor request error %s", who));
@@ -2236,6 +2310,24 @@ void process_user_queue_item(snac *snac, xs_dict *q_item)
2236 verify_links(snac); 2310 verify_links(snac);
2237 } 2311 }
2238 else 2312 else
2313 if (strcmp(type, "actor_refresh") == 0) {
2314 const char *actor = xs_dict_get(q_item, "actor");
2315 double mtime = object_mtime(actor);
2316
2317 /* only refresh if it was refreshed more than an hour ago */
2318 if (mtime + 3600.0 < (double) time(NULL)) {
2319 xs *actor_o = NULL;
2320 int status;
2321
2322 if (valid_status((status = activitypub_request(snac, actor, &actor_o))))
2323 actor_add(actor, actor_o);
2324 else
2325 object_touch(actor);
2326
2327 snac_log(snac, xs_fmt("actor_refresh %s %d", actor, status));
2328 }
2329 }
2330 else
2239 snac_log(snac, xs_fmt("unexpected user q_item type '%s'", type)); 2331 snac_log(snac, xs_fmt("unexpected user q_item type '%s'", type));
2240} 2332}
2241 2333