Skip to content
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions backend/database/Federation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import sqlalchemy as sql
from web import sql_database as db
from sqlalchemy.orm import relationship
import util


class Federation(db.Model):
id = sql.Column(sql.Integer, primary_key=True)
name = sql.Column(sql.String(100), nullable=False)
domain = sql.Column(sql.String(200), nullable=False)
remote_password = sql.Column(sql.String(100), nullable=True)
remote_user_id = sql.Column(sql.Integer, nullable=True)
federation_user_id = sql.Column(sql.Integer, sql.ForeignKey(
'member.id', ondelete='CASCADE'), nullable=True)
federation_user = relationship(
'database.Member.Member', lazy="joined")
accepted = sql.Column(sql.Boolean, nullable=False, default=False)
initiator = sql.Column(sql.Boolean, nullable=False, default=False)

def to_dict(self):
return {
"id": self.id,
"name": self.name,
"domain": self.domain,
"remote_user_id": self.remote_user_id,
"federation_user_id": self.federation_user_id,
"accepted": self.accepted,
"initiator": self.initiator
}
1 change: 1 addition & 0 deletions backend/database/Models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
from database.KeyValue import KeyValue
from database.Reminder import Reminder
from database.Session import Session
from database.Federation import Federation
26 changes: 26 additions & 0 deletions backend/database/Queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,32 @@ def delete_transaction(self, transaction_id):
session.commit()
return True

def get_federations(self):
with self.get_session() as session:
federations = session.query(
Federation).order_by(desc(Federation.id)).all()
output = []
for f in federations:
federation: Federation = f
output.append(federation.to_dict())

return output

def add_federation(self, name, domain, user_id=None, remote_password=None, remote_user_id=None):
with self.get_session() as session:
if user_id is not None:
# local initiator
new_federation = Federation(name=name, domain=domain, federation_user_id=user_id, initiator=True)
session.add(new_federation)
session.commit()
return new_federation.to_dict()
elif remote_password is not None and remote_user_id is not None:
# remote initiator
new_federation = Federation(name=name, domain=domain, remote_password=remote_password, remote_user_id=remote_user_id, initiator=False)
session.add(new_federation)
session.commit()
return new_federation

def delete_user(self, member_id):
with self.get_session() as session:
session.delete(session.query(
Expand Down
67 changes: 66 additions & 1 deletion backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import flask
import mail
import secrets
import requests

api_bp = flask.Blueprint("api", __name__, url_prefix="/api/")
api = Api(api_bp, doc='/docu/', base_url='/api')
Expand Down Expand Up @@ -94,7 +95,6 @@
'amount': fields.Float(required=True)
})


@api.route('/users')
class GET_USERS(Resource):
@authenticated
Expand Down Expand Up @@ -962,6 +962,71 @@
"Logout", f"MemberID: {request.cookies.get(f'{util.auth_cookie_memberID}memberID')}")
return util.build_response("OK")

model_federation_local = api.model('Federation-Local', {
'domain': fields.String(required=True),
'name': fields.String(required=True),
})

model_federation_remote = api.model('Federation-Extern', {
'name': fields.String(required=True),
'domain': fields.String(required=True),
'password': fields.String(required=True),
'user_id': fields.Integer(required=True),
})

@api.route('/federations')
class get_federations(Resource):
def get(self):
"""
Get all federations
"""
return util.build_response(db.get_federations())

@api.route('/federation/local')
class add_federation_local(Resource):
@api.doc(body=model_federation_local)
def post(self):
"""
Create a federation request
"""

password = secrets.token_urlsafe(64)
member = db.add_user(request.json["name"], 0, password, alias=request.json["name"], hidden=True)
db.add_federation(request.json["name"], request.json["domain"], member["id"])

url = f"http://{request.json['domain']}/api/federation/remote"

payload = json.dumps({
"name": util.federation_name,
"domain": util.domain,
"password": password,
"user_id": member["id"]
})
headers = {
'Content-Type': 'application/json'
}

response = requests.request("POST", url, headers=headers, data=payload, timeout=5)
Comment thread Fixed
if (response.status_code != 200):
return util.build_response("Federation request failed")

responseJson = response.json()
if not ("status" in responseJson and responseJson["status"] == "ok"):
return util.build_response("Federation request failed")

return util.build_response("Federation request sent")

@api.route('/federation/remote')
class add_federation_remote(Resource):
@api.doc(body=model_federation_remote)
def post(self):
"""
Create a federation request
"""
db.add_federation(name=request.json["name"], domain=request.json["domain"], remote_password=request.json["password"], remote_user_id=request.json["user_id"])

return util.build_response({"status": "ok"})


if __name__ == "__main__":
if util.logging_enabled:
Expand Down
1 change: 1 addition & 0 deletions backend/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"DOMAIN") else "127.0.0.1:3000"
logging_enabled = os.environ.get(
"DEBUG") == "true" if os.environ.get("DEBUG") else False
federation_name = os.environ.get("FEDERATION") if os.environ.get("FEDERATION") else domain

token = os.environ.get("X_AUTH_TOKEN")
old_domain = os.environ.get("OLD_DOMAIN")
Expand Down
34 changes: 10 additions & 24 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading