v25/v25/web/server/api.py
2020-08-14 01:22:09 +03:00

83 lines
3.0 KiB
Python

from json import loads
from sys import stderr
from typing import Callable, Tuple, Any
from flask import Flask, jsonify, request, abort
from v25.messaging.encoding import Encoding
from v25.messaging.message import Message
from v25.messaging.subject import Subject
from v25.storage.secstorage import SecureStorage
from v25.storage.storage import PushStorage
class API(Flask):
def nomessassertcall(self, f: Callable[[Any, SecureStorage], object]) -> str:
try:
return jsonify(f(*self.ss()))
except AssertionError as e:
print('asrt', e, file=stderr)
abort(403)
def __init__(self, import_name, storage: PushStorage):
self.storage = storage
super().__init__(import_name)
self.routes()
def allowed(self, s: Subject):
return 'allowed' in self.storage.check(s)
def ss(self) -> Tuple[Any, SecureStorage]:
d = request.json
source: str = d['source']
subject = Subject.loads(d['subject'])
assert self.allowed(subject), subject.dumps()
subject.vkey.verify(source.encode(), Encoding.decode(d['signature']))
return loads(source), SecureStorage(self.storage, subject)
def routes(self):
app = self
@app.route('/')
def root():
return "V25API"
@app.route('/check', methods=['POST'])
def check():
return self.nomessassertcall(lambda d, storage: storage.check(Subject.loads(d)))
@app.route('/push', methods=['POST'])
def push():
return self.nomessassertcall(lambda d, storage: storage.push(Message.loads(d)))
@app.route('/edit', methods=['POST'])
def edit():
return self.nomessassertcall(
lambda d, storage: storage.edit(Message.loads(d['old']), Message.loads(d['new'])))
@app.route('/delete', methods=['POST'])
def delete():
return self.nomessassertcall(lambda d, storage: storage.delete(Message.loads(d)))
@app.route('/pull', methods=['POST'])
def pull():
return self.nomessassertcall(lambda d, storage: list(map(Message.dumps, storage.pull(
(Subject.loads(d['pair'][0]), Subject.loads(d['pair'][1])), d['params']))))
@app.route('/flags', methods=['POST'])
def flags():
return self.nomessassertcall(lambda d, storage: storage.flags(Message.loads(d['m']), d['flags']))
@app.route('/events', methods=['POST'])
def events():
return self.nomessassertcall(lambda d, storage: [list(map(Encoding.encode, ev)) for ev in storage.events(
Subject.loads(d['sfrom']),
Subject.loads(d['sto']),
Encoding.decode(d['after'])
)])
@app.route('/subscribe', methods=['POST'])
def subscribe():
return self.nomessassertcall(lambda d, storage: storage.subscribe(Subject.loads(d['subject']),
d['subscription']))