Prepare for room v3+, misc bugfixes
This commit is contained in:
@@ -44,7 +44,7 @@ async def validate_json():
|
||||
|
||||
try:
|
||||
request.get_json(force=True)
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
return jsonify({"error": "Content not JSON.", "errcode": "M_NOT_JSON"}), 400
|
||||
|
||||
|
||||
|
||||
@@ -621,7 +621,7 @@ async def url_preview():
|
||||
@client.route("/_matrix/client/v1/media/preview_url")
|
||||
async def media_preview():
|
||||
response = send_file(config.cat)
|
||||
response.headers["Content-Disposition"] = f'inline; filename="cat.jpg"'
|
||||
response.headers["Content-Disposition"] = 'inline; filename="cat.jpg"'
|
||||
response.headers["Content-Type"] = "image/jpg"
|
||||
return response
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from vona.config import the_funny_number
|
||||
from datetime import datetime, timezone
|
||||
from vona.federation import send_join
|
||||
import vona.globals as globals
|
||||
@@ -7,7 +6,6 @@ import time
|
||||
|
||||
from flask import (
|
||||
Blueprint,
|
||||
request,
|
||||
jsonify,
|
||||
)
|
||||
|
||||
|
||||
@@ -2,15 +2,12 @@ from vona.federation import send_join
|
||||
import vona.globals as globals
|
||||
import vona.config as config
|
||||
|
||||
import base64
|
||||
import re
|
||||
import os
|
||||
|
||||
from flask import (
|
||||
Blueprint,
|
||||
jsonify,
|
||||
request,
|
||||
Response,
|
||||
)
|
||||
|
||||
synapse = Blueprint("synapse", __name__)
|
||||
@@ -99,7 +96,7 @@ async def whois(user_id):
|
||||
"": {
|
||||
"sessions": [{
|
||||
"connections": [{
|
||||
"ip":f"127.0.0.1",
|
||||
"ip":"127.0.0.1",
|
||||
"last_seen":config.the_funny_number,
|
||||
"user_agent":f"Vona/{globals.version}"
|
||||
}]
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import vona.federation.rooms as rooms
|
||||
import vona.globals as globals
|
||||
import vona.config as config
|
||||
|
||||
import threading
|
||||
import json
|
||||
import time
|
||||
import os
|
||||
|
||||
from flask import (
|
||||
jsonify,
|
||||
Response,
|
||||
request,
|
||||
send_file,
|
||||
Blueprint,
|
||||
)
|
||||
|
||||
@@ -23,210 +21,8 @@ class bullshit:
|
||||
return {}
|
||||
|
||||
def send_join(request, room) -> dict:
|
||||
event_chain = []
|
||||
event_hashes = []
|
||||
|
||||
event_ids = [
|
||||
globals.make_event_id(seed=f"1_{room}"),
|
||||
globals.make_event_id(seed=f"2_{room}"),
|
||||
globals.make_event_id(seed=f"3_{room}"),
|
||||
globals.make_event_id(seed=f"4_{room}"),
|
||||
globals.make_event_id(seed=f"5_{room}"),
|
||||
globals.make_event_id(seed=f"6_{room}"),
|
||||
]
|
||||
|
||||
create_event = {
|
||||
"content": {
|
||||
"m.federate": True,
|
||||
"creator": f"@vona:{config.server_name}",
|
||||
"room_version": globals.room_version_from_id(room)
|
||||
},
|
||||
"event_id": event_ids[0],
|
||||
"origin_server_ts": 1,
|
||||
"room_id": room,
|
||||
"sender": f"@vona:{config.server_name}",
|
||||
"state_key": "",
|
||||
"depth": 1,
|
||||
"type": "m.room.create",
|
||||
"auth_events": [],
|
||||
"prev_events": []
|
||||
}
|
||||
|
||||
screate_event = globals.hash_and_sign_event(create_event)
|
||||
event_chain.append(screate_event)
|
||||
|
||||
our_join = {
|
||||
"content": {
|
||||
"displayname": "Vona",
|
||||
"avatar_url": f"mxc://{config.server_name}/cat",
|
||||
"membership": "join"
|
||||
},
|
||||
"origin_server_ts": 2,
|
||||
"sender": f"@vona:{config.server_name}",
|
||||
"state_key": f"@vona:{config.server_name}",
|
||||
"type": "m.room.member",
|
||||
"event_id": event_ids[1],
|
||||
"room_id": room,
|
||||
"depth": 2,
|
||||
"auth_events": [[
|
||||
screate_event["event_id"],
|
||||
screate_event["hashes"]
|
||||
]],
|
||||
"prev_events": [[
|
||||
screate_event["event_id"],
|
||||
screate_event["hashes"]
|
||||
]]
|
||||
}
|
||||
|
||||
sour_join = globals.hash_and_sign_event(our_join)
|
||||
event_chain.append(sour_join)
|
||||
|
||||
pls = {
|
||||
"content": {
|
||||
"users": {
|
||||
f"@vona:{config.server_name}": "100"
|
||||
}
|
||||
},
|
||||
"origin_server_ts": 3,
|
||||
"room_id": room,
|
||||
"sender": f"@vona:{config.server_name}",
|
||||
"state_key": "",
|
||||
"type": "m.room.power_levels",
|
||||
"event_id": event_ids[2],
|
||||
"depth": 3,
|
||||
"user_id": f"@vona:{config.server_name}",
|
||||
"auth_events": [
|
||||
[
|
||||
screate_event["event_id"],
|
||||
screate_event["hashes"]
|
||||
],
|
||||
[
|
||||
sour_join["event_id"],
|
||||
sour_join["hashes"]
|
||||
]
|
||||
],
|
||||
"prev_events": [[
|
||||
sour_join["event_id"],
|
||||
sour_join["hashes"]
|
||||
]]
|
||||
}
|
||||
|
||||
spls = globals.hash_and_sign_event(pls)
|
||||
event_chain.append(spls)
|
||||
|
||||
join_rule = {
|
||||
"content": {
|
||||
"join_rule": "public"
|
||||
},
|
||||
"origin_server_ts": 4,
|
||||
"sender": f"@vona:{config.server_name}",
|
||||
"state_key": "",
|
||||
"type": "m.room.join_rules",
|
||||
"event_id": event_ids[3],
|
||||
"room_id": room,
|
||||
"depth": 4,
|
||||
"auth_events": [
|
||||
[
|
||||
screate_event["event_id"],
|
||||
screate_event["hashes"]
|
||||
],
|
||||
[
|
||||
sour_join["event_id"],
|
||||
sour_join["hashes"]
|
||||
],
|
||||
[
|
||||
spls["event_id"],
|
||||
spls["hashes"]
|
||||
]
|
||||
],
|
||||
"prev_events": [[
|
||||
spls["event_id"],
|
||||
spls["hashes"]
|
||||
]]
|
||||
}
|
||||
|
||||
sjoin_rule = globals.hash_and_sign_event(join_rule)
|
||||
event_chain.append(sjoin_rule)
|
||||
|
||||
guest_access = {
|
||||
"content": {
|
||||
"guest_access": "forbidden"
|
||||
},
|
||||
"origin_server_ts": 5,
|
||||
"depth": 5,
|
||||
"sender": f"@vona:{config.server_name}",
|
||||
"state_key": "",
|
||||
"type": "m.room.guest_access",
|
||||
"event_id": event_ids[4],
|
||||
"room_id": room,
|
||||
"auth_events": [
|
||||
[
|
||||
screate_event["event_id"],
|
||||
screate_event["hashes"]
|
||||
],
|
||||
[
|
||||
sour_join["event_id"],
|
||||
sour_join["hashes"]
|
||||
],
|
||||
[
|
||||
spls["event_id"],
|
||||
spls["hashes"]
|
||||
]
|
||||
],
|
||||
"prev_events": [[
|
||||
sjoin_rule["event_id"],
|
||||
sjoin_rule["hashes"]
|
||||
]]
|
||||
}
|
||||
|
||||
sguest_access = globals.hash_and_sign_event(guest_access)
|
||||
event_chain.append(sguest_access)
|
||||
|
||||
history = {
|
||||
"content": {
|
||||
"history_visibility": "shared"
|
||||
},
|
||||
"type": "m.room.history_visibility",
|
||||
"sender": f"@vona:{config.server_name}",
|
||||
"state_key": "",
|
||||
"origin_server_ts": 6,
|
||||
"depth": 6,
|
||||
"event_id": event_ids[5],
|
||||
"room_id": room,
|
||||
"auth_events": [
|
||||
[
|
||||
screate_event["event_id"],
|
||||
screate_event["hashes"]
|
||||
],
|
||||
[
|
||||
sour_join["event_id"],
|
||||
sour_join["hashes"]
|
||||
],
|
||||
[
|
||||
spls["event_id"],
|
||||
spls["hashes"]
|
||||
]
|
||||
],
|
||||
"prev_events": [[
|
||||
sguest_access["event_id"],
|
||||
sguest_access["hashes"]
|
||||
]]
|
||||
}
|
||||
|
||||
shistory = globals.hash_and_sign_event(history)
|
||||
event_chain.append(shistory)
|
||||
|
||||
remote_join = request.get_json()
|
||||
|
||||
response = {
|
||||
"auth_chain": event_chain,
|
||||
"event": remote_join,
|
||||
"members_omitted": False,
|
||||
"servers_in_room": [config.server_name],
|
||||
"state": event_chain
|
||||
}
|
||||
|
||||
return response
|
||||
if globals.room_version_from_id(room) in ["1", "2"]:
|
||||
return rooms.v1_v2(request, room)
|
||||
|
||||
|
||||
@server.route("/_matrix/federation/v1/version")
|
||||
@@ -288,27 +84,39 @@ async def thumbnail_media(media_id):
|
||||
"error": "Cat is too cute to thumbnail"
|
||||
}), 418
|
||||
|
||||
|
||||
@server.route("/_matrix/federation/v1/send_join/<room>/<eventId>", methods=["PUT"])
|
||||
async def send_join_v1(room, eventId):
|
||||
if globals.room_version_from_id(room) not in ["1", "2"]:
|
||||
return jsonify({
|
||||
"errcode": "M_INCOMPATIBLE_ROOM_VERSION",
|
||||
"error": "This room is not v1 or v2."
|
||||
}), 400
|
||||
|
||||
return jsonify([200, send_join(request, room)])
|
||||
|
||||
|
||||
@server.route("/_matrix/federation/v2/send_join/<room>/<eventId>", methods=["PUT"])
|
||||
async def send_join_v2(room, eventId):
|
||||
return jsonify(send_join(request, room))
|
||||
|
||||
|
||||
@server.route("/_matrix/federation/v1/make_join/<room>/<user>")
|
||||
async def make_join(room, user):
|
||||
def not_invited():
|
||||
if ":" in room:
|
||||
if room.split(":")[1] != config.server_name:
|
||||
return jsonify({
|
||||
"errcode": "M_FORBIDDEN",
|
||||
"error": "You are not invited to this room."
|
||||
}), 403
|
||||
else:
|
||||
return jsonify({
|
||||
"errcode": "M_FORBIDDEN",
|
||||
"error": "You are not invited to this room."
|
||||
}), 403
|
||||
|
||||
try:
|
||||
if room.split(":")[1] != config.server_name:
|
||||
return not_invited()
|
||||
except:
|
||||
return not_invited()
|
||||
|
||||
room_ver = globals.room_version_from_id(room)
|
||||
|
||||
state = send_join(
|
||||
request=bullshit,
|
||||
@@ -329,29 +137,43 @@ async def make_join(room, user):
|
||||
"depth": 7
|
||||
}
|
||||
|
||||
join["auth_events"] = [
|
||||
[
|
||||
state[0]["event_id"],
|
||||
state[0]["hashes"]
|
||||
],
|
||||
[
|
||||
state[2]["event_id"],
|
||||
state[2]["hashes"]
|
||||
],
|
||||
[
|
||||
state[3]["event_id"],
|
||||
state[3]["hashes"]
|
||||
]
|
||||
]
|
||||
if room_ver in ["1", "2"]:
|
||||
join["event_id"] = globals.make_event_id(seed=f"{user}+{room}")
|
||||
|
||||
join["auth_events"] = [
|
||||
[
|
||||
state[0]["event_id"],
|
||||
state[0]["hashes"]
|
||||
],
|
||||
[
|
||||
state[2]["event_id"],
|
||||
state[2]["hashes"]
|
||||
],
|
||||
[
|
||||
state[3]["event_id"],
|
||||
state[3]["hashes"]
|
||||
]
|
||||
]
|
||||
|
||||
join["prev_events"] = [[
|
||||
state[5]["event_id"],
|
||||
state[5]["hashes"]
|
||||
]]
|
||||
else:
|
||||
join["auth_events"] = [
|
||||
globals.make_ref_hash(state[0], int(room_ver)),
|
||||
globals.make_ref_hash(state[2], int(room_ver)),
|
||||
globals.make_ref_hash(state[3], int(room_ver)),
|
||||
]
|
||||
|
||||
join["prev_events"] = [
|
||||
globals.make_ref_hash(state[5], int(room_ver)),
|
||||
]
|
||||
|
||||
join["prev_events"] = [[
|
||||
state[5]["event_id"],
|
||||
state[5]["hashes"]
|
||||
]]
|
||||
|
||||
return jsonify({
|
||||
"event": globals.hash_and_sign_event(join),
|
||||
"room_version": globals.room_version_from_id(room)
|
||||
"room_version": room_ver
|
||||
})
|
||||
|
||||
|
||||
@@ -475,8 +297,7 @@ async def invite_user_v1(room, txnId):
|
||||
and ":" in event["event_id"]
|
||||
):
|
||||
return jsonify({
|
||||
"event": globals.sign_json_without_discard(event),
|
||||
"room_version": invite_data["room_version"]
|
||||
"event": globals.sign_json_without_discard(event)
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
@@ -550,7 +371,12 @@ async def state_ids(room):
|
||||
event_ids = []
|
||||
|
||||
for event in state:
|
||||
event_ids.append(event["event_id"])
|
||||
if "event_id" in event:
|
||||
event_ids.append(event["event_id"])
|
||||
else:
|
||||
event_ids.append(
|
||||
globals.make_ref_hash(event)
|
||||
)
|
||||
|
||||
if evt in event_ids:
|
||||
return jsonify({
|
||||
|
||||
213
vona/federation/rooms.py
Normal file
213
vona/federation/rooms.py
Normal file
@@ -0,0 +1,213 @@
|
||||
import vona.globals as globals
|
||||
import vona.config as config
|
||||
|
||||
# This file is responsible for creating Matrix rooms.
|
||||
|
||||
# Room V3+
|
||||
# TODO
|
||||
|
||||
# Room V1/V2
|
||||
def v1_v2(request, room) -> dict:
|
||||
event_chain = []
|
||||
|
||||
event_ids = [
|
||||
globals.make_event_id(seed=f"1_{room}"),
|
||||
globals.make_event_id(seed=f"2_{room}"),
|
||||
globals.make_event_id(seed=f"3_{room}"),
|
||||
globals.make_event_id(seed=f"4_{room}"),
|
||||
globals.make_event_id(seed=f"5_{room}"),
|
||||
globals.make_event_id(seed=f"6_{room}"),
|
||||
]
|
||||
|
||||
create_event = {
|
||||
"content": {
|
||||
"m.federate": True,
|
||||
"creator": f"@vona:{config.server_name}",
|
||||
"room_version": globals.room_version_from_id(room)
|
||||
},
|
||||
"event_id": event_ids[0],
|
||||
"origin_server_ts": 1,
|
||||
"room_id": room,
|
||||
"sender": f"@vona:{config.server_name}",
|
||||
"state_key": "",
|
||||
"depth": 1,
|
||||
"type": "m.room.create",
|
||||
"auth_events": [],
|
||||
"prev_events": []
|
||||
}
|
||||
|
||||
screate_event = globals.hash_and_sign_event(create_event)
|
||||
event_chain.append(screate_event)
|
||||
|
||||
our_join = {
|
||||
"content": {
|
||||
"displayname": "Vona",
|
||||
"avatar_url": f"mxc://{config.server_name}/cat",
|
||||
"membership": "join"
|
||||
},
|
||||
"origin_server_ts": 2,
|
||||
"sender": f"@vona:{config.server_name}",
|
||||
"state_key": f"@vona:{config.server_name}",
|
||||
"type": "m.room.member",
|
||||
"event_id": event_ids[1],
|
||||
"room_id": room,
|
||||
"depth": 2,
|
||||
"auth_events": [[
|
||||
screate_event["event_id"],
|
||||
screate_event["hashes"]
|
||||
]],
|
||||
"prev_events": [[
|
||||
screate_event["event_id"],
|
||||
screate_event["hashes"]
|
||||
]]
|
||||
}
|
||||
|
||||
sour_join = globals.hash_and_sign_event(our_join)
|
||||
event_chain.append(sour_join)
|
||||
|
||||
pls = {
|
||||
"content": {
|
||||
"users": {
|
||||
f"@vona:{config.server_name}": "100"
|
||||
}
|
||||
},
|
||||
"origin_server_ts": 3,
|
||||
"room_id": room,
|
||||
"sender": f"@vona:{config.server_name}",
|
||||
"state_key": "",
|
||||
"type": "m.room.power_levels",
|
||||
"event_id": event_ids[2],
|
||||
"depth": 3,
|
||||
"user_id": f"@vona:{config.server_name}",
|
||||
"auth_events": [
|
||||
[
|
||||
screate_event["event_id"],
|
||||
screate_event["hashes"]
|
||||
],
|
||||
[
|
||||
sour_join["event_id"],
|
||||
sour_join["hashes"]
|
||||
]
|
||||
],
|
||||
"prev_events": [[
|
||||
sour_join["event_id"],
|
||||
sour_join["hashes"]
|
||||
]]
|
||||
}
|
||||
|
||||
spls = globals.hash_and_sign_event(pls)
|
||||
event_chain.append(spls)
|
||||
|
||||
join_rule = {
|
||||
"content": {
|
||||
"join_rule": "public"
|
||||
},
|
||||
"origin_server_ts": 4,
|
||||
"sender": f"@vona:{config.server_name}",
|
||||
"state_key": "",
|
||||
"type": "m.room.join_rules",
|
||||
"event_id": event_ids[3],
|
||||
"room_id": room,
|
||||
"depth": 4,
|
||||
"auth_events": [
|
||||
[
|
||||
screate_event["event_id"],
|
||||
screate_event["hashes"]
|
||||
],
|
||||
[
|
||||
sour_join["event_id"],
|
||||
sour_join["hashes"]
|
||||
],
|
||||
[
|
||||
spls["event_id"],
|
||||
spls["hashes"]
|
||||
]
|
||||
],
|
||||
"prev_events": [[
|
||||
spls["event_id"],
|
||||
spls["hashes"]
|
||||
]]
|
||||
}
|
||||
|
||||
sjoin_rule = globals.hash_and_sign_event(join_rule)
|
||||
event_chain.append(sjoin_rule)
|
||||
|
||||
guest_access = {
|
||||
"content": {
|
||||
"guest_access": "forbidden"
|
||||
},
|
||||
"origin_server_ts": 5,
|
||||
"depth": 5,
|
||||
"sender": f"@vona:{config.server_name}",
|
||||
"state_key": "",
|
||||
"type": "m.room.guest_access",
|
||||
"event_id": event_ids[4],
|
||||
"room_id": room,
|
||||
"auth_events": [
|
||||
[
|
||||
screate_event["event_id"],
|
||||
screate_event["hashes"]
|
||||
],
|
||||
[
|
||||
sour_join["event_id"],
|
||||
sour_join["hashes"]
|
||||
],
|
||||
[
|
||||
spls["event_id"],
|
||||
spls["hashes"]
|
||||
]
|
||||
],
|
||||
"prev_events": [[
|
||||
sjoin_rule["event_id"],
|
||||
sjoin_rule["hashes"]
|
||||
]]
|
||||
}
|
||||
|
||||
sguest_access = globals.hash_and_sign_event(guest_access)
|
||||
event_chain.append(sguest_access)
|
||||
|
||||
history = {
|
||||
"content": {
|
||||
"history_visibility": "shared"
|
||||
},
|
||||
"type": "m.room.history_visibility",
|
||||
"sender": f"@vona:{config.server_name}",
|
||||
"state_key": "",
|
||||
"origin_server_ts": 6,
|
||||
"depth": 6,
|
||||
"event_id": event_ids[5],
|
||||
"room_id": room,
|
||||
"auth_events": [
|
||||
[
|
||||
screate_event["event_id"],
|
||||
screate_event["hashes"]
|
||||
],
|
||||
[
|
||||
sour_join["event_id"],
|
||||
sour_join["hashes"]
|
||||
],
|
||||
[
|
||||
spls["event_id"],
|
||||
spls["hashes"]
|
||||
]
|
||||
],
|
||||
"prev_events": [[
|
||||
sguest_access["event_id"],
|
||||
sguest_access["hashes"]
|
||||
]]
|
||||
}
|
||||
|
||||
shistory = globals.hash_and_sign_event(history)
|
||||
event_chain.append(shistory)
|
||||
|
||||
remote_join = request.get_json()
|
||||
|
||||
response = {
|
||||
"auth_chain": event_chain,
|
||||
"event": remote_join,
|
||||
"members_omitted": False,
|
||||
"servers_in_room": [config.server_name],
|
||||
"state": event_chain
|
||||
}
|
||||
|
||||
return response
|
||||
@@ -7,7 +7,6 @@ import hashlib
|
||||
import base64
|
||||
import random
|
||||
import httpx
|
||||
import copy
|
||||
import json
|
||||
import re
|
||||
|
||||
@@ -263,14 +262,15 @@ def make_ref_hash(
|
||||
|
||||
def room_version_from_id(room):
|
||||
room_id_no_sigil = room.replace("!", "")
|
||||
|
||||
hexadecimal_room_id = bytes(room_id_no_sigil, "utf-8").hex()
|
||||
|
||||
if "1" not in hexadecimal_room_id and "2" not in hexadecimal_room_id:
|
||||
hexadecimal_room_id = "1" + hexadecimal_room_id[1:]
|
||||
versions = [str(i) for i in range(1, 3)]
|
||||
|
||||
if not any(ver in hexadecimal_room_id for ver in versions):
|
||||
hexadecimal_room_id = "2" + hexadecimal_room_id[1:]
|
||||
|
||||
def remove_chars(s):
|
||||
return re.sub("[^12]", "", s)
|
||||
return re.sub(f"[^{''.join(versions)}]", "", s)
|
||||
|
||||
nums = remove_chars(hexadecimal_room_id)
|
||||
|
||||
@@ -278,9 +278,9 @@ def room_version_from_id(room):
|
||||
s = s.replace(" ", "").lower()
|
||||
counts = Counter(s)
|
||||
most_common = counts.most_common(1)
|
||||
return most_common[0] if most_common else None
|
||||
return most_common[0] if most_common else ("2",)
|
||||
|
||||
return most_common_character(nums)[0]
|
||||
return str(most_common_character(nums)[0])
|
||||
|
||||
|
||||
room_dir = {
|
||||
|
||||
@@ -133,11 +133,11 @@ async def invite():
|
||||
"public_keys": [
|
||||
{
|
||||
"key_validity_url": f"https://{server_name}/_matrix/identity/v2/pubkey/isvalid",
|
||||
"public_key":"ohyeah"
|
||||
"public_key": "ohyeah"
|
||||
},
|
||||
{
|
||||
"key_validity_url": f"https://{server_name}/_matrix/identity/v2/pubkey/ephemeral/isvalid",
|
||||
"public_key":"thisssssss"
|
||||
"public_key": "burgerkingfootlettuce"
|
||||
}
|
||||
],
|
||||
"token": "vona"
|
||||
@@ -148,10 +148,10 @@ async def invite():
|
||||
@identity.route("/_matrix/identity/v2/sign-ed25519", methods=["POST"])
|
||||
async def invite_signing():
|
||||
required_keys = {"mxid", "private_key", "token"}
|
||||
d = data.get_json()
|
||||
d = request.data.get_json()
|
||||
|
||||
if set(d.keys()) == required_keys:
|
||||
return jsonify(sign_json(d))
|
||||
return jsonify(globals.sign_json(d))
|
||||
else:
|
||||
return jsonify({
|
||||
"errcode": "M_UNRECOGNIZED",
|
||||
|
||||
Reference in New Issue
Block a user