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
|
Returns the AP JSON for this object
|
||||||
"""
|
"""
|
||||||
|
self.author.ensure_uris()
|
||||||
value = {
|
value = {
|
||||||
"to": [],
|
"to": [],
|
||||||
"cc": [],
|
"cc": [],
|
||||||
|
@ -655,11 +656,14 @@ class Post(StatorModel):
|
||||||
if self.edited:
|
if self.edited:
|
||||||
value["updated"] = format_ld_date(self.edited)
|
value["updated"] = format_ld_date(self.edited)
|
||||||
# Targeting
|
# Targeting
|
||||||
# TODO: Add followers object
|
|
||||||
if self.visibility == self.Visibilities.public:
|
if self.visibility == self.Visibilities.public:
|
||||||
value["to"].append("as:Public")
|
value["to"].append("as:Public")
|
||||||
elif self.visibility == self.Visibilities.unlisted:
|
elif self.visibility == self.Visibilities.unlisted:
|
||||||
value["cc"].append("as:Public")
|
value["cc"].append("as:Public")
|
||||||
|
elif (
|
||||||
|
self.visibility == self.Visibilities.followers and self.author.followers_uri
|
||||||
|
):
|
||||||
|
value["to"].append(self.author.followers_uri)
|
||||||
# Mentions
|
# Mentions
|
||||||
for mention in self.mentions.all():
|
for mention in self.mentions.all():
|
||||||
value["tag"].append(mention.to_ap_tag())
|
value["tag"].append(mention.to_ap_tag())
|
||||||
|
@ -922,6 +926,8 @@ class Post(StatorModel):
|
||||||
post.visibility = Post.Visibilities.public
|
post.visibility = Post.Visibilities.public
|
||||||
elif "public" in cc or "as:public" in cc:
|
elif "public" in cc or "as:public" in cc:
|
||||||
post.visibility = Post.Visibilities.unlisted
|
post.visibility = Post.Visibilities.unlisted
|
||||||
|
elif post.author.followers_uri in to:
|
||||||
|
post.visibility = Post.Visibilities.followers
|
||||||
# Attachments
|
# Attachments
|
||||||
# These have no IDs, so we have to wipe them each time
|
# These have no IDs, so we have to wipe them each time
|
||||||
post.attachments.all().delete()
|
post.attachments.all().delete()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
0.9
|
0.10
|
||||||
===
|
====
|
||||||
|
|
||||||
*Released: Not Yet Released*
|
*Released: Not Yet Released*
|
||||||
|
|
||||||
|
@ -15,6 +15,11 @@ This release's major changes:
|
||||||
|
|
||||||
* TBC
|
* 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
|
If you'd like to help with code, design, or other areas, see
|
||||||
:doc:`/contributing` to see how to get in touch.
|
: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 "#world" in ap["object"]["content"]
|
||||||
assert 'rel="tag"' 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
|
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 ###
|
### Alternate constructors/fetchers ###
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -482,12 +495,15 @@ class Identity(StatorModel):
|
||||||
def to_ap(self):
|
def to_ap(self):
|
||||||
from activities.models import Emoji
|
from activities.models import Emoji
|
||||||
|
|
||||||
|
self.ensure_uris()
|
||||||
response = {
|
response = {
|
||||||
"id": self.actor_uri,
|
"id": self.actor_uri,
|
||||||
"type": self.actor_type.title(),
|
"type": self.actor_type.title(),
|
||||||
"inbox": self.actor_uri + "inbox/",
|
"inbox": self.inbox_uri,
|
||||||
"outbox": self.actor_uri + "outbox/",
|
"outbox": self.outbox_uri,
|
||||||
"featured": self.actor_uri + "collections/featured/",
|
"featured": self.featured_collection_uri,
|
||||||
|
"followers": self.followers_uri,
|
||||||
|
"following": self.following_uri,
|
||||||
"preferredUsername": self.username,
|
"preferredUsername": self.username,
|
||||||
"publicKey": {
|
"publicKey": {
|
||||||
"id": self.public_key_id,
|
"id": self.public_key_id,
|
||||||
|
@ -514,9 +530,9 @@ class Identity(StatorModel):
|
||||||
"mediaType": media_type_from_filename(self.image.name),
|
"mediaType": media_type_from_filename(self.image.name),
|
||||||
"url": self.image.url,
|
"url": self.image.url,
|
||||||
}
|
}
|
||||||
if self.local:
|
if self.shared_inbox_uri:
|
||||||
response["endpoints"] = {
|
response["endpoints"] = {
|
||||||
"sharedInbox": f"https://{self.domain.uri_domain}/inbox/",
|
"sharedInbox": self.shared_inbox_uri,
|
||||||
}
|
}
|
||||||
if self.metadata:
|
if self.metadata:
|
||||||
response["attachment"] = [
|
response["attachment"] = [
|
||||||
|
|
Loading…
Reference in New Issue