# Copyright (c) 2019. Tobias Kurze """ This module provides functions related to authentication through the API. For example: listing of available auth providers or registration of users. Login through API does not start a new session, but instead returns JWT. """ from datetime import datetime from pprint import pprint from flask_jwt_extended import jwt_required from flask_restx import fields, Resource, inputs from backend import db, app from backend.api import api_recorder from backend.api.models import recorder_model, recorder_model_model, recorder_command_model from backend.models.recorder_model import Recorder, RecorderModel, RecorderCommand from backend.models.room_model import Room import backend.recorder_adapters as r_a # == @api_recorder.route('/') @api_recorder.response(404, 'Recorder not found') @api_recorder.param('id', 'The recorder identifier') class RecorderResource(Resource): @jwt_required @api_recorder.doc('get_recorder') @api_recorder.marshal_with(recorder_model, skip_none=False) def get(self, id): """Fetch a recorder given its identifier""" recorder = Recorder.query.get(id) if recorder is not None: return recorder api_recorder.abort(404) @jwt_required @api_recorder.doc('delete_todo') @api_recorder.response(204, 'Todo deleted') def delete(self, id): """Delete a recorder given its identifier""" recorder = Recorder.query.get(id) if recorder is not None: db.session.delete(recorder) db.session.commit() return '', 204 api_recorder.abort(404) recorder_update_parser = api_recorder.parser() recorder_update_parser.add_argument('name', type=str, required=False, nullable=False, store_missing=False) recorder_update_parser.add_argument('network_name', type=inputs.regex(inputs.netloc_regex), required=False, store_missing=False) recorder_update_parser.add_argument('ip', type=inputs.ipv4, required=False, store_missing=False) recorder_update_parser.add_argument('ip6', type=inputs.ipv6, required=False, store_missing=False) recorder_update_parser.add_argument('ssh_port', type=inputs.int_range(0,65535), required=False, default=22, store_missing=False) recorder_update_parser.add_argument('telnet_port', type=inputs.int_range(0,65535), required=False, default=23, store_missing=False) recorder_update_parser.add_argument('room_id', type=int, required=False, store_missing=False) recorder_update_parser.add_argument('offline', type=inputs.boolean, required=False, default=False, store_missing=False) recorder_update_parser.add_argument('locked', type=inputs.boolean, required=False, default=False, store_missing=False) recorder_update_parser.add_argument('lock_message', type=str, required=False, nullable=True, default=None, store_missing=False) recorder_update_parser.add_argument('model_id', type=int, required=False, store_missing=False) recorder_update_parser.add_argument('description', type=str, required=False, nullable=True, default=None, store_missing=False) recorder_update_parser.add_argument('virtual_command_ids', action='split', nullable=True, default=[], required=False, store_missing=False) @jwt_required @api_recorder.doc('update_recorder') @api_recorder.expect(recorder_model) def put(self, id): """Update a recorder given its identifier""" args = self.recorder_update_parser.parse_args(strict=True) args['last_time_modified'] = datetime.utcnow() pprint(args) num_rows_matched = Recorder.query.filter_by(id=id).update(args) print(num_rows_matched) if num_rows_matched < 1: api_recorder.abort(404) db.session.commit() return "ok" @api_recorder.route('') class RecorderList(Resource): @jwt_required @api_recorder.doc('recorders') @api_recorder.marshal_list_with(recorder_model, skip_none=False) def get(self): """ List all recorders :return: recorders """ return Recorder.get_all() @jwt_required @api_recorder.doc('create_recorder') @api_recorder.expect(recorder_model) @api_recorder.marshal_with(recorder_model, skip_none=False, code=201) def post(self): if "room_id" in api_recorder.payload: if api_recorder.payload["room_id"] is None: api_recorder.payload["room"] = None else: room = Room.query.get(api_recorder.payload["room_id"]) if room is not None: api_recorder.payload["room"] = room else: return "specified room (id: {}) does not exist!".format(api_recorder.payload["room_id"]), 404 if "recorder_model_id" in api_recorder.payload: if api_recorder.payload["recorder_model_id"] is None: api_recorder.payload["recorder_model"] = None else: rec_model = RecorderModel.query.get(api_recorder.payload["recorder_model_id"]) if rec_model is not None: api_recorder.payload["recorder_model"] = rec_model else: return "specified recorder model (id: {}) does not exist!".format( api_recorder.payload["recorder_model_id"]), 404 recorder = Recorder(**api_recorder.payload) db.session.add(recorder) db.session.commit() return recorder @api_recorder.route('/model/') @api_recorder.response(404, 'Recorder Model not found') @api_recorder.param('id', 'The recorder model identifier') class RecorderModelResource(Resource): @jwt_required @api_recorder.doc('get_recorder_model') @api_recorder.marshal_with(recorder_model_model) def get(self, id): """Fetch a recorder model given its identifier""" recorder_model = RecorderModel.query.get(id) if recorder_model is not None: return recorder_model api_recorder.abort(404) recorder_model_parser = api_recorder.parser() recorder_model_parser.add_argument('notes', type=str, required=True) @jwt_required @api_recorder.doc('update_recorder_model') @api_recorder.expect(recorder_model_parser) @api_recorder.marshal_with(recorder_model_model) def put(self, id): """Update a recorder_model given its identifier""" num_rows_matched = RecorderModel.query.filter_by(id=id).update(api_recorder.payload) if num_rows_matched < 1: api_recorder.abort(404) db.session.commit() return "ok" @api_recorder.route('/model') class RecorderModelList(Resource): @jwt_required @api_recorder.doc('recorders') @api_recorder.marshal_list_with(recorder_model_model) def get(self): return RecorderModel.get_all() @api_recorder.route('/command/') @api_recorder.response(404, 'Recorder Command not found') @api_recorder.param('id', 'The recorder command identifier') class RecorderCommandResource(Resource): @jwt_required @api_recorder.doc('get_recorder_command') @api_recorder.marshal_with(recorder_command_model) def get(self, id): """Fetch a recorder command given its identifier""" recorder_command = RecorderCommand.query.get(id) if recorder_command is not None: return recorder_command api_recorder.abort(404) recorder_command_model_parser = api_recorder.parser() recorder_command_model_parser.add_argument('description', type=str, required=False) recorder_command_model_parser.add_argument('alternative_name', type=str, required=False) @jwt_required @api_recorder.doc('update_recorder_command') @api_recorder.expect(recorder_command_model_parser) @api_recorder.marshal_with(recorder_command_model) def put(self, id): """Update a recorder command given its identifier""" num_rows_matched = RecorderCommand.query.filter_by(id=id).update(api_recorder.payload) if num_rows_matched < 1: api_recorder.abort(404) db.session.commit() return "ok" @api_recorder.route('/command') class RecorderCommandList(Resource): @jwt_required @api_recorder.doc('recorder_commands') @api_recorder.marshal_list_with(recorder_command_model) def get(self): """ List all recorders commands :return: recorder commands """ return RecorderCommand.get_all()