forked from forks/microblog.pub
parent
e265704e03
commit
95e411ac9b
6 changed files with 73 additions and 19 deletions
|
@ -31,6 +31,7 @@ from config import JWT
|
||||||
from config import MEDIA_CACHE
|
from config import MEDIA_CACHE
|
||||||
from config import _drop_db
|
from config import _drop_db
|
||||||
from core import feed
|
from core import feed
|
||||||
|
from core.activitypub import accept_follow
|
||||||
from core.activitypub import activity_url
|
from core.activitypub import activity_url
|
||||||
from core.activitypub import new_context
|
from core.activitypub import new_context
|
||||||
from core.activitypub import post_to_outbox
|
from core.activitypub import post_to_outbox
|
||||||
|
@ -353,6 +354,24 @@ def api_undo() -> _Response:
|
||||||
return _user_api_response(activity=undo_id)
|
return _user_api_response(activity=undo_id)
|
||||||
|
|
||||||
|
|
||||||
|
@blueprint.route("/accept_follow", methods=["POST"])
|
||||||
|
@api_required
|
||||||
|
def api_accept_follow() -> _Response:
|
||||||
|
oid = _user_api_arg("id")
|
||||||
|
doc = DB.activities.find_one({"box": Box.INBOX.value, "remote_id": oid})
|
||||||
|
print(doc)
|
||||||
|
if not doc:
|
||||||
|
raise ActivityNotFoundError(f"cannot found {oid}")
|
||||||
|
|
||||||
|
obj = ap.parse_activity(doc.get("activity"))
|
||||||
|
if not obj.has_type(ap.ActivityType.FOLLOW):
|
||||||
|
raise ValueError(f"{obj} is not a Follow activity")
|
||||||
|
|
||||||
|
accept_id = accept_follow(obj)
|
||||||
|
|
||||||
|
return _user_api_response(activity=accept_id)
|
||||||
|
|
||||||
|
|
||||||
@blueprint.route("/new_list", methods=["POST"])
|
@blueprint.route("/new_list", methods=["POST"])
|
||||||
@api_required
|
@api_required
|
||||||
def api_new_list() -> _Response:
|
def api_new_list() -> _Response:
|
||||||
|
|
|
@ -137,6 +137,8 @@ if PROFILE_METADATA:
|
||||||
{"type": "PropertyValue", "name": key, "value": linkify(value)}
|
{"type": "PropertyValue", "name": key, "value": linkify(value)}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
MANUALLY_APPROVES_FOLLOWERS = bool(conf.get("manually_approves_followers", False))
|
||||||
|
|
||||||
ME = {
|
ME = {
|
||||||
"@context": DEFAULT_CTX,
|
"@context": DEFAULT_CTX,
|
||||||
"type": "Person",
|
"type": "Person",
|
||||||
|
@ -151,7 +153,7 @@ ME = {
|
||||||
"summary": SUMMARY,
|
"summary": SUMMARY,
|
||||||
"endpoints": {},
|
"endpoints": {},
|
||||||
"url": ID,
|
"url": ID,
|
||||||
"manuallyApprovesFollowers": False,
|
"manuallyApprovesFollowers": MANUALLY_APPROVES_FOLLOWERS,
|
||||||
"attachment": attachments,
|
"attachment": attachments,
|
||||||
"icon": {
|
"icon": {
|
||||||
"mediaType": mimetypes.guess_type(ICON_URL)[0],
|
"mediaType": mimetypes.guess_type(ICON_URL)[0],
|
||||||
|
|
|
@ -825,3 +825,24 @@ def handle_replies(create: ap.Create) -> None:
|
||||||
|
|
||||||
# Spawn a task to process it (and determine if it needs to be saved)
|
# Spawn a task to process it (and determine if it needs to be saved)
|
||||||
Tasks.process_reply(create.get_object_id())
|
Tasks.process_reply(create.get_object_id())
|
||||||
|
|
||||||
|
|
||||||
|
def accept_follow(activity: ap.BaseActivity) -> str:
|
||||||
|
actor_id = activity.get_actor().id
|
||||||
|
accept = ap.Accept(
|
||||||
|
actor=ID,
|
||||||
|
context=new_context(activity),
|
||||||
|
object={
|
||||||
|
"type": "Follow",
|
||||||
|
"id": activity.id,
|
||||||
|
"object": activity.get_object_id(),
|
||||||
|
"actor": actor_id,
|
||||||
|
},
|
||||||
|
to=[actor_id],
|
||||||
|
published=now(),
|
||||||
|
)
|
||||||
|
update_one_activity(
|
||||||
|
by_remote_id(activity.id),
|
||||||
|
upsert({MetaKey.FOLLOW_STATUS: FollowStatus.ACCEPTED.value}),
|
||||||
|
)
|
||||||
|
return post_to_outbox(accept)
|
||||||
|
|
|
@ -8,9 +8,8 @@ from little_boxes.errors import NotAnActivityError
|
||||||
|
|
||||||
import config
|
import config
|
||||||
from core.activitypub import _answer_key
|
from core.activitypub import _answer_key
|
||||||
|
from core.activitypub import accept_follow
|
||||||
from core.activitypub import handle_replies
|
from core.activitypub import handle_replies
|
||||||
from core.activitypub import new_context
|
|
||||||
from core.activitypub import post_to_outbox
|
|
||||||
from core.activitypub import update_cached_actor
|
from core.activitypub import update_cached_actor
|
||||||
from core.db import DB
|
from core.db import DB
|
||||||
from core.db import update_one_activity
|
from core.db import update_one_activity
|
||||||
|
@ -23,7 +22,6 @@ from core.meta import in_inbox
|
||||||
from core.meta import inc
|
from core.meta import inc
|
||||||
from core.meta import upsert
|
from core.meta import upsert
|
||||||
from core.tasks import Tasks
|
from core.tasks import Tasks
|
||||||
from utils import now
|
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -179,21 +177,14 @@ def _like_process_inbox(like: ap.Like, new_meta: _NewMeta) -> None:
|
||||||
@process_inbox.register
|
@process_inbox.register
|
||||||
def _follow_process_inbox(activity: ap.Follow, new_meta: _NewMeta) -> None:
|
def _follow_process_inbox(activity: ap.Follow, new_meta: _NewMeta) -> None:
|
||||||
_logger.info(f"process_inbox activity={activity!r}")
|
_logger.info(f"process_inbox activity={activity!r}")
|
||||||
# Reply to a Follow with an Accept
|
# Reply to a Follow with an Accept if we're not manully approving them
|
||||||
actor_id = activity.get_actor().id
|
if not config.MANUALLY_APPROVES_FOLLOWERS:
|
||||||
accept = ap.Accept(
|
accept_follow(activity)
|
||||||
actor=config.ID,
|
else:
|
||||||
context=new_context(activity),
|
update_one_activity(
|
||||||
object={
|
by_remote_id(activity.id),
|
||||||
"type": "Follow",
|
upsert({MetaKey.FOLLOW_STATUS: FollowStatus.WAITING.value}),
|
||||||
"id": activity.id,
|
)
|
||||||
"object": activity.get_object_id(),
|
|
||||||
"actor": actor_id,
|
|
||||||
},
|
|
||||||
to=[actor_id],
|
|
||||||
published=now(),
|
|
||||||
)
|
|
||||||
post_to_outbox(accept)
|
|
||||||
|
|
||||||
|
|
||||||
def _update_follow_status(follow_id: str, status: FollowStatus) -> None:
|
def _update_follow_status(follow_id: str, status: FollowStatus) -> None:
|
||||||
|
|
|
@ -349,3 +349,15 @@ class _20190906_InReplyToMigration(Migration):
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.exception(f"failed to process activity {data!r}")
|
logger.exception(f"failed to process activity {data!r}")
|
||||||
|
|
||||||
|
|
||||||
|
class _20191020_ManuallyApprovesFollowerSupportMigrationn(Migration):
|
||||||
|
def migrate(self) -> None:
|
||||||
|
DB.activities.update_many(
|
||||||
|
{
|
||||||
|
**by_type(ap.ActivityType.FOLLOW),
|
||||||
|
**in_inbox(),
|
||||||
|
"meta.follow_status": {"$exists": False},
|
||||||
|
},
|
||||||
|
{"$set": {"meta.follow_status": "accepted"}},
|
||||||
|
)
|
||||||
|
|
|
@ -176,6 +176,15 @@
|
||||||
{% if item | has_type('Follow') %}
|
{% if item | has_type('Follow') %}
|
||||||
<div style="margin-left:70px;padding-bottom:5px;margin-bottom:15px;display:inline-block;">
|
<div style="margin-left:70px;padding-bottom:5px;margin-bottom:15px;display:inline-block;">
|
||||||
<span class="bar-item-no-hover">new follower</span>
|
<span class="bar-item-no-hover">new follower</span>
|
||||||
|
<span class="bar-item-no-hover">{{ item.meta.follow_status }}</span>
|
||||||
|
{% if config.MANUALLY_APPROVES_FOLLOWERS and item.meta.follow_status != "accepted" %}
|
||||||
|
<form action="/api/accept_follow" class="action-form" method="POST">
|
||||||
|
<input type="hidden" name="redirect" value="{{ request.path }}"/>
|
||||||
|
<input type="hidden" name="id" value="{{ item.remote_id }}"/>
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||||
|
<button type="submit" class="bar-item">approve follow request</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
{% if item.meta.notification_unread %}<span class="bar-item-no-bg"><span class="pcolor">new</span></span>{% endif %}
|
{% if item.meta.notification_unread %}<span class="bar-item-no-bg"><span class="pcolor">new</span></span>{% endif %}
|
||||||
<span class="bar-item-no-bg">{{ (item.activity.published or item.meta.published) | format_timeago }}</span>
|
<span class="bar-item-no-bg">{{ (item.activity.published or item.meta.published) | format_timeago }}</span>
|
||||||
<a class="bar-item" href="/admin/profile?actor_id={{item.meta.actor_id}}">profile</a>
|
<a class="bar-item" href="/admin/profile?actor_id={{item.meta.actor_id}}">profile</a>
|
||||||
|
|
Loading…
Reference in a new issue