kopia lustrzana https://github.com/snarfed/bridgy-fed
AP users: add User.name() and label_id(), ActivityPub.address computed property
for #512circle-datastore-transactions
rodzic
17ed24b6f5
commit
ca64793fff
|
@ -6,6 +6,7 @@ import logging
|
|||
from urllib.parse import quote_plus
|
||||
|
||||
from flask import abort, g, request
|
||||
from google.cloud import ndb
|
||||
from granary import as1, as2
|
||||
from httpsig import HeaderVerifier
|
||||
from httpsig.requests_auth import HTTPSignatureAuth
|
||||
|
@ -51,9 +52,19 @@ class ActivityPub(User, Protocol):
|
|||
"""ActivityPub protocol class.
|
||||
|
||||
Key id is AP/AS2 actor id URL. (*Not* fediverse/WebFinger @-@ handle!)
|
||||
|
||||
Includes extra `address` computed property for querying entities by handle.
|
||||
"""
|
||||
LABEL = 'activitypub'
|
||||
|
||||
@ndb.ComputedProperty
|
||||
def address(self):
|
||||
return self.ap_address()
|
||||
|
||||
def label_id(self):
|
||||
"""Returns this user's human-readable unique id, eg '@me@snarfed.org'."""
|
||||
return self.address or self.key.id()
|
||||
|
||||
def web_url(self):
|
||||
"""Returns this user's web URL aka web_url, eg 'https://foo.com/'."""
|
||||
return util.get_url(self.actor_as2) or self.ap_actor()
|
||||
|
|
23
models.py
23
models.py
|
@ -174,11 +174,26 @@ class User(StringIdModel, metaclass=ProtocolUserMeta):
|
|||
if self.actor_as2:
|
||||
return as2.to_as1(self.actor_as2)
|
||||
|
||||
def name(self):
|
||||
"""Returns this user's human-readable name, eg 'Ryan Barrett'."""
|
||||
if self.actor_as2:
|
||||
name = self.actor_as2.get('name')
|
||||
if name:
|
||||
return name
|
||||
|
||||
return self.label_id()
|
||||
|
||||
def label_id(self):
|
||||
"""Returns this user's human-readable unique id, eg '@me@snarfed.org'."""
|
||||
return self.key.id()
|
||||
|
||||
def username(self):
|
||||
"""Returns the user's preferred username.
|
||||
|
||||
Uses stored representative h-card if available, falls back to id.
|
||||
|
||||
TODO(#512): move to Web
|
||||
|
||||
Returns: str
|
||||
"""
|
||||
id = self.key.id()
|
||||
|
@ -255,7 +270,7 @@ class User(StringIdModel, metaclass=ProtocolUserMeta):
|
|||
|
||||
def user_page_path(self, rest=None):
|
||||
"""Returns the user's Bridgy Fed user page path."""
|
||||
path = f'/{self.LABEL}/{self.key.id()}'
|
||||
path = f'/{self.LABEL}/{self.label_id()}'
|
||||
if rest:
|
||||
path += f'/{rest}'
|
||||
return path
|
||||
|
@ -263,12 +278,8 @@ class User(StringIdModel, metaclass=ProtocolUserMeta):
|
|||
def user_page_link(self):
|
||||
"""Returns a pretty user page link with the user's name and profile picture."""
|
||||
actor = self.actor_as2 or {}
|
||||
name = (actor.get('name') or
|
||||
# prettify if domain, noop if username
|
||||
util.domain_from_link(self.username()))
|
||||
img = util.get_url(actor, 'icon') or ''
|
||||
|
||||
return f'<a class="h-card u-author" href="{self.user_page_path()}"><img src="{img}" class="profile"> {name}</a>'
|
||||
return f'<a class="h-card u-author" href="{self.user_page_path()}"><img src="{img}" class="profile"> {self.name()}</a>'
|
||||
|
||||
|
||||
class Target(ndb.Model):
|
||||
|
|
|
@ -1543,17 +1543,20 @@ class ActivityPubUtilsTest(TestCase):
|
|||
activitypub.postprocess_as2(activitypub.postprocess_as2(obj)),
|
||||
ignore=['to'])
|
||||
|
||||
def test_ap_actor(self):
|
||||
def test_ap_address(self):
|
||||
user = ActivityPub(actor_as2={**ACTOR, 'preferredUsername': 'me'})
|
||||
self.assertEqual('@me@mas.to', user.ap_address())
|
||||
self.assertEqual('@me@mas.to', user.address)
|
||||
|
||||
user = ActivityPub(actor_as2=ACTOR)
|
||||
self.assertEqual('@swentel@mas.to', user.ap_address())
|
||||
self.assertEqual('@swentel@mas.to', user.address)
|
||||
|
||||
user = ActivityPub(id='https://mas.to/users/alice')
|
||||
self.assertEqual('@alice@mas.to', user.ap_address())
|
||||
self.assertEqual('@alice@mas.to', user.address)
|
||||
|
||||
def test_ap_address(self):
|
||||
def test_ap_actor(self):
|
||||
user = self.make_user('http://foo/actor', cls=ActivityPub)
|
||||
self.assertEqual('http://foo/actor', user.ap_actor())
|
||||
|
||||
|
@ -1566,3 +1569,10 @@ class ActivityPubUtilsTest(TestCase):
|
|||
|
||||
user.actor_as2['url'] = ['http://my/url']
|
||||
self.assertEqual('http://my/url', user.web_url())
|
||||
|
||||
def test_label_id(self):
|
||||
user = self.make_user('http://foo', cls=ActivityPub)
|
||||
self.assertEqual('http://foo', user.label_id())
|
||||
|
||||
user.actor_as2 = ACTOR
|
||||
self.assertEqual('@swentel@mas.to', user.label_id())
|
||||
|
|
|
@ -230,7 +230,7 @@ class FollowTest(testutil.TestCase):
|
|||
def test_callback_user_use_instead(self, mock_get, mock_post):
|
||||
user = self.make_user('www.alice.com')
|
||||
self.user.use_instead = user.key
|
||||
user.put()
|
||||
self.user.put()
|
||||
|
||||
mock_get.side_effect = (
|
||||
requests_response(''),
|
||||
|
|
|
@ -94,6 +94,18 @@ class UserTest(TestCase):
|
|||
'https://user', '://y.z'):
|
||||
self.assertFalse(g.user.is_web_url(url), url)
|
||||
|
||||
def test_name(self):
|
||||
self.assertEqual('y.z', g.user.name())
|
||||
|
||||
g.user.actor_as2 = {'id': 'abc'}
|
||||
self.assertEqual('y.z', g.user.name())
|
||||
|
||||
g.user.actor_as2 = {'name': 'alice'}
|
||||
self.assertEqual('alice', g.user.name())
|
||||
|
||||
def test_label_id(self):
|
||||
self.assertEqual('y.z', g.user.label_id())
|
||||
|
||||
|
||||
class ObjectTest(TestCase):
|
||||
def setUp(self):
|
||||
|
|
|
@ -1501,6 +1501,9 @@ http://this/404s
|
|||
'preferredUsername': 'user.com',
|
||||
})
|
||||
|
||||
def test_label_id(self, _, __):
|
||||
self.assertEqual('user.com', self.user.label_id())
|
||||
|
||||
def test_web_url(self, _, __):
|
||||
self.assertEqual('https://user.com/', self.user.web_url())
|
||||
|
||||
|
|
4
web.py
4
web.py
|
@ -49,6 +49,10 @@ class Web(User, Protocol):
|
|||
def _get_kind(cls):
|
||||
return 'MagicKey'
|
||||
|
||||
def label_id(self):
|
||||
# prettify if domain, noop if username
|
||||
return util.domain_from_link(self.username(), minimize=False)
|
||||
|
||||
def web_url(self):
|
||||
"""Returns this user's web URL aka web_url, eg 'https://foo.com/'."""
|
||||
return f'https://{self.key.id()}/'
|
||||
|
|
Ładowanie…
Reference in New Issue