init
This commit is contained in:
245
src/s2s.py
Normal file
245
src/s2s.py
Normal file
@@ -0,0 +1,245 @@
|
||||
from flask import Flask, jsonify, Response, request, send_file, abort, Blueprint
|
||||
from globals import vona_version, make_event_id, hash_event
|
||||
from config import *
|
||||
import requests
|
||||
import json
|
||||
import os
|
||||
|
||||
server = Blueprint('matrix_server', __name__)
|
||||
|
||||
def send_join(request, roomId):
|
||||
# We may have to include signatures here
|
||||
# as well, which will be a pain
|
||||
|
||||
eventIds = [
|
||||
f"${make_event_id()}:{server_name}",
|
||||
f"${make_event_id()}:{server_name}",
|
||||
f"${make_event_id()}:{server_name}",
|
||||
f"${make_event_id()}:{server_name}"
|
||||
]
|
||||
|
||||
events = {
|
||||
"auth_chain": [eventIds[2], eventIds[3]],
|
||||
"event": {},
|
||||
"members_omitted": True,
|
||||
"servers_in_room": [server_name],
|
||||
"state": [
|
||||
{
|
||||
"content": {
|
||||
"room_version": the_funny_number,
|
||||
"creator": f"@vona:{server_name}"
|
||||
},
|
||||
"room_id": roomId,
|
||||
"event_id": eventIds[0],
|
||||
"state_key": "",
|
||||
"origin_server_ts": 1,
|
||||
"type": "m.room.create",
|
||||
"sender": f"@vona:{server_name}"
|
||||
},
|
||||
{
|
||||
"content": {"membership": "join"},
|
||||
"room_id": roomId,
|
||||
"event_id": eventIds[1],
|
||||
"state_key": f"@vona:{server_name}",
|
||||
"origin_server_ts": 2,
|
||||
"type": "m.room.member",
|
||||
"sender": f"@vona:{server_name}"
|
||||
},
|
||||
{
|
||||
"content": {"users": {f"@vona:{server_name}": 100}},
|
||||
"room_id": roomId,
|
||||
"event_id": eventIds[2],
|
||||
"state_key": "",
|
||||
"origin_server_ts": 3,
|
||||
"type": "m.room.power_levels",
|
||||
"sender": f"@vona:{server_name}"
|
||||
},
|
||||
{
|
||||
"content": {"join_rule": "public"},
|
||||
"room_id": roomId,
|
||||
"event_id": eventIds[3],
|
||||
"state_key": "",
|
||||
"origin_server_ts": 4,
|
||||
"type": "m.room.join_rules",
|
||||
"sender": f"@vona:{server_name}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
for event in events['state']:
|
||||
event_hash = hash_event(event)
|
||||
if event['type'] != "m.room.create":
|
||||
event['prev_events'] = [eventIds[event['origin_server_ts'] - 1], {"sha256": event_hash}]
|
||||
|
||||
join_event = request.json
|
||||
join_event['prev_events'] = [eventIds[3], {"sha256": events['state'][3]['prev_events'][1]['sha256']}]
|
||||
events['event'] = join_event
|
||||
|
||||
print(json.dumps(events, indent='\t'))
|
||||
print(json.dumps(eventIds, indent='\t'))
|
||||
|
||||
return events
|
||||
|
||||
@server.route('/_matrix/federation/v1/version')
|
||||
def version():
|
||||
return jsonify({"server": {"version": vona_version,"name": "Vona"}})
|
||||
|
||||
@server.route('/_matrix/key/v2/server')
|
||||
def keys():
|
||||
# todo
|
||||
return jsonify({})
|
||||
|
||||
@server.route('/_matrix/federation/v1/query/directory')
|
||||
def room_query():
|
||||
return jsonify({
|
||||
"room_id": room_dir_room['chunk'][0]['room_id'],
|
||||
"servers": [server_name]
|
||||
})
|
||||
|
||||
@server.route('/_matrix/federation/v1/media/download/<media_id>')
|
||||
def download_media(media_id):
|
||||
# Auth media requires this to be
|
||||
# multipart despite not even using
|
||||
# it for anything. Minor annoyance.
|
||||
|
||||
with open(cat, 'rb') as img_file:
|
||||
image_data = img_file.read()
|
||||
boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW'
|
||||
response_body = (
|
||||
f'--{boundary}\r\n'
|
||||
f'Content-Type: application/json\r\n\r\n'
|
||||
f'{{}}\r\n'
|
||||
f'--{boundary}\r\n'
|
||||
f'Content-Type: image/jpeg\r\n'
|
||||
f'Content-Disposition: attachment; filename="cat.jpg"\r\n\r\n'
|
||||
).encode() + image_data + f'\r\n--{boundary}--\r\n'.encode()
|
||||
|
||||
response = Response(response_body, content_type=f'multipart/mixed; boundary={boundary}')
|
||||
response.status_code = 200
|
||||
return response
|
||||
|
||||
@server.route('/_matrix/federation/v1/media/thumbnail/<media_id>')
|
||||
def thumbnail_media(media_id):
|
||||
return jsonify({"errcode": "M_TOO_CUTE","error": "Cat is too cute to thumbnail"}), 403
|
||||
|
||||
@server.route('/_matrix/federation/v1/send_join/<roomId>/<eventId>', methods=['PUT'])
|
||||
def send_join_v1(roomId, eventId):
|
||||
return jsonify(send_join(request, roomId))
|
||||
|
||||
@server.route('/_matrix/federation/v2/send_join/<roomId>/<eventId>', methods=['PUT'])
|
||||
def send_join_v2(roomId, eventId):
|
||||
return jsonify(send_join(request, roomId))
|
||||
|
||||
@server.route('/_matrix/federation/v1/make_join/<roomId>/<userId>')
|
||||
def make_join(roomId, userId):
|
||||
return jsonify({
|
||||
"event": {
|
||||
"content": {
|
||||
"join_authorised_via_users_server": f"@vona:{server_name}",
|
||||
"membership": "join"
|
||||
},
|
||||
"origin": server_name,
|
||||
"origin_server_ts": str(the_funny_number),
|
||||
"room_id": roomId,
|
||||
"sender": userId,
|
||||
"state_key": userId,
|
||||
"type": "m.room.member"
|
||||
},
|
||||
"room_version": "2"
|
||||
})
|
||||
|
||||
@server.route('/_matrix/federation/v1/publicRooms', methods=['POST', 'GET'])
|
||||
def room_directory():
|
||||
return jsonify(room_dir_room)
|
||||
|
||||
|
||||
# https://spec.matrix.org/v1.15/server-server-api/#transactions
|
||||
@server.route('/_matrix/federation/v1/send/<txnId>', methods=['PUT'])
|
||||
def federation_send(txnId):
|
||||
# This only works for v2 rooms, but anything
|
||||
# bigger than v2 isn't real, so not a problem
|
||||
|
||||
data = request.data.decode('utf-8')
|
||||
parsed_data = json.loads(data)
|
||||
response = {"pdus": {}}
|
||||
|
||||
if 'pdus' in parsed_data and parsed_data['pdus']:
|
||||
for pdu in parsed_data['pdus']:
|
||||
if 'hashes' in pdu and 'sha256' in pdu['hashes']:
|
||||
pdu_hash = pdu['hashes']['sha256']
|
||||
response_key = f"${pdu_hash}:{parsed_data['origin']}"
|
||||
response["pdus"][response_key] = {}
|
||||
|
||||
return jsonify(response)
|
||||
|
||||
@server.route('/_matrix/federation/v1/query/profile')
|
||||
def user_profile():
|
||||
field = request.args.get('field')
|
||||
if field:
|
||||
if field == 'avatar_url':
|
||||
return jsonify({"avatar_url":f"mxc://{server_name}/cat"})
|
||||
elif field == 'displayname':
|
||||
return jsonify({"displayname":"Vona"})
|
||||
else:
|
||||
return jsonify({"errcode": "M_NOT_FOUND","error": "The requested profile key does not exist."}), 404
|
||||
return jsonify({"avatar_url": f"mxc://{server_name}/cat","displayname": "Vona"})
|
||||
|
||||
@server.route('/_matrix/federation/v1/user/devices/<user>')
|
||||
def user_devices(user):
|
||||
return jsonify({
|
||||
"devices": [],
|
||||
"stream_id": the_funny_number,
|
||||
"user_id": f"@vona:{server_name}"
|
||||
})
|
||||
|
||||
@server.route('/_matrix/federation/v1/user/keys/query', methods=['POST'])
|
||||
def user_keys():
|
||||
return jsonify({"device_keys":{f"@vona:{server_name}":{}}})
|
||||
|
||||
@server.route('/_matrix/federation/v2/invite/<room>/<txnId>', methods=['PUT'])
|
||||
def fed_invite_user(room, txnId):
|
||||
return jsonify({"errcode":"M_INCOMPATIBLE_ROOM_VERSION","error": "Don't touch my users mofo","room_version": str(the_funny_number)}), 400
|
||||
|
||||
@server.route('/_matrix/federation/v1/hierarchy/<roomId>')
|
||||
def space_hierachy(roomId):
|
||||
room = room_dir_room['chunk'][0]
|
||||
return jsonify({
|
||||
"children": [{
|
||||
"avatar_url": room['avatar_url'],
|
||||
"children_state": [{
|
||||
"content": {"via": [server_name]},
|
||||
"origin_server_ts": the_funny_number,
|
||||
"sender": f"@vona:{server_name}",
|
||||
"state_key": room['room_id'],
|
||||
"type": "m.space.child"
|
||||
}],
|
||||
"guest_can_join": room['guest_can_join'],
|
||||
"join_rule": room['join_rule'],
|
||||
"name": room['name'],
|
||||
"num_joined_members": room['num_joined_members'],
|
||||
"room_id": room['room_id'],
|
||||
"room_type": room['room_type'],
|
||||
"topic": room['topic'],
|
||||
"world_readable": room['world_readable']
|
||||
}],
|
||||
"inaccessible_children": [],
|
||||
"room": {
|
||||
"allowed_room_ids": [],
|
||||
"avatar_url": room['avatar_url'],
|
||||
"children_state": [{
|
||||
"content": {"via": [server_name]},
|
||||
"origin_server_ts": the_funny_number,
|
||||
"sender": f"@vona:{server_name}",
|
||||
"state_key": room['room_id'],
|
||||
"type": "m.space.child"
|
||||
}],
|
||||
"guest_can_join": room['guest_can_join'],
|
||||
"join_rule": room['join_rule'],
|
||||
"name": room['name'],
|
||||
"num_joined_members": room['num_joined_members'],
|
||||
"room_id": room['room_id'],
|
||||
"room_type": room['room_type'],
|
||||
"topic": room['topic'],
|
||||
"world_readable": room['world_readable']
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user