def delete(self, todolist_id): """ --- tags: - "todolist" summary: Deletes todolist parameters: - name: todolist_id in: path schema: type: string format: uuid example: 00000000-0000-0000-0000-000000000000 responses: '204': description: "Successful operation" content: application/json: schema: TodoListOK '400': description: "Database error" content: application/json: schema: TodoListError '401': description: "Not user logged in" content: application/json: schema: TodoListError '404': description: "Not existing user" content: application/json: schema: TodoListError """ logged_user_id = current_user.user_id if not current_user.role(todolist_id): logger.error(f"Getting {request.url} using {request.method}, user {current_user.login} " f"with no access to todolist {todolist_id}") return jsonify({'error': 'User with no access to todolist'}), 404 if current_user.role(todolist_id) != 'owner': logger.error(f"Getting {request.url} using {request.method}, user {current_user.login} " f"has got no permission to delete todolist {todolist_id}") return jsonify({'error': 'No permission for deleting todolist'}), 403 todolist_api = TodoListApi(logged_user_id) todolist = todolist_api.read_todolist_by_id(todolist_id) deleted = todolist_api.delete_todolist(todolist_id) if not deleted: logger.error(f"Getting {request.url} with {request.method}, database error") return jsonify({'error': f"Database error"}), 400 logger.info(f"Getting {request.url} using {request.method}") return jsonify({'response': f"TodoList {todolist.label} deleted"}), 200
def get(self, todolist_id): """ --- tags: - "task" summary: Returns task tree one level or expanded descendants parameters: - name: todolist_id in: path schema: type: string format: uuid example: 00000000-0000-0000-0000-000000000000 - name: expand in: query schema: type: boolean - name: task_id in: query schema: type: string format: uuid example: 00000000-0000-0000-0000-000000000000 responses: '200': description: "Successful operation" content: application/json: schema: TaskGet '404': description: "No task available or no access to todolist" content: application/json: schema: TaskError """ logged_user_id = current_user.user_id if not current_user.role(todolist_id): return jsonify({'error': 'User with no access to todolist'}), 404 # additional query params expand = request.args.get('expand', default=None) task_id = request.args.get('task_id', default=None) task_api = TaskApi(logged_user_id, todolist_id) data = task_api.get_tasks(boolean(expand), task_id) logger.info(f"Getting {request.url} using {request.method}") if data: return jsonify(data), 200 else: return jsonify({'error': 'No list available'}), 404
def decorated_view(*args, **kwargs): if not current_user.is_authenticated: return login_manager.unauthorized() unauthorized = False if role != "ANY": unauthorized = True if current_user.role() == role: unauthorized = False if unauthorized: return login_manager.unauthorized() return fn(*args, **kwargs)
def put(self, todolist_id, email): """ --- tags: - "todolist" summary: Manages permissions parameters: - name: todolist_id in: path schema: type: string format: uuid example: 00000000-0000-0000-0000-000000000000 - name: email in: path schema: type: string maxLength: 250 minLength: 5 pattern: ^[^@\s]+@[^@\s]+\.[^@\s]+$ example: [email protected] - name: role in: query schema: type: string enum: [owner, admin, reader] - name: new_owner_role in: query schema: type: string enum: [admin, reader] responses: '200': description: "Successful operation" content: application/json: schema: TodoListOK '400': description: "Request with no data to change" content: application/json: schema: TodoListError '401': description: "No user logged in" content: application/json: schema: TodoListError '403': description: "No permission for updating todolist" content: application/json: schema: TodoListError '404': description: "Not existing todolist" content: application/json: schema: TodoListError """ # noqa if not current_user: return jsonify({'error': 'No user logged in'}), 401 logged_user_id = current_user.user_id if not current_user.role(todolist_id): logger.error(f"Getting {request.url} using {request.method}, user {current_user.login} " f"with no access to todolist {todolist_id}") return jsonify({'error': 'User with no access to todolist'}), 404 if current_user.role(todolist_id) != 'owner': logger.error(f"Getting {request.url} using {request.method}, user {current_user.login} " f"has got no permission to update todolist {todolist_id}") return jsonify({'error': 'No permission for updating todolist'}), 403 if current_user.email == email: logger.error(f"Getting {request.url} using {request.method}, user {current_user.login} " f"has got no permission to his rights himself") return jsonify({'error': 'No permission for updating logged user rights itself'}), 403 # check todolist todolist_api = TodoListApi(logged_user_id) todolist = todolist_api.read_todolist_by_id(todolist_id) # check user user_api = UserApi() user = user_api.read_user_by_email(email) if not user: logger.error(f"Getting {request.url} using {request.method}, not existing email {email}") return jsonify({'error': f"Not existing {email}"}), 404 role_name = request.args.get('role', default=None) new_owner_role_name = None if role_name and role_name == 'owner': new_owner_role_name = request.args.get('new_owner_role', default=None) updated = todolist_api.permissions(todolist_id, user.user_id, role_name, new_owner_role_name) if not updated: logger.error(f"Getting {request.url} with {request.method}, database error") return jsonify({'error': f"Database error"}), 400 logger.info(f"Getting {request.url} using {request.method}") return jsonify({'response': f"TodoList {todolist.label} updated"}), 200
def patch(self, todolist_id): """ --- tags: - "todolist" summary: Changes todolists properties parameters: - name: todolist_id in: path schema: type: string format: uuid example: 00000000-0000-0000-0000-000000000000 requestBody: required: true content: application/json: schema: TodoListPatch responses: '200': description: "Successful operation" content: application/json: schema: TodoListOK '400': description: "Request with no data to change or database error" content: application/json: schema: TodoListError '403': description: "No permission for updating todolist" content: application/json: schema: TodoListError '404': description: "Not existing todolist" content: application/json: schema: TodoListError '409': description: "Bad format of input data" content: application/json: schema: TodoListError """ logged_user_id = current_user.user_id if not current_user.role(todolist_id): logger.error(f"Getting {request.url} using {request.method}, user {current_user.login} " f"with no access to todolist {todolist_id}") return jsonify({'error': 'User with no access to todolist'}), 404 if current_user.role(todolist_id) == 'reader': logger.error(f"Getting {request.url} using {request.method}, user {current_user.login} " f"has got no permission to update todolist {todolist_id}") return jsonify({'error': 'No permission for updating todolist'}), 403 schema, errors = TodoListPatch().load(request.get_json()) if errors: logger.error(f"Getting {request.url} using {request.method}, errors {errors}") return jsonify({'error': errors}), 409 if not schema: logger.debug(f"Getting {request.url} using {request.method}, no data to change") return jsonify({'error': 'Request with no data to change'}), 400 todolist_api = TodoListApi(logged_user_id) todolist = todolist_api.read_todolist_by_id(todolist_id) to_change = dict() if schema.get('label', None) and schema['label'] != todolist.label: to_change['label'] = schema['label'] # can be null if schema.get('description', None) != todolist.description: to_change['description'] = schema.get('description', None) if schema.get('status', None) and schema['status'] != todolist.status.name: to_change['status'] = schema['status'] if schema.get('priority', None) and schema['priority'] != todolist.priority.value: to_change['priority'] = schema['priority'] if to_change: logger.info(f"Getting {request.url} using {request.method} with schema {schema}") updated = todolist_api.update_todolist(todolist_id, to_change) if not updated: logger.error(f"Getting {request.url} with {request.method}, database error") return jsonify({'error': f"Database error"}), 400 return jsonify({'response': f"TodoList {todolist.label} modified"}), 200
def post(self, todolist_id): """ --- tags: - "task" summary: Creates new tasks parameters: - name: todolist_id in: path schema: type: string format: uuid example: 00000000-0000-0000-0000-000000000000 requestBody: required: true content: application/json: schema: TaskPost responses: '201': description: "Successful operation" content: application/json: schema: TaskGet '400': description: "Database error" content: application/json: schema: TaskError '403': description: "No permission to access todolist or create a task or limit exceeded" content: application/json: schema: TaskError '409': description: "Not correct input data" content: application/json: schema: TaskError """ logged_user_id = current_user.user_id if not current_user.role(todolist_id): logger.error(f"Getting {request.url} using {request.method}, user {current_user.login} " f"with no access to todolist {todolist_id}") return jsonify({'error': 'No permission to access todolist'}), 403 if current_user.role(todolist_id) == 'reader': logger.error(f"Getting {request.url} using {request.method}, user {current_user.login} " f"with no permission to create task") return jsonify({'error': 'No permission to create task'}), 403 schema, errors = TaskPost().load(request.get_json()) if errors: logger.error(f"Getting {request.url} using {request.method}, errors: {errors}") return jsonify({'error': errors}), 409 task_api = TaskApi(logged_user_id, todolist_id) task = task_api.create_task(schema) if task is None: logger.error(f"Getting {request.url} with {request.method}, database error") return jsonify({'error': 'Database error'}), 400 elif not task: logger.error(f"Getting {request.url} with {request.method}, limit exceeded") return jsonify({'error': 'Limit exceeded'}), 403 return jsonify(task.to_dict()), 201
def put(self, todolist_id, task_id): """ --- tags: - "task" summary: Reparent task, moves it inside the todolist parameters: - name: todolist_id in: path schema: type: string format: uuid example: 00000000-0000-0000-0000-000000000000 - name: task_id in: path schema: type: string format: uuid example: 00000000-0000-0000-0000-000000000000 - name: new_parent_id in: query schema: type: string format: uuid example: 00000000-0000-0000-0000-000000000000 responses: '200': description: "Successful operation" content: application/json: schema: TaskOK '400': description: "Request with no data to change" content: application/json: schema: TaskError '403': description: "No permission to access todolist or change a task" content: application/json: schema: TaskError '404': description: "Not existing todolist" content: application/json: schema: TaskError """ logged_user_id = current_user.user_id if not current_user.role(todolist_id): logger.error(f"Getting {request.url} using {request.method}, user {current_user.login} " f"with no access to todolist {todolist_id}") return jsonify({'error': 'No permission to access todolist'}), 403 if current_user.role(todolist_id) == 'reader': logger.error(f"Getting {request.url} using {request.method}, user {current_user.login} " f"with no permission to create task") return jsonify({'error': 'No permission to create task'}), 403 logger.info(f"Getting {request.url} using {request.method}") new_parent_id = request.args.get('new_parent_id', default=None) # check task task_api = TaskApi(logged_user_id, todolist_id) task = task_api.read_task_by_id(task_id) updated = task_api.reparent_tasks(task_id, new_parent_id) if updated is None: logger.error(f"Getting {request.url} with {request.method}, database error") return jsonify({'error': f"Database error"}), 400 elif not updated: logger.error(f"Getting {request.url} using {request.method}, user {current_user.login} " f"with no permission to reparent task") return jsonify({'error': f"No permission to reparent task."}), 403 return jsonify({'response': f"TodoList {task.label} updated"}), 200
def delete(self, todolist_id): """ --- tags: - "task" summary: Deletes task or purges done tasks parameters: - name: todolist_id in: path schema: type: string format: uuid example: 00000000-0000-0000-0000-000000000000 - name: action in: query schema: type: string enum: [delete, purge] required: true - name: task_id in: query schema: type: string format: uuid example: 00000000-0000-0000-0000-000000000000 responses: '204': description: "Successful operation" content: application/json: schema: TaskOK '400': description: "Database error" content: application/json: schema: TaskError '403': description: "No permission to access todolist or change a task" content: application/json: schema: TaskError '409': description: "task_id cannot be null" content: application/json: schema: TaskError """ logged_user_id = current_user.user_id if not current_user.role(todolist_id): logger.error(f"Getting {request.url} using {request.method}, user {current_user.login} " f"with no access to todolist {todolist_id}") return jsonify({'error': 'No permission to access todolist'}), 403 if current_user.role(todolist_id) == 'reader': logger.error(f"Getting {request.url} using {request.method}, user {current_user.login} " f"with no permission to create task") return jsonify({'error': 'No permission to create task'}), 403 task_api = TaskApi(logged_user_id, todolist_id) action = request.args.get('action', default=None) task_id = request.args.get('task_id', default=None) logger.info(f"Getting {request.url} using {request.method}") if action == 'purge': deleted = task_api.purge_tasks() else: if not task_id: logger.error(f"Getting {request.url} using {request.method}: " f"task_id cannot be null when action {action}") return jsonify({'error': f"task_id cannot be null"}), 409 task = task_api.read_task_by_id(task_id) deleted = task_api.delete_task(task_id) if not deleted: logger.error(f"Getting {request.url} with {request.method}, database error") return jsonify({'error': f"Database error"}), 400 if action == 'purge': return jsonify({'response': f"Tasks purged"}), 200 else: return jsonify({'response': f"Task {task.label} deleted"}), 200
def patch(self, todolist_id, task_id): """ --- tags: - "task" summary: Changes tasks properties parameters: - name: todolist_id in: path schema: type: string format: uuid example: 00000000-0000-0000-0000-000000000000 - name: task_id in: path schema: type: string format: uuid example: 00000000-0000-0000-0000-000000000000 requestBody: required: true content: application/json: schema: TaskPatch responses: '200': description: "Successful operation" content: application/json: schema: TaskOK '400': description: "Request with no data to change or database error" content: application/json: schema: TaskError '403': description: "No permission to access todolist or change a task" content: application/json: schema: TaskError '409': description: "Bad format of input data" content: application/json: schema: TaskError """ logged_user_id = current_user.user_id if not current_user.role(todolist_id): logger.error(f"Getting {request.url} using {request.method}, user {current_user.login} " f"with no access to todolist {todolist_id}") return jsonify({'error': 'No permission to access todolist'}), 403 if current_user.role(todolist_id) == 'reader': logger.error(f"Getting {request.url} using {request.method}, user {current_user.login} " f"with no permission to create task") return jsonify({'error': 'No permission to create task'}), 403 schema, errors = TaskPatch().load(request.get_json()) if errors: return jsonify({'error': errors}), 409 if not schema: return jsonify({'error': 'Request with no data to change'}), 400 task_api = TaskApi(logged_user_id, todolist_id) task = task_api.read_task_by_id(task_id) to_change = dict() if schema.get('label', None) and schema['label'] != task.label: to_change['label'] = schema['label'] # can be null if schema.get('description', None) != task.description: to_change['description'] = schema.get('description', None) if schema.get('status', None) and schema['status'] != task.status.name: to_change['status'] = schema['status'] if schema.get('priority', None) and schema['priority'] != task.priority.value: to_change['priority'] = schema['priority'] if to_change: logger.info(f"Getting {request.url} using {request.method} with schema {schema}") updated = task_api.update_task(task_id, to_change) if updated is None: logger.error(f"Getting {request.url} with {request.method}, database error") return jsonify({'error': f"Database error"}), 400 elif not updated: logger.error(f"Getting {request.url} using {request.method}, todolist {todolist_id}. " f"No permission for updating task. Not all descendants are done.") return jsonify({'error': f"No permission for updating task. Not all descendants are done."}), 403 return jsonify({'response': f"Task {task.label} modified"}), 200
def decorator(*args, **kwargs): if current_user.role() == "ADMIN": return a(*args, **kwargs) else: abort(401)
def index(): tasks = DbCommunicator.get_items() has_write_access = current_user.role() == Role.Writer item_view_model = ViewModel(tasks, has_write_access) return render_template('index.html', data=item_view_model)
def requireWriteAccess(): if current_user.role() == Role.Reader: abort(403) return