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): """ --- tags: - "todolist" summary: Returns one or all todolists per user parameters: - name: todolist_id in: query schema: type: string format: uuid example: 00000000-0000-0000-0000-000000000000 - name: label in: query schema: type: string - name: status in: query schema: type: string enum: [active, inactive] - name: priority in: query schema: type: string enum: [veryhigh, high, medium, low, verylow] responses: '200': description: "Successful operation" content: application/json: schema: TodoListGet '404': description: "No list available" content: application/json: schema: TodoListError """ logged_user_id = current_user.user_id filters = dict() filters['label'] = request.args.get('label', default=None) filters['status'] = request.args.get('status', default=None) filters['priority'] = request.args.get('priority', default=None) # todolist todolist_id = request.args.get('todolist_id', default=None) todolist_api = TodoListApi(logged_user_id) data = tuple(todolist_api.get_todolists(todolist_id=todolist_id, filters=filters)) logger.info(f"Getting {request.url} using {request.method}") if data: return jsonify(data), 200 else: return jsonify({'error': 'No list available'}), 404
def post(self): """ --- tags: - "todolist" summary: Creates new todolists requestBody: required: true content: application/json: schema: TodoListPost responses: '201': description: "Successful operation" content: application/json: schema: TodoListGet '403': description: "Limit of todolists owned by user exceeded" content: application/json: schema: TodoListError '409': description: "Database error" content: application/json: schema: TodoListError '409': description: "Not correct input data" content: application/json: schema: TodoListError """ logged_user_id = current_user.user_id schema, errors = TodoListPost().load(request.get_json()) if errors: logger.error(f"Getting {request.url} using {request.method}, errors: {errors}") return jsonify({'error': errors}), 409 logger.info(f"Getting {request.url} using {request.method} with schema {schema}") todolist_api = TodoListApi(logged_user_id) todolist = todolist_api.create_todolist(schema) if todolist is None: logger.error(f"Getting {request.url} with {request.method}, database error") return jsonify({'error': 'Database error'}), 400 elif not todolist: logger.error(f"Getting {request.url} with {request.method}, limit exceeded") return jsonify({'error': 'Limit exceeded'}), 403 return jsonify(todolist.to_dict()), 201
def setUp(self): super().setUp() self.user = UserTbl(user_id=str(uuid4()), login='******', password='******', name='Test User 1', email='*****@*****.**', created=datetime.utcnow()) db.session.add(self.user) db.session.commit() owner = RoleTbl(role='owner', change_owner=1, delete=1, change_permissions=1, change_data=1, read=1, todolist_count_limit=10, task_count_limit=100, task_depth_limit=10) admin = RoleTbl(role='admin', change_owner=0, delete=0, change_permissions=0, change_data=1, read=1, task_count_limit=80, task_depth_limit=8) reader = RoleTbl(role='reader', change_owner=0, delete=0, change_permissions=0, change_data=0, read=1) db.session.add(owner) db.session.add(admin) db.session.add(reader) db.session.commit() todolist_api = TodoListApi(self.user.user_id) self.todolist = todolist_api.create_todolist({ 'label': 'List 1', 'status': TodoListStatus.active.name, 'priority': Priority.high.value }) self.task_api = TaskApi(self.user.user_id, self.todolist.todolist_id)
def setUp(self): super().setUp() self.user = UserTbl(user_id=str(uuid4()), login='******', password='******', name='Test User 1', email='*****@*****.**', created=datetime.utcnow()) db.session.add(self.user) db.session.commit() owner = RoleTbl(role='owner', change_owner=1, delete=1, change_permissions=1, change_data=1, read=1, todolist_count_limit=10, task_count_limit=100, task_depth_limit=10) admin = RoleTbl(role='admin', change_owner=0, delete=0, change_permissions=0, change_data=1, read=1, task_count_limit=80, task_depth_limit=8) reader = RoleTbl(role='reader', change_owner=0, delete=0, change_permissions=0, change_data=0, read=1) db.session.add(owner) db.session.add(admin) db.session.add(reader) db.session.commit() self.todolist_api = TodoListApi(self.user.user_id)
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
class TodoListApiTests(TestCaseWithDB): def setUp(self): super().setUp() self.user = UserTbl(user_id=str(uuid4()), login='******', password='******', name='Test User 1', email='*****@*****.**', created=datetime.utcnow()) db.session.add(self.user) db.session.commit() owner = RoleTbl(role='owner', change_owner=1, delete=1, change_permissions=1, change_data=1, read=1, todolist_count_limit=10, task_count_limit=100, task_depth_limit=10) admin = RoleTbl(role='admin', change_owner=0, delete=0, change_permissions=0, change_data=1, read=1, task_count_limit=80, task_depth_limit=8) reader = RoleTbl(role='reader', change_owner=0, delete=0, change_permissions=0, change_data=0, read=1) db.session.add(owner) db.session.add(admin) db.session.add(reader) db.session.commit() self.todolist_api = TodoListApi(self.user.user_id) def create_todolist_set(self): self.todolist_api.create_todolist({ 'label': 'List 1', 'status': TodoListStatus.active.name, 'priority': Priority.high.value }) self.todolist_api.create_todolist({ 'label': 'List 2', 'status': TodoListStatus.inactive.name, 'priority': Priority.medium.value }) self.todolist_api.create_todolist({ 'label': 'List 4', 'status': TodoListStatus.active.name, 'priority': Priority.medium.value }) self.todolist_api.create_todolist({ 'label': 'List 3', 'status': TodoListStatus.active.name, 'priority': Priority.medium.value }) self.todolist_api.create_todolist({ 'label': 'List 5', 'status': TodoListStatus.inactive.name, 'priority': Priority.veryhigh.value }) self.todolist_api.create_todolist({ 'label': 'List 6', 'status': TodoListStatus.active.name, 'priority': Priority.veryhigh.value }) def test_create_todolist(self): todo = self.todolist_api.create_todolist({ 'label': 'List1', 'status': TodoListStatus.active.name, 'priority': Priority.medium.value }) self.assertEqual([(row['label'], row['priority'], row['status']) for row in self.user.all_todolists()], [('List1', 'medium', 'active')]) self.assertEqual([(change['changed_by'], change['status']) for change in todo.status_changes], [('Test User 1', 'active')]) self.assertEqual(todo.all_roles, [{ 'login': '******', 'name': 'Test User 1', 'email': '*****@*****.**', 'role': 'owner' }]) self.assertEqual(todo.creator, self.user.user_id) todo_fetched = self.todolist_api.read_todolist_by_id(todo.todolist_id) self.assertEqual(todo, todo_fetched) # change limit to 1 of allowed todolists db.session.query(RoleTbl).filter_by(role='owner').update( {'todolist_count_limit': 1}) db.session.commit() self.assertEqual( self.todolist_api.create_todolist({ 'label': 'List2', 'status': TodoListStatus.active.name, 'priority': Priority.medium.value }), False) self.assertEqual([(row['label'], row['priority'], row['status']) for row in self.user.all_todolists()], [('List1', 'medium', 'active')]) # change limit to 10 of allowed todolists again db.session.query(RoleTbl).filter_by(role='owner').update( {'todolist_count_limit': 10}) db.session.commit() todo = self.todolist_api.create_todolist({ 'label': 'List2', 'status': TodoListStatus.active.name, 'priority': Priority.medium.value }) self.assertEqual([(row['label'], row['priority'], row['status']) for row in self.user.all_todolists()], [('List1', 'medium', 'active'), ('List2', 'medium', 'active')]) def test_get_todo_lists(self): self.create_todolist_set() self.assertEqual([{ 'label': row['label'], 'priority': row['priority'], 'status': row['status'] } for row in self.todolist_api.get_todolists(filters={})], [{ 'label': 'List 6', 'priority': 'veryhigh', 'status': 'active' }, { 'label': 'List 5', 'priority': 'veryhigh', 'status': 'inactive' }, { 'label': 'List 1', 'priority': 'high', 'status': 'active' }, { 'label': 'List 3', 'priority': 'medium', 'status': 'active' }, { 'label': 'List 4', 'priority': 'medium', 'status': 'active' }, { 'label': 'List 2', 'priority': 'medium', 'status': 'inactive' }]) self.assertEqual([{ 'label': row['label'], 'priority': row['priority'], 'status': row['status'] } for row in self.todolist_api.get_todolists( filters={'priority': 'medium'})], [{ 'label': 'List 3', 'priority': 'medium', 'status': 'active' }, { 'label': 'List 4', 'priority': 'medium', 'status': 'active' }, { 'label': 'List 2', 'priority': 'medium', 'status': 'inactive' }]) self.assertEqual([{ 'label': row['label'], 'priority': row['priority'], 'status': row['status'] } for row in self.todolist_api.get_todolists(filters={ 'priority': 'medium', 'status': 'active' })], [ { 'label': 'List 3', 'priority': 'medium', 'status': 'active' }, { 'label': 'List 4', 'priority': 'medium', 'status': 'active' }, ]) self.assertEqual( [{ 'label': row['label'], 'priority': row['priority'], 'status': row['status'] } for row in self.todolist_api.get_todolists(filters={ 'priority': 'medium', 'status': 'active', 'label': 'List 4' })], [ { 'label': 'List 4', 'priority': 'medium', 'status': 'active' }, ]) todo = db.session.query(TodoListTbl).filter_by(label='List 3').first() self.assertEqual([{ 'label': row['label'], 'priority': row['priority'], 'status': row['status'] } for row in self.todolist_api.get_todolists( todolist_id=todo.todolist_id)], [ { 'label': 'List 3', 'priority': 'medium', 'status': 'active' }, ]) def test_update_todo_lists(self): self.create_todolist_set() todo = db.session.query(TodoListTbl).filter_by(label='List 3').first() self.assertEqual([{ 'label': row['label'], 'description': row['description'], 'priority': row['priority'], 'status': row['status'], 'saved_status': status['status'], 'changed_by': status['changed_by'] } for row in self.todolist_api.get_todolists( todolist_id=todo.todolist_id) for status in row['status_changes']], [ { 'label': 'List 3', 'description': None, 'priority': 'medium', 'status': 'active', 'saved_status': 'active', 'changed_by': 'Test User 1' }, ]) self.todolist_api.update_todolist(todo.todolist_id, {'label': 'List 7'}) self.assertEqual([{ 'label': row['label'], 'description': row['description'], 'priority': row['priority'], 'status': row['status'], 'saved_status': status['status'], 'changed_by': status['changed_by'] } for row in self.todolist_api.get_todolists( todolist_id=todo.todolist_id) for status in row['status_changes']], [ { 'label': 'List 7', 'description': None, 'priority': 'medium', 'status': 'active', 'saved_status': 'active', 'changed_by': 'Test User 1' }, ]) self.todolist_api.update_todolist(todo.todolist_id, {'description': 'This is List 7'}) self.assertEqual([{ 'label': row['label'], 'description': row['description'], 'priority': row['priority'], 'status': row['status'], 'saved_status': status['status'], 'changed_by': status['changed_by'] } for row in self.todolist_api.get_todolists( todolist_id=todo.todolist_id) for status in row['status_changes']], [ { 'label': 'List 7', 'description': 'This is List 7', 'priority': 'medium', 'status': 'active', 'saved_status': 'active', 'changed_by': 'Test User 1' }, ]) self.todolist_api.update_todolist(todo.todolist_id, {'priority': 'a'}) self.assertEqual([{ 'label': row['label'], 'description': row['description'], 'priority': row['priority'], 'status': row['status'], 'saved_status': status['status'], 'changed_by': status['changed_by'] } for row in self.todolist_api.get_todolists( todolist_id=todo.todolist_id) for status in row['status_changes']], [ { 'label': 'List 7', 'description': 'This is List 7', 'priority': 'veryhigh', 'status': 'active', 'saved_status': 'active', 'changed_by': 'Test User 1' }, ]) self.todolist_api.update_todolist(todo.todolist_id, {'status': 'inactive'}) self.assertEqual([{ 'label': row['label'], 'description': row['description'], 'priority': row['priority'], 'status': row['status'], 'saved_status': status['status'], 'changed_by': status['changed_by'] } for row in self.todolist_api.get_todolists( todolist_id=todo.todolist_id) for status in row['status_changes']], [ { 'label': 'List 7', 'description': 'This is List 7', 'priority': 'veryhigh', 'status': 'inactive', 'saved_status': 'inactive', 'changed_by': 'Test User 1' }, { 'label': 'List 7', 'description': 'This is List 7', 'priority': 'veryhigh', 'status': 'inactive', 'saved_status': 'active', 'changed_by': 'Test User 1' }, ]) def test_delete_todo_lists(self): self.create_todolist_set() todo = db.session.query(TodoListTbl).filter_by(label='List 3').first() self.assertEqual([{ 'label': row['label'], 'description': row['description'], 'priority': row['priority'], 'status': row['status'], 'saved_status': status['status'], 'changed_by': status['changed_by'] } for row in self.todolist_api.get_todolists( todolist_id=todo.todolist_id) for status in row['status_changes']], [ { 'label': 'List 3', 'description': None, 'priority': 'medium', 'status': 'active', 'saved_status': 'active', 'changed_by': 'Test User 1' }, ]) self.assertEqual(self.todolist_api.delete_todolist(todo.todolist_id), True) self.assertEqual( list( self.todolist_api.get_todolists(todolist_id=todo.todolist_id)), []) def test_permissions_todo_lists(self): self.create_todolist_set() user2 = UserTbl(user_id=str(uuid4()), login='******', password='******', name='Test User 2', email='*****@*****.**', created=datetime.utcnow()) db.session.add(user2) user3 = UserTbl(user_id=str(uuid4()), login='******', password='******', name='Test User 3', email='*****@*****.**', created=datetime.utcnow()) db.session.add(user3) db.session.commit() todo = db.session.query(TodoListTbl).filter_by(label='List 3').first() self.assertEqual([{ 'login': row['login'], 'role': row['role'] } for row in todo.all_roles], [{ 'login': '******', 'role': 'owner' }]) self.assertEqual( self.todolist_api.permissions(todo.todolist_id, self.user.user_id), None) # add permissions for user2 and user3 self.todolist_api.permissions(todo.todolist_id, user2.user_id, 'admin') self.todolist_api.permissions(todo.todolist_id, user3.user_id, 'reader') self.assertEqual([{ 'login': row['login'], 'role': row['role'] } for row in todo.all_roles], [{ 'login': '******', 'role': 'owner' }, { 'login': '******', 'role': 'admin' }, { 'login': '******', 'role': 'reader' }]) # remove permission for user 2 self.todolist_api.permissions(todo.todolist_id, user2.user_id) self.assertEqual([{ 'login': row['login'], 'role': row['role'] } for row in todo.all_roles], [{ 'login': '******', 'role': 'owner' }, { 'login': '******', 'role': 'reader' }]) # changed owner from user1 to user 3 self.todolist_api.permissions(todo.todolist_id, user3.user_id, 'owner') self.assertEqual([{ 'login': row['login'], 'role': row['role'] } for row in todo.all_roles], [{ 'login': '******', 'role': 'owner' }]) # changed owner from user3 to user 1 and set the previous owner role to reader todolist_api_user3 = TodoListApi(user3.user_id) todolist_api_user3.permissions(todo.todolist_id, self.user.user_id, 'owner', 'reader') self.assertEqual([{ 'login': row['login'], 'role': row['role'] } for row in todo.all_roles], [{ 'login': '******', 'role': 'owner' }, { 'login': '******', 'role': 'reader' }])
def test_permissions_todo_lists(self): self.create_todolist_set() user2 = UserTbl(user_id=str(uuid4()), login='******', password='******', name='Test User 2', email='*****@*****.**', created=datetime.utcnow()) db.session.add(user2) user3 = UserTbl(user_id=str(uuid4()), login='******', password='******', name='Test User 3', email='*****@*****.**', created=datetime.utcnow()) db.session.add(user3) db.session.commit() todo = db.session.query(TodoListTbl).filter_by(label='List 3').first() self.assertEqual([{ 'login': row['login'], 'role': row['role'] } for row in todo.all_roles], [{ 'login': '******', 'role': 'owner' }]) self.assertEqual( self.todolist_api.permissions(todo.todolist_id, self.user.user_id), None) # add permissions for user2 and user3 self.todolist_api.permissions(todo.todolist_id, user2.user_id, 'admin') self.todolist_api.permissions(todo.todolist_id, user3.user_id, 'reader') self.assertEqual([{ 'login': row['login'], 'role': row['role'] } for row in todo.all_roles], [{ 'login': '******', 'role': 'owner' }, { 'login': '******', 'role': 'admin' }, { 'login': '******', 'role': 'reader' }]) # remove permission for user 2 self.todolist_api.permissions(todo.todolist_id, user2.user_id) self.assertEqual([{ 'login': row['login'], 'role': row['role'] } for row in todo.all_roles], [{ 'login': '******', 'role': 'owner' }, { 'login': '******', 'role': 'reader' }]) # changed owner from user1 to user 3 self.todolist_api.permissions(todo.todolist_id, user3.user_id, 'owner') self.assertEqual([{ 'login': row['login'], 'role': row['role'] } for row in todo.all_roles], [{ 'login': '******', 'role': 'owner' }]) # changed owner from user3 to user 1 and set the previous owner role to reader todolist_api_user3 = TodoListApi(user3.user_id) todolist_api_user3.permissions(todo.todolist_id, self.user.user_id, 'owner', 'reader') self.assertEqual([{ 'login': row['login'], 'role': row['role'] } for row in todo.all_roles], [{ 'login': '******', 'role': 'owner' }, { 'login': '******', 'role': 'reader' }])