kopia lustrzana https://github.com/snarfed/bridgy-fed
rodzic
356903c3e9
commit
37c781a2df
40
atproto.py
40
atproto.py
|
@ -461,6 +461,10 @@ class ATProto(User, Protocol):
|
|||
Doesn't deliver anywhere externally! Relays will receive this record
|
||||
through ``subscribeRepos`` and then deliver it to AppView(s), which will
|
||||
notify recipients as necessary.
|
||||
|
||||
Exceptions:
|
||||
* ``flag``s are translated to ``createReport`` to the mod service
|
||||
* DMs are translated to ``sendMessage`` to the chat service
|
||||
"""
|
||||
if util.domain_from_link(url) not in DOMAINS:
|
||||
logger.info(f'Target PDS {url} is not us')
|
||||
|
@ -527,6 +531,7 @@ class ATProto(User, Protocol):
|
|||
# * delete actor => tombstone repo
|
||||
# * flag => send report to mod service
|
||||
# * stop-following => delete follow record (prepared above)
|
||||
# * dm => chat message
|
||||
verb = obj.as1.get('verb')
|
||||
if verb == 'delete':
|
||||
atp_base_id = (base_id if ATProto.owns_id(base_id)
|
||||
|
@ -537,7 +542,11 @@ class ATProto(User, Protocol):
|
|||
arroba.server.storage.tombstone_repo(repo)
|
||||
return True
|
||||
|
||||
elif verb == 'flag':
|
||||
if not record:
|
||||
# _convert already logged
|
||||
return False
|
||||
|
||||
if verb == 'flag':
|
||||
logger.info(f'flag => createReport with {record}')
|
||||
return to_cls.create_report(record, from_user=user)
|
||||
|
||||
|
@ -546,11 +555,13 @@ class ATProto(User, Protocol):
|
|||
assert base_obj and base_obj.type == 'follow', base_obj
|
||||
verb = 'delete'
|
||||
|
||||
# write commit
|
||||
if not record:
|
||||
# _convert already logged
|
||||
return False
|
||||
elif as1.is_dm(obj.as1):
|
||||
# is_dm checked that `to` has one elem
|
||||
to_id = as1.get_ids(base_obj_as1, 'to')[0]
|
||||
assert to_id.startswith('did:'), to_id
|
||||
return ATProto.send_chat(record, from_repo=repo, to_did=to_id)
|
||||
|
||||
# write commit
|
||||
type = record['$type']
|
||||
lex_type = LEXICONS[type]['type']
|
||||
assert lex_type == 'record', f"Can't store {type} object of type {lex_type}"
|
||||
|
@ -835,12 +846,14 @@ class ATProto(User, Protocol):
|
|||
logger.info(f'Created report on {mod_host}: {json_dumps(output)}')
|
||||
return True
|
||||
|
||||
def send_chat(self, msg, from_user):
|
||||
@classmethod
|
||||
def send_chat(cls, msg, from_repo, to_did):
|
||||
"""Sends a chat message to this user.
|
||||
|
||||
Args:
|
||||
msg (dict): ``chat.bsky.convo.defs#messageInput``
|
||||
from_user (models.User)
|
||||
from_repo (arroba.repo.Repo)
|
||||
to_did (str)
|
||||
|
||||
Returns:
|
||||
bool: True if the report was sent successfully, False if the flag's
|
||||
|
@ -848,18 +861,11 @@ class ATProto(User, Protocol):
|
|||
"""
|
||||
assert msg['$type'] == 'chat.bsky.convo.defs#messageInput'
|
||||
|
||||
to_did = self.key.id()
|
||||
from_did = from_user.get_copy(ATProto)
|
||||
if not from_did or not from_user.is_enabled(ATProto):
|
||||
return False
|
||||
|
||||
repo = arroba.server.storage.load_repo(from_did)
|
||||
|
||||
chat_host = os.environ['CHAT_HOST']
|
||||
token = service_jwt(host=chat_host,
|
||||
aud=os.environ['CHAT_DID'],
|
||||
repo_did=from_did,
|
||||
privkey=repo.signing_key)
|
||||
repo_did=from_repo.did,
|
||||
privkey=from_repo.signing_key)
|
||||
client = Client(f'https://{chat_host}', truncate=True, headers={
|
||||
'User-Agent': USER_AGENT,
|
||||
'Authorization': f'Bearer {token}',
|
||||
|
@ -876,5 +882,5 @@ class ATProto(User, Protocol):
|
|||
util.interpret_http_exception(e)
|
||||
return False
|
||||
|
||||
logger.info(f'Sent chat message from {from_user.handle} to {self.handle} {to_did}: {json_dumps(sent)}')
|
||||
logger.info(f'Sent chat message from {from_repo.handle} to {to_did}: {json_dumps(sent)}')
|
||||
return True
|
||||
|
|
|
@ -1741,8 +1741,7 @@ Sed tortor neque, aliquet quis posuere aliquam […]
|
|||
'Authorization': ANY,
|
||||
})
|
||||
|
||||
# sendMessage
|
||||
@patch('requests.post', return_value=requests_response({
|
||||
@patch('requests.post', return_value=requests_response({ # sendMessage
|
||||
'id': 'chat456',
|
||||
'rev': '22222222tef2d',
|
||||
'sender': {'did': 'did:plc:user'},
|
||||
|
@ -1764,18 +1763,25 @@ Sed tortor neque, aliquet quis posuere aliquam […]
|
|||
}),
|
||||
requests_response(DID_DOC),
|
||||
])
|
||||
def test_send_chat(self, mock_get, mock_post):
|
||||
def test_send_dm_chat(self, mock_get, mock_post):
|
||||
user = self.make_user_and_repo()
|
||||
alice = ATProto(id='did:plc:alice')
|
||||
|
||||
self.assertTrue(alice.send_chat({
|
||||
'$type': 'chat.bsky.convo.defs#messageInput',
|
||||
'text': 'hello world',
|
||||
}, from_user=user))
|
||||
dm = Object(id='fake:dm', source_protocol='fake', our_as1={
|
||||
'objectType': 'note',
|
||||
'actor': user.key.id(),
|
||||
'content': 'hello world',
|
||||
'to': ['did:plc:alice'],
|
||||
})
|
||||
self.assertTrue(ATProto.send(dm, 'https://bsky.brid.gy/'))
|
||||
|
||||
headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': common.USER_AGENT,
|
||||
'Authorization': ANY,
|
||||
}
|
||||
mock_get.assert_any_call(
|
||||
'https://chat.service.local/xrpc/chat.bsky.convo.getConvoForMembers?members=did%3Aplc%3Aalice',
|
||||
json=None, data=None, headers=ANY)
|
||||
json=None, data=None, headers=headers)
|
||||
mock_post.assert_called_with(
|
||||
'https://chat.service.local/xrpc/chat.bsky.convo.sendMessage',
|
||||
json={
|
||||
|
@ -1783,12 +1789,12 @@ Sed tortor neque, aliquet quis posuere aliquam […]
|
|||
'message': {
|
||||
'$type': 'chat.bsky.convo.defs#messageInput',
|
||||
'text': 'hello world',
|
||||
# unused
|
||||
'createdAt': '2022-01-02T03:04:05.000Z',
|
||||
'bridgyOriginalText': 'hello world',
|
||||
'bridgyOriginalUrl': 'fake:dm',
|
||||
},
|
||||
}, data=None, headers={
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': common.USER_AGENT,
|
||||
'Authorization': ANY,
|
||||
})
|
||||
}, data=None, headers=headers)
|
||||
|
||||
# getConvoForMembers
|
||||
@patch('requests.get', return_value=requests_response({
|
||||
|
@ -1797,12 +1803,14 @@ Sed tortor neque, aliquet quis posuere aliquam […]
|
|||
}, status=400))
|
||||
def test_send_chat_recipient_disabled(self, mock_get):
|
||||
user = self.make_user_and_repo()
|
||||
alice = ATProto(id='did:plc:alice')
|
||||
|
||||
self.assertFalse(alice.send_chat({
|
||||
'$type': 'chat.bsky.convo.defs#messageInput',
|
||||
'text': 'hello world',
|
||||
}, from_user=user))
|
||||
dm = Object(id='fake:dm', source_protocol='fake', our_as1={
|
||||
'objectType': 'note',
|
||||
'actor': user.key.id(),
|
||||
'content': 'hello world',
|
||||
'to': ['did:plc:alice'],
|
||||
})
|
||||
self.assertFalse(ATProto.send(dm, 'https://bsky.brid.gy/'))
|
||||
|
||||
mock_get.assert_any_call(
|
||||
'https://chat.service.local/xrpc/chat.bsky.convo.getConvoForMembers?members=did%3Aplc%3Aalice',
|
||||
|
|
Ładowanie…
Reference in New Issue