less messy assert processing

This commit is contained in:
AF 2020-08-11 02:44:54 +03:00
parent f363a86f87
commit b6edd8fc43
4 changed files with 38 additions and 32 deletions

View File

@ -50,7 +50,7 @@ class Message:
return self.sfrom, self.sto return self.sfrom, self.sto
def seal(self) -> bytes: def seal(self) -> bytes:
assert isinstance(self.sfrom, PrivateSubject) assert isinstance(self.sfrom, PrivateSubject), 'Subject misuse'
scontent: nacl.signing.SignedMessage = self.sfrom.skey.sign(self.pcontent) scontent: nacl.signing.SignedMessage = self.sfrom.skey.sign(self.pcontent)
self.encrypt(scontent) self.encrypt(scontent)
return self.econtent return self.econtent
@ -83,7 +83,7 @@ class Message:
def decrypt(self, s: int) -> bytes: def decrypt(self, s: int) -> bytes:
subject = self.pair[s] subject = self.pair[s]
assert isinstance(subject, PrivateSubject) assert isinstance(subject, PrivateSubject), 'Subject misuse'
key: bytes = nacl.public.SealedBox(subject.ekey).decrypt( key: bytes = nacl.public.SealedBox(subject.ekey).decrypt(
[self.econtent[:KEY_SIZE], self.econtent[KEY_SIZE:2 * KEY_SIZE]][s]) [self.econtent[:KEY_SIZE], self.econtent[KEY_SIZE:2 * KEY_SIZE]][s])
return nacl.secret.SecretBox(key).decrypt(self.econtent[2 * KEY_SIZE:]) return nacl.secret.SecretBox(key).decrypt(self.econtent[2 * KEY_SIZE:])
@ -118,9 +118,9 @@ class Message:
def alter(self, sfrom: Optional[Subject] = None, sto: Optional[Subject] = None): def alter(self, sfrom: Optional[Subject] = None, sto: Optional[Subject] = None):
if sfrom is not None: if sfrom is not None:
assert self.sfrom == sfrom assert self.sfrom == sfrom, 'alter mismatch'
self.sfrom = sfrom self.sfrom = sfrom
if sto is not None: if sto is not None:
assert self.sto == sto assert self.sto == sto, 'alter mismatch'
self.sto = sto self.sto = sto
return self return self

View File

@ -105,10 +105,10 @@ class DBStorage(AbstractStorage):
session.close() session.close()
def edit(self, old: Message, new: Message): def edit(self, old: Message, new: Message):
assert old.edited(new) assert old.edited(new), 'edit misuse'
session = self.Session() session = self.Session()
msg = self.one_alike(session, old) msg = self.one_alike(session, old)
assert msg.en == old.editnonce assert msg.en == old.editnonce, 'edit misuse'
msgn = Msg.from_message(new) msgn = Msg.from_message(new)
msg.en = msgn.en msg.en = msgn.en
msg.ec = msgn.ec msg.ec = msgn.ec
@ -169,9 +169,9 @@ class DBStorage(AbstractStorage):
def flags(self, m: Message, flags: str): def flags(self, m: Message, flags: str):
session = self.Session() session = self.Session()
msg: Msg = self.one_alike(session, m) msg: Msg = self.one_alike(session, m)
assert msg.en == m.editnonce assert msg.en == m.editnonce, 'flags misuse'
assert Flags(msg.flags).quable() assert Flags(msg.flags).quable(), 'flags misuse'
assert not Flags(flags).quable() assert not Flags(flags).quable(), 'flags misuse'
msg.flags = flags msg.flags = flags
session.commit() session.commit()
session.close() session.close()

View File

@ -10,26 +10,29 @@ class SecureStorage(AbstractStorage):
self.storage = storage self.storage = storage
self.subject = subject self.subject = subject
def asrt(self):
return self.subject.dumps()
def check(self, subject: Subject) -> dict: def check(self, subject: Subject) -> dict:
assert self.subject == subject assert self.subject == subject, self.asrt()
return self.storage.check(subject) return self.storage.check(subject)
def push(self, m: Message) -> None: def push(self, m: Message) -> None:
assert self.subject == m.sfrom assert self.subject == m.sfrom, self.asrt()
return self.storage.push(m) return self.storage.push(m)
def edit(self, old: Message, new: Message): def edit(self, old: Message, new: Message):
assert self.subject == old.sfrom assert self.subject == old.sfrom, self.asrt()
return self.storage.edit(old, new) return self.storage.edit(old, new)
def delete(self, m: Message): def delete(self, m: Message):
assert self.subject in m.pair assert self.subject in m.pair, self.asrt()
return self.storage.delete(m) return self.storage.delete(m)
def pull(self, pair: Tuple[Subject, Subject], params: Optional[dict] = None) -> Iterable[Message]: def pull(self, pair: Tuple[Subject, Subject], params: Optional[dict] = None) -> Iterable[Message]:
assert self.subject in pair assert self.subject in pair, self.asrt()
return self.storage.pull(pair, params) return self.storage.pull(pair, params)
def flags(self, m: Message, flags: str): def flags(self, m: Message, flags: str):
assert self.subject in m.pair assert self.subject in m.pair, self.asrt()
return self.storage.flags(m, flags) return self.storage.flags(m, flags)

View File

@ -1,7 +1,8 @@
from json import loads from json import loads
from typing import Tuple from sys import stderr
from typing import Callable, Tuple, Any
from flask import Flask, jsonify, request from flask import Flask, jsonify, request, abort
from v25.messaging.encoding import Encoding from v25.messaging.encoding import Encoding
from v25.messaging.message import Message from v25.messaging.message import Message
@ -11,6 +12,13 @@ from v25.storage.storage import AbstractStorage
class API(Flask): 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: AbstractStorage): def __init__(self, import_name, storage: AbstractStorage):
self.storage = storage self.storage = storage
super().__init__(import_name) super().__init__(import_name)
@ -19,11 +27,11 @@ class API(Flask):
def allowed(self, s: Subject): def allowed(self, s: Subject):
return 'allowed' in self.storage.check(s) return 'allowed' in self.storage.check(s)
def ss(self): def ss(self) -> Tuple[Any, SecureStorage]:
d = request.json d = request.json
source: str = d['source'] source: str = d['source']
subject = Subject.loads(d['subject']) subject = Subject.loads(d['subject'])
assert self.allowed(subject) assert self.allowed(subject), subject.dumps()
subject.vkey.verify(source.encode(), Encoding.decode(d['signature'])) subject.vkey.verify(source.encode(), Encoding.decode(d['signature']))
return loads(source), SecureStorage(self.storage, subject) return loads(source), SecureStorage(self.storage, subject)
@ -36,31 +44,26 @@ class API(Flask):
@app.route('/check', methods=['POST']) @app.route('/check', methods=['POST'])
def check(): def check():
d, storage = self.ss() return self.nomessassertcall(lambda d, storage: storage.check(Subject.loads(d)))
return jsonify(storage.check(Subject.loads(d)))
@app.route('/push', methods=['POST']) @app.route('/push', methods=['POST'])
def push(): def push():
d, storage = self.ss() return self.nomessassertcall(lambda d, storage: storage.push(Message.loads(d)))
return jsonify(storage.push(Message.loads(d)))
@app.route('/edit', methods=['POST']) @app.route('/edit', methods=['POST'])
def edit(): def edit():
d, storage = self.ss() return self.nomessassertcall(
return jsonify(storage.edit(Message.loads(d['old']), Message.loads(d['new']))) lambda d, storage: storage.edit(Message.loads(d['old']), Message.loads(d['new'])))
@app.route('/delete', methods=['POST']) @app.route('/delete', methods=['POST'])
def delete(): def delete():
d, storage = self.ss() return self.nomessassertcall(lambda d, storage: storage.delete(Message.loads(d)))
return jsonify(storage.delete(Message.loads(d)))
@app.route('/pull', methods=['POST']) @app.route('/pull', methods=['POST'])
def pull(): def pull():
d, storage = self.ss() return self.nomessassertcall(lambda d, storage: list(map(Message.dumps, storage.pull(
pair: Tuple[Subject, Subject] = Subject.loads(d['pair'][0]), Subject.loads(d['pair'][1]) (Subject.loads(d['pair'][0]), Subject.loads(d['pair'][1])), d['params']))))
return jsonify(list(map(Message.dumps, storage.pull(pair, d['params']))))
@app.route('/flags', methods=['POST']) @app.route('/flags', methods=['POST'])
def flags(): def flags():
d, storage = self.ss() return self.nomessassertcall(lambda d, storage: storage.flags(Message.loads(d['m']), d['flags']))
return jsonify(storage.flags(Message.loads(d['m']), d['flags']))