diff options
| author | 2025-01-24 20:38:26 +0100 | |
|---|---|---|
| committer | 2025-01-24 20:38:26 +0100 | |
| commit | 85be7f36e12507cff7607df22ca14f8bfc00f6e2 (patch) | |
| tree | e41bedab3e3b011c16d2ea6180926470cc8586aa /activitypub.c | |
| parent | fix memory leak (diff) | |
| parent | Version 2.69 RELEASED. (diff) | |
| download | penes-snac2-85be7f36e12507cff7607df22ca14f8bfc00f6e2.tar.gz penes-snac2-85be7f36e12507cff7607df22ca14f8bfc00f6e2.tar.xz penes-snac2-85be7f36e12507cff7607df22ca14f8bfc00f6e2.zip | |
Merge remote-tracking branch 'upstream/master' into curl-smtp
Diffstat (limited to 'activitypub.c')
| -rw-r--r-- | activitypub.c | 131 |
1 files changed, 97 insertions, 34 deletions
diff --git a/activitypub.c b/activitypub.c index 2b10435..4cb779a 100644 --- a/activitypub.c +++ b/activitypub.c | |||
| @@ -587,6 +587,70 @@ int is_msg_from_private_user(const xs_dict *msg) | |||
| 587 | } | 587 | } |
| 588 | 588 | ||
| 589 | 589 | ||
| 590 | int followed_hashtag_check(snac *user, const xs_dict *msg) | ||
| 591 | /* returns true if this message contains a hashtag followed by me */ | ||
| 592 | { | ||
| 593 | const xs_list *fw_tags = xs_dict_get(user->config, "followed_hashtags"); | ||
| 594 | |||
| 595 | if (xs_is_list(fw_tags)) { | ||
| 596 | const xs_list *tags_in_msg = xs_dict_get(msg, "tag"); | ||
| 597 | |||
| 598 | if (xs_is_list(tags_in_msg)) { | ||
| 599 | const xs_dict *te; | ||
| 600 | |||
| 601 | /* iterate the tags in the message */ | ||
| 602 | xs_list_foreach(tags_in_msg, te) { | ||
| 603 | if (xs_is_dict(te)) { | ||
| 604 | const char *type = xs_dict_get(te, "type"); | ||
| 605 | const char *name = xs_dict_get(te, "name"); | ||
| 606 | |||
| 607 | if (xs_is_string(type) && xs_is_string(name)) { | ||
| 608 | if (strcmp(type, "Hashtag") == 0) { | ||
| 609 | xs *lc_name = xs_utf8_to_lower(name); | ||
| 610 | |||
| 611 | if (xs_list_in(fw_tags, lc_name) != -1) | ||
| 612 | return 1; | ||
| 613 | } | ||
| 614 | } | ||
| 615 | } | ||
| 616 | } | ||
| 617 | } | ||
| 618 | } | ||
| 619 | |||
| 620 | return 0; | ||
| 621 | } | ||
| 622 | |||
| 623 | |||
| 624 | void followed_hashtag_distribute(const xs_dict *msg) | ||
| 625 | /* distribute this post to all users following the included hashtags */ | ||
| 626 | { | ||
| 627 | const char *id = xs_dict_get(msg, "id"); | ||
| 628 | const xs_list *tags_in_msg = xs_dict_get(msg, "tag"); | ||
| 629 | |||
| 630 | if (!xs_is_string(id) || !xs_is_list(tags_in_msg) || xs_list_len(tags_in_msg) == 0) | ||
| 631 | return; | ||
| 632 | |||
| 633 | srv_debug(1, xs_fmt("followed_hashtag_distribute check for %s", id)); | ||
| 634 | |||
| 635 | xs *users = user_list(); | ||
| 636 | const char *uid; | ||
| 637 | |||
| 638 | xs_list_foreach(users, uid) { | ||
| 639 | snac user; | ||
| 640 | |||
| 641 | if (user_open(&user, uid)) { | ||
| 642 | if (followed_hashtag_check(&user, msg)) { | ||
| 643 | timeline_add(&user, id, msg); | ||
| 644 | |||
| 645 | snac_log(&user, xs_fmt("followed hashtag in %s", id)); | ||
| 646 | } | ||
| 647 | |||
| 648 | user_free(&user); | ||
| 649 | } | ||
| 650 | } | ||
| 651 | } | ||
| 652 | |||
| 653 | |||
| 590 | int is_msg_for_me(snac *snac, const xs_dict *c_msg) | 654 | int is_msg_for_me(snac *snac, const xs_dict *c_msg) |
| 591 | /* checks if this message is for me */ | 655 | /* checks if this message is for me */ |
| 592 | { | 656 | { |
| @@ -602,19 +666,32 @@ int is_msg_for_me(snac *snac, const xs_dict *c_msg) | |||
| 602 | if (xs_match(type, "Like|Announce|EmojiReact")) { | 666 | if (xs_match(type, "Like|Announce|EmojiReact")) { |
| 603 | const char *object = xs_dict_get(c_msg, "object"); | 667 | const char *object = xs_dict_get(c_msg, "object"); |
| 604 | 668 | ||
| 605 | if (xs_type(object) == XSTYPE_DICT) | 669 | if (xs_is_dict(object)) |
| 606 | object = xs_dict_get(object, "id"); | 670 | object = xs_dict_get(object, "id"); |
| 607 | 671 | ||
| 608 | /* bad object id? reject */ | 672 | /* bad object id? reject */ |
| 609 | if (xs_type(object) != XSTYPE_STRING) | 673 | if (!xs_is_string(object)) |
| 610 | return 0; | 674 | return 0; |
| 611 | 675 | ||
| 612 | /* if it's about one of our posts, accept it */ | 676 | /* if it's about one of our posts, accept it */ |
| 613 | if (xs_startswith(object, snac->actor)) | 677 | if (xs_startswith(object, snac->actor)) |
| 614 | return 2; | 678 | return 2; |
| 615 | 679 | ||
| 616 | /* if it's by someone we don't follow, reject */ | 680 | /* if it's by someone we follow, accept it */ |
| 617 | return following_check(snac, actor); | 681 | if (following_check(snac, actor)) |
| 682 | return 1; | ||
| 683 | |||
| 684 | /* do we follow any hashtag? */ | ||
| 685 | if (xs_is_list(xs_dict_get(snac->config, "followed_hashtags"))) { | ||
| 686 | xs *obj = NULL; | ||
| 687 | |||
| 688 | /* if the admired object contains any followed hashtag, accept it */ | ||
| 689 | if (valid_status(object_get(object, &obj)) && | ||
| 690 | followed_hashtag_check(snac, obj)) | ||
| 691 | return 7; | ||
| 692 | } | ||
| 693 | |||
| 694 | return 0; | ||
| 618 | } | 695 | } |
| 619 | 696 | ||
| 620 | /* if it's an Undo, it must be from someone related to us */ | 697 | /* if it's an Undo, it must be from someone related to us */ |
| @@ -708,30 +785,8 @@ int is_msg_for_me(snac *snac, const xs_dict *c_msg) | |||
| 708 | } | 785 | } |
| 709 | 786 | ||
| 710 | /* does this message contain a tag we are following? */ | 787 | /* does this message contain a tag we are following? */ |
| 711 | const xs_list *fw_tags = xs_dict_get(snac->config, "followed_hashtags"); | 788 | if (pub_msg && followed_hashtag_check(snac, msg)) |
| 712 | if (pub_msg && xs_type(fw_tags) == XSTYPE_LIST) { | 789 | return 7; |
| 713 | const xs_list *tags_in_msg = xs_dict_get(msg, "tag"); | ||
| 714 | if (xs_type(tags_in_msg) == XSTYPE_LIST) { | ||
| 715 | const xs_dict *te; | ||
| 716 | |||
| 717 | /* iterate the tags in the message */ | ||
| 718 | xs_list_foreach(tags_in_msg, te) { | ||
| 719 | if (xs_type(te) == XSTYPE_DICT) { | ||
| 720 | const char *type = xs_dict_get(te, "type"); | ||
| 721 | const char *name = xs_dict_get(te, "name"); | ||
| 722 | |||
| 723 | if (xs_type(type) == XSTYPE_STRING && xs_type(name) == XSTYPE_STRING) { | ||
| 724 | if (strcmp(type, "Hashtag") == 0) { | ||
| 725 | xs *lc_name = xs_utf8_to_lower(name); | ||
| 726 | |||
| 727 | if (xs_list_in(fw_tags, lc_name) != -1) | ||
| 728 | return 7; | ||
| 729 | } | ||
| 730 | } | ||
| 731 | } | ||
| 732 | } | ||
| 733 | } | ||
| 734 | } | ||
| 735 | 790 | ||
| 736 | return 0; | 791 | return 0; |
| 737 | } | 792 | } |
| @@ -2277,15 +2332,23 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req) | |||
| 2277 | xs *who_o = NULL; | 2332 | xs *who_o = NULL; |
| 2278 | 2333 | ||
| 2279 | if (valid_status(actor_request(snac, who, &who_o))) { | 2334 | if (valid_status(actor_request(snac, who, &who_o))) { |
| 2280 | if (timeline_admire(snac, object, actor, 0) == HTTP_STATUS_CREATED) | 2335 | /* don't account as such announces by our own relay */ |
| 2281 | snac_log(snac, xs_fmt("new 'Announce' %s %s", actor, object)); | 2336 | xs *this_relay = xs_fmt("%s/relay", srv_baseurl); |
| 2282 | else | 2337 | |
| 2283 | snac_log(snac, xs_fmt("repeated 'Announce' from %s to %s", | 2338 | if (strcmp(actor, this_relay) != 0) { |
| 2284 | actor, object)); | 2339 | if (timeline_admire(snac, object, actor, 0) == HTTP_STATUS_CREATED) |
| 2340 | snac_log(snac, xs_fmt("new 'Announce' %s %s", actor, object)); | ||
| 2341 | else | ||
| 2342 | snac_log(snac, xs_fmt("repeated 'Announce' from %s to %s", | ||
| 2343 | actor, object)); | ||
| 2344 | } | ||
| 2285 | 2345 | ||
| 2286 | /* distribute the post with the actor as 'proxy' */ | 2346 | /* distribute the post with the actor as 'proxy' */ |
| 2287 | list_distribute(snac, actor, a_msg); | 2347 | list_distribute(snac, actor, a_msg); |
| 2288 | 2348 | ||
| 2349 | /* distribute the post to users following these hashtags */ | ||
| 2350 | followed_hashtag_distribute(a_msg); | ||
| 2351 | |||
| 2289 | do_notify = 1; | 2352 | do_notify = 1; |
| 2290 | } | 2353 | } |
| 2291 | else | 2354 | else |
| @@ -2300,7 +2363,7 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req) | |||
| 2300 | } | 2363 | } |
| 2301 | else | 2364 | else |
| 2302 | if (strcmp(type, "Update") == 0) { /** **/ | 2365 | if (strcmp(type, "Update") == 0) { /** **/ |
| 2303 | if (xs_match(utype, "Person|Service")) { /** **/ | 2366 | if (xs_match(utype, "Person|Service|Application")) { /** **/ |
| 2304 | actor_add(actor, xs_dict_get(msg, "object")); | 2367 | actor_add(actor, xs_dict_get(msg, "object")); |
| 2305 | timeline_touch(snac); | 2368 | timeline_touch(snac); |
| 2306 | 2369 | ||