Fixed #616: Do followers-only properly
This commit is contained in:
parent
1dd076ff7d
commit
759d5ac052
|
@ -623,6 +623,7 @@ class Post(StatorModel):
|
|||
"""
|
||||
Returns the AP JSON for this object
|
||||
"""
|
||||
self.author.ensure_uris()
|
||||
value = {
|
||||
"to": [],
|
||||
"cc": [],
|
||||
|
@ -655,11 +656,14 @@ class Post(StatorModel):
|
|||
if self.edited:
|
||||
value["updated"] = format_ld_date(self.edited)
|
||||
# Targeting
|
||||
# TODO: Add followers object
|
||||
if self.visibility == self.Visibilities.public:
|
||||
value["to"].append("as:Public")
|
||||
elif self.visibility == self.Visibilities.unlisted:
|
||||
value["cc"].append("as:Public")
|
||||
elif (
|
||||
self.visibility == self.Visibilities.followers and self.author.followers_uri
|
||||
):
|
||||
value["to"].append(self.author.followers_uri)
|
||||
# Mentions
|
||||
for mention in self.mentions.all():
|
||||
value["tag"].append(mention.to_ap_tag())
|
||||
|
@ -922,6 +926,8 @@ class Post(StatorModel):
|
|||
post.visibility = Post.Visibilities.public
|
||||
elif "public" in cc or "as:public" in cc:
|
||||
post.visibility = Post.Visibilities.unlisted
|
||||
elif post.author.followers_uri in to:
|
||||
post.visibility = Post.Visibilities.followers
|
||||
# Attachments
|
||||
# These have no IDs, so we have to wipe them each time
|
||||
post.attachments.all().delete()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
0.9
|
||||
===
|
||||
0.10
|
||||
====
|
||||
|
||||
*Released: Not Yet Released*
|
||||
|
||||
|
@ -15,6 +15,11 @@ This release's major changes:
|
|||
|
||||
* TBC
|
||||
|
||||
Minor changes also include:
|
||||
|
||||
* Followers-only mode now works correctly inbound and outbound (though outbound
|
||||
may need the other server to refresh the profile first).
|
||||
|
||||
If you'd like to help with code, design, or other areas, see
|
||||
:doc:`/contributing` to see how to get in touch.
|
||||
|
||||
|
|
|
@ -499,3 +499,45 @@ def test_post_hashtag_to_ap(identity: Identity, config_system):
|
|||
]
|
||||
assert "#world" in ap["object"]["content"]
|
||||
assert 'rel="tag"' in ap["object"]["content"]
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize(
|
||||
"visibility",
|
||||
[
|
||||
Post.Visibilities.public,
|
||||
Post.Visibilities.unlisted,
|
||||
Post.Visibilities.followers,
|
||||
Post.Visibilities.mentioned,
|
||||
],
|
||||
)
|
||||
def test_post_targets_to_ap(
|
||||
identity: Identity, other_identity: Identity, visibility: Post.Visibilities
|
||||
):
|
||||
"""
|
||||
Ensures that posts have the right targets in AP form.
|
||||
"""
|
||||
|
||||
# Make a post
|
||||
post = Post.objects.create(
|
||||
content="<p>Hello @other</p>",
|
||||
author=identity,
|
||||
local=True,
|
||||
visibility=visibility,
|
||||
)
|
||||
post.mentions.add(other_identity)
|
||||
|
||||
# Check its AP targets
|
||||
ap_dict = post.to_ap()
|
||||
if visibility == Post.Visibilities.public:
|
||||
assert ap_dict["to"] == ["as:Public"]
|
||||
assert ap_dict["cc"] == [other_identity.actor_uri]
|
||||
elif visibility == Post.Visibilities.unlisted:
|
||||
assert "to" not in ap_dict
|
||||
assert ap_dict["cc"] == ["as:Public", other_identity.actor_uri]
|
||||
elif visibility == Post.Visibilities.followers:
|
||||
assert ap_dict["to"] == [identity.followers_uri]
|
||||
assert ap_dict["cc"] == [other_identity.actor_uri]
|
||||
elif visibility == Post.Visibilities.mentioned:
|
||||
assert "to" not in ap_dict
|
||||
assert ap_dict["cc"] == [other_identity.actor_uri]
|
||||
|
|
|
@ -317,6 +317,19 @@ class Identity(StatorModel):
|
|||
for data in self.metadata
|
||||
]
|
||||
|
||||
def ensure_uris(self):
|
||||
"""
|
||||
Ensures that local identities have all the URIs populated on their fields
|
||||
(this lets us add new ones easily)
|
||||
"""
|
||||
if self.local:
|
||||
self.inbox_uri = self.actor_uri + "inbox/"
|
||||
self.outbox_uri = self.actor_uri + "outbox/"
|
||||
self.featured_collection_uri = self.actor_uri + "collections/featured/"
|
||||
self.followers_uri = self.actor_uri + "followers/"
|
||||
self.following_uri = self.actor_uri + "following/"
|
||||
self.shared_inbox_uri = f"https://{self.domain.uri_domain}/inbox/"
|
||||
|
||||
### Alternate constructors/fetchers ###
|
||||
|
||||
@classmethod
|
||||
|
@ -482,12 +495,15 @@ class Identity(StatorModel):
|
|||
def to_ap(self):
|
||||
from activities.models import Emoji
|
||||
|
||||
self.ensure_uris()
|
||||
response = {
|
||||
"id": self.actor_uri,
|
||||
"type": self.actor_type.title(),
|
||||
"inbox": self.actor_uri + "inbox/",
|
||||
"outbox": self.actor_uri + "outbox/",
|
||||
"featured": self.actor_uri + "collections/featured/",
|
||||
"inbox": self.inbox_uri,
|
||||
"outbox": self.outbox_uri,
|
||||
"featured": self.featured_collection_uri,
|
||||
"followers": self.followers_uri,
|
||||
"following": self.following_uri,
|
||||
"preferredUsername": self.username,
|
||||
"publicKey": {
|
||||
"id": self.public_key_id,
|
||||
|
@ -514,9 +530,9 @@ class Identity(StatorModel):
|
|||
"mediaType": media_type_from_filename(self.image.name),
|
||||
"url": self.image.url,
|
||||
}
|
||||
if self.local:
|
||||
if self.shared_inbox_uri:
|
||||
response["endpoints"] = {
|
||||
"sharedInbox": f"https://{self.domain.uri_domain}/inbox/",
|
||||
"sharedInbox": self.shared_inbox_uri,
|
||||
}
|
||||
if self.metadata:
|
||||
response["attachment"] = [
|
||||
|
|
Loading…
Reference in New Issue