feat: init ap server w webfinger endpoint
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
faa67e9408
commit
73430848e8
6 changed files with 120 additions and 0 deletions
0
ap/__init__.py
Normal file
0
ap/__init__.py
Normal file
12
ap/__main__.py
Normal file
12
ap/__main__.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
if __name__ == "__main__":
|
||||
from .config import Config
|
||||
from .db import Database
|
||||
from .server import app
|
||||
|
||||
db = Database()
|
||||
db.add_user("alice")
|
||||
|
||||
config = Config()
|
||||
config.options["port"] = 9003
|
||||
config.options["hostname"] = f'lab.batsense.net:{config.options["port"]}'
|
||||
app.run(host="0.0.0.0", port=config.options["port"], debug=True)
|
12
ap/config.py
Normal file
12
ap/config.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
from ftest_common.logger import logger
|
||||
|
||||
|
||||
class Config(object):
|
||||
_instance = None
|
||||
options = {}
|
||||
|
||||
def __new__(cls):
|
||||
if cls._instance is None:
|
||||
logger.info("Creating the config")
|
||||
cls._instance = super(Config, cls).__new__(cls)
|
||||
return cls._instance
|
26
ap/db.py
Normal file
26
ap/db.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
from ftest_common.logger import logger
|
||||
|
||||
|
||||
class Database(object):
|
||||
_instance = None
|
||||
db = {}
|
||||
# { "user": [{name: foo..}{..}{..}] }
|
||||
|
||||
def __new__(cls):
|
||||
if cls._instance is None:
|
||||
logger.info("Creating the store")
|
||||
cls._instance = super(Database, cls).__new__(cls)
|
||||
return cls._instance
|
||||
|
||||
def get_user(self, username):
|
||||
for u in self.db["users"]:
|
||||
print(u)
|
||||
if u["username"] == username:
|
||||
return u
|
||||
return None
|
||||
|
||||
def add_user(self, username):
|
||||
if "users" not in self.db:
|
||||
self.db["users"] = []
|
||||
|
||||
self.db["users"].append({"username": username})
|
17
ap/errors.py
Normal file
17
ap/errors.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
from flask import jsonify, Response as FlaskResponse
|
||||
|
||||
|
||||
def bad_req(msg):
|
||||
"""400 bad request status code"""
|
||||
res = FlaskResponse()
|
||||
res.status_code = 400
|
||||
res.data = msg
|
||||
return res
|
||||
|
||||
|
||||
def not_found(msg):
|
||||
"""404 not found request status code"""
|
||||
res = FlaskResponse()
|
||||
res.status_code = 404
|
||||
res.data = msg
|
||||
return res
|
53
ap/server.py
Normal file
53
ap/server.py
Normal file
|
@ -0,0 +1,53 @@
|
|||
from flask import Flask, request, jsonify
|
||||
from flask_cors import CORS, cross_origin
|
||||
|
||||
from .config import Config
|
||||
from .db import Database
|
||||
from .errors import bad_req, not_found
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
JRD_JSON = "application/jrd+json; charset=utf-8"
|
||||
|
||||
WEBFINGER_ROUTE = "/.well-known/webfinger"
|
||||
|
||||
@app.route(WEBFINGER_ROUTE, methods=["GET"])
|
||||
@cross_origin()
|
||||
def hello_world():
|
||||
config = Config()
|
||||
db = Database()
|
||||
|
||||
resource = request.args.get("resource")
|
||||
if resource is None:
|
||||
bad_req("webfinger must have 'resource' arg")
|
||||
if "acct:" not in resource:
|
||||
return bad_req("webfinger resource query must have 'acct'")
|
||||
if "@" not in resource:
|
||||
return bad_req("webfinger resource query must have '@'")
|
||||
|
||||
parts = resource.split("acct:")
|
||||
parts = parts[1].split("@")
|
||||
username = parts[0]
|
||||
hostname = parts[1]
|
||||
if hostname != config.options["hostname"]:
|
||||
bad_req(f"Only serves hostname {config.options['hostname']}")
|
||||
user = db.get_user(username)
|
||||
if user is None:
|
||||
return not_found(f"resource {username} not found")
|
||||
|
||||
resp = jsonify(
|
||||
{
|
||||
"subject": f"acct:{username}@{hostname}",
|
||||
"aliases": [f"http://{hostname}/@{username}"],
|
||||
"links": [
|
||||
{
|
||||
"rel": "self",
|
||||
"type": "application/activity+json",
|
||||
"href": f"http://{hostname}/users/{username}",
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
resp.headers["Content-Type"] = JRD_JSON
|
||||
return resp
|
Loading…
Reference in a new issue