kopia lustrzana https://gitlab.com/jaywink/federation
Merge branch 'matrix/create-missing-profiles' into 'master'
Ensure missing profiles are created on Matrix side Closes #126 and #127 See merge request jaywink/federation!165merge-requests/166/merge
commit
a64107da85
|
@ -11,7 +11,7 @@ import requests
|
|||
from federation.entities.base import Post, Profile
|
||||
from federation.entities.matrix.enums import EventType
|
||||
from federation.entities.mixins import BaseEntity
|
||||
from federation.entities.utils import get_base_attributes
|
||||
from federation.entities.utils import get_base_attributes, get_profile
|
||||
from federation.utils.matrix import get_matrix_configuration, appservice_auth_header
|
||||
from federation.utils.network import fetch_document, fetch_file
|
||||
|
||||
|
@ -20,6 +20,7 @@ logger = logging.getLogger("federation")
|
|||
|
||||
class MatrixEntityMixin(BaseEntity):
|
||||
_event_type: str = None
|
||||
_payloads: List[Dict] = []
|
||||
_profile_room_id = None
|
||||
_txn_id: str = None
|
||||
|
||||
|
@ -59,11 +60,10 @@ class MatrixEntityMixin(BaseEntity):
|
|||
if status == 200:
|
||||
data = json.loads(doc)
|
||||
self._profile_room_id = data["room_id"]
|
||||
# TODO create?
|
||||
|
||||
# noinspection PyMethodMayBeStatic
|
||||
def payloads(self) -> List[Dict]:
|
||||
return []
|
||||
return self._payloads
|
||||
|
||||
@property
|
||||
def profile_room_alias(self):
|
||||
|
@ -73,6 +73,11 @@ class MatrixEntityMixin(BaseEntity):
|
|||
def profile_room_alias_url_safe(self):
|
||||
return f"{quote(self.profile_room_alias)}"
|
||||
|
||||
@property
|
||||
def server_name(self) -> str:
|
||||
config = get_matrix_configuration()
|
||||
return config['homeserver_name']
|
||||
|
||||
@property
|
||||
def txn_id(self) -> str:
|
||||
return self._txn_id
|
||||
|
@ -89,7 +94,7 @@ class MatrixRoomMessage(Post, MatrixEntityMixin):
|
|||
response = requests.post(
|
||||
url=f"{super().get_endpoint()}/createRoom?user_id={self.mxid}",
|
||||
json={
|
||||
# TODO auto-invite recipients if private chat
|
||||
# TODO auto-invite other recipients if private chat
|
||||
"preset": "public_chat" if self.public else "private_chat",
|
||||
"name": f"Thread by {self.mxid}",
|
||||
"topic": self.url,
|
||||
|
@ -113,6 +118,17 @@ class MatrixRoomMessage(Post, MatrixEntityMixin):
|
|||
response.raise_for_status()
|
||||
self._thread_room_event_id = response.json()["event_id"]
|
||||
|
||||
def get_profile_room_id(self):
|
||||
super().get_profile_room_id()
|
||||
if not self._profile_room_id:
|
||||
from federation.entities.matrix.mappers import get_outbound_entity
|
||||
# Need to also create the profile
|
||||
profile = get_profile(self.actor_id)
|
||||
profile_entity = get_outbound_entity(profile, None)
|
||||
payloads = profile_entity.payloads()
|
||||
if payloads:
|
||||
self._payloads.extend(payloads)
|
||||
|
||||
def payloads(self) -> List[Dict]:
|
||||
payloads = super().payloads()
|
||||
payloads.append({
|
||||
|
@ -130,6 +146,15 @@ class MatrixRoomMessage(Post, MatrixEntityMixin):
|
|||
},
|
||||
"method": "put",
|
||||
})
|
||||
# Tag the thread room as low priority
|
||||
payloads.append({
|
||||
"endpoint": f"{super().get_endpoint()}/user/{self.mxid}/rooms/{self._thread_room_id}/tags/m.lowpriority"
|
||||
f"?user_id={self.mxid}",
|
||||
"payload": {
|
||||
"order": 0,
|
||||
},
|
||||
"method": "put",
|
||||
})
|
||||
return payloads
|
||||
|
||||
def pre_send(self):
|
||||
|
@ -198,34 +223,43 @@ class MatrixProfile(Profile, MatrixEntityMixin):
|
|||
_remote_profile_create_needed = False
|
||||
_remote_room_create_needed = False
|
||||
|
||||
@property
|
||||
def localpart(self) -> str:
|
||||
config = get_matrix_configuration()
|
||||
return self.mxid.replace("@", "").replace(f":{config['homeserver_name']}", "")
|
||||
|
||||
def payloads(self) -> List[Dict]:
|
||||
payloads = super().payloads()
|
||||
if self._remote_profile_create_needed:
|
||||
payloads.append({
|
||||
"endpoint": f"{super().get_endpoint()}/register",
|
||||
"payload": {
|
||||
"username": f"{self.localpart}",
|
||||
"type": "m.login.application_service",
|
||||
},
|
||||
})
|
||||
if self._remote_room_create_needed:
|
||||
payloads.append({
|
||||
"endpoint": f"{super().get_endpoint()}/createRoom",
|
||||
"payload": {
|
||||
"invite": [
|
||||
self.mxid,
|
||||
],
|
||||
def create_profile_room(self):
|
||||
headers = appservice_auth_header()
|
||||
response = requests.post(
|
||||
url=f"{super().get_endpoint()}/createRoom?user_id={self.mxid}",
|
||||
json={
|
||||
"name": self.name,
|
||||
"preset": "public_chat" if self.public else "private_chat",
|
||||
"room_alias_name": f"@{self.localpart}",
|
||||
"topic": f"Profile room of {self.url}",
|
||||
},
|
||||
})
|
||||
headers=headers,
|
||||
)
|
||||
response.raise_for_status()
|
||||
self._profile_room_id = response.json()["room_id"]
|
||||
|
||||
def register_user(self):
|
||||
headers = appservice_auth_header()
|
||||
response = requests.post(
|
||||
url=f"{super().get_endpoint()}/register",
|
||||
json={
|
||||
"username": f"{self.localpart}",
|
||||
"type": "m.login.application_service",
|
||||
},
|
||||
headers=headers,
|
||||
)
|
||||
response.raise_for_status()
|
||||
|
||||
@property
|
||||
def localpart(self) -> str:
|
||||
return self.mxid.replace("@", "").replace(f":{self.server_name}", "")
|
||||
|
||||
def payloads(self) -> List[Dict]:
|
||||
payloads = super().payloads()
|
||||
if self._remote_profile_create_needed:
|
||||
self.register_user()
|
||||
if self._remote_room_create_needed:
|
||||
self.create_profile_room()
|
||||
payloads.append({
|
||||
"endpoint": f"{super().get_endpoint()}/profile/{self.mxid}/displayname?user_id={self.mxid}",
|
||||
"payload": {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import inspect
|
||||
from typing import Optional
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from federation.entities.base import Profile
|
||||
|
||||
|
||||
def get_base_attributes(entity):
|
||||
|
@ -36,3 +39,20 @@ def get_name_for_profile(fid: str) -> Optional[str]:
|
|||
return profile.name
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def get_profile(fid):
|
||||
# type: (str) -> Profile
|
||||
"""
|
||||
Get a profile via the configured profile getter.
|
||||
|
||||
Currently only works with Django configuration.
|
||||
"""
|
||||
try:
|
||||
from federation.utils.django import get_function_from_config
|
||||
profile_func = get_function_from_config("get_profile_function")
|
||||
if not profile_func:
|
||||
return
|
||||
return profile_func(fid=fid)
|
||||
except Exception:
|
||||
pass
|
||||
|
|
Ładowanie…
Reference in New Issue