import json from binascii import Error as asciiError from flask import Blueprint from flask import current_app as app from flask import g, jsonify, request from flask.views import View from flask.wrappers import Response from marshmallow.exceptions import ValidationError from werkzeug.exceptions import Unauthorized from ereuse_devicehub.auth import Auth from ereuse_devicehub.db import db from ereuse_devicehub.parser.models import SnapshotsLog from ereuse_devicehub.parser.parser import ParseSnapshotLsHw from ereuse_devicehub.parser.schemas import Snapshot_lite from ereuse_devicehub.resources.action.views.snapshot import ( SnapshotMixin, move_json, save_json, ) from ereuse_devicehub.resources.enums import Severity api = Blueprint('api', __name__, url_prefix='/api') class LoginMixin(View): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.authenticate() def authenticate(self): unauthorized = Unauthorized('Provide a suitable token.') basic_token = request.headers.get('Authorization', " ").split(" ") if not len(basic_token) == 2: raise unauthorized token = basic_token[1] try: token = Auth.decode(token) except asciiError: raise unauthorized self.user = Auth().authenticate(token) g.user = self.user class InventoryView(LoginMixin, SnapshotMixin): methods = ['POST'] def dispatch_request(self): snapshot_json = json.loads(request.data) self.tmp_snapshots = app.config['TMP_SNAPSHOTS'] self.path_snapshot = save_json(snapshot_json, self.tmp_snapshots, g.user.email) snapshot_json = self.validate(snapshot_json) if type(snapshot_json) == Response: return snapshot_json self.snapshot_json = ParseSnapshotLsHw(snapshot_json).get_snapshot() snapshot = self.build() snapshot.device.set_hid() snapshot.device.binding.device.set_hid() db.session.add(snapshot) snap_log = SnapshotsLog( description='Ok', snapshot_uuid=snapshot.uuid, severity=Severity.Info, sid=snapshot.sid, version=str(snapshot.version), snapshot=snapshot, ) snap_log.save() db.session().final_flush() db.session.commit() url = "https://{}/".format(app.config['HOST']) public_url = "{}{}".format(url.strip("/"), snapshot.device.url.to_text()) self.response = jsonify( { 'dhid': snapshot.device.dhid, 'url': url, 'public_url': public_url, } ) self.response.status_code = 201 move_json(self.tmp_snapshots, self.path_snapshot, g.user.email) return self.response def validate(self, snapshot_json): self.schema = Snapshot_lite() try: return self.schema.load(snapshot_json) except ValidationError as err: txt = "{}".format(err) uuid = snapshot_json.get('uuid') sid = snapshot_json.get('sid') version = snapshot_json.get('version') error = SnapshotsLog( description=txt, snapshot_uuid=uuid, severity=Severity.Error, sid=sid, version=str(version), ) error.save(commit=True) # raise err self.response = jsonify(err) self.response.status_code = 400 return self.response api.add_url_rule('/inventory/', view_func=InventoryView.as_view('inventory'))