Loading portal/rest/schemas.py +20 −14 Original line number Original line Diff line number Diff line Loading @@ -8,7 +8,13 @@ Schemas used to serialize/deserialize and validate of the models in the DB """ """ class UserSchema(Schema): class BaseSchema(object): id = fields.Str(dump_only=True, required=True) created_at = fields.LocalDateTime() updated_at = fields.LocalDateTime() class UserSchema(BaseSchema, Schema): """User schema """User schema """ """ id = fields.Str(dump_only=True, required=True) id = fields.Str(dump_only=True, required=True) Loading @@ -32,7 +38,7 @@ class PasswordChangeSchema(Schema): new_password = fields.String(required=True) new_password = fields.String(required=True) class CourseSchema(Schema): class CourseSchema(BaseSchema, Schema): """Course Schema """Course Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading Loading @@ -85,7 +91,7 @@ class SubmissionCreateSchema(Schema): project_params = fields.Dict() project_params = fields.Dict() class ProjectSchema(Schema): class ProjectSchema(BaseSchema, Schema): """Project Schema """Project Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading @@ -101,7 +107,7 @@ class ProjectSchema(Schema): groups = fields.Nested('portal.rest.schemas.GroupSchema', many=True, only=('id', 'name')) groups = fields.Nested('portal.rest.schemas.GroupSchema', many=True, only=('id', 'name')) class ProjectConfigSchema(Schema): class ProjectConfigSchema(BaseSchema, Schema): """Project config Schema """Project config Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading @@ -117,7 +123,7 @@ class ProjectConfigSchema(Schema): archive_from = fields.LocalDateTime() archive_from = fields.LocalDateTime() class RoleSchema(Schema): class RoleSchema(BaseSchema, Schema): """Role Schema """Role Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading @@ -129,7 +135,7 @@ class RoleSchema(Schema): permissions = fields.Nested('portal.rest.schemas.RolePermissionsSchema') permissions = fields.Nested('portal.rest.schemas.RolePermissionsSchema') class RolePermissionsSchema(Schema): class RolePermissionsSchema(BaseSchema, Schema): """Role Permissions Schema """Role Permissions Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading Loading @@ -168,7 +174,7 @@ class RolePermissionsSchema(Schema): write_reviews_own = fields.Bool() write_reviews_own = fields.Bool() class GroupSchema(Schema): class GroupSchema(BaseSchema, Schema): """Group Schema """Group Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading @@ -178,7 +184,7 @@ class GroupSchema(Schema): projects = fields.Nested(ProjectSchema, only=('id', 'name'), many=True) projects = fields.Nested(ProjectSchema, only=('id', 'name'), many=True) class SubmissionSchema(Schema): class SubmissionSchema(BaseSchema, Schema): """Submission Schema """Submission Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading @@ -190,7 +196,7 @@ class SubmissionSchema(Schema): user = fields.Nested(UserSchema, only=('id', 'username', 'uco', 'name', 'email')) user = fields.Nested(UserSchema, only=('id', 'username', 'uco', 'name', 'email')) class ReviewSchema(Schema): class ReviewSchema(BaseSchema, Schema): """Review Schema """Review Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading @@ -198,7 +204,7 @@ class ReviewSchema(Schema): review_items = fields.Nested('portal.rest.schemas.ReviewItemSchema', many=True) review_items = fields.Nested('portal.rest.schemas.ReviewItemSchema', many=True) class ReviewItemSchema(Schema): class ReviewItemSchema(BaseSchema, Schema): """Review Item Schema """Review Item Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading @@ -209,7 +215,7 @@ class ReviewItemSchema(Schema): user = fields.Nested(UserSchema, only=('id', 'uco', 'email', 'username')) user = fields.Nested(UserSchema, only=('id', 'uco', 'email', 'username')) class ComponentSchema(Schema): class ComponentSchema(BaseSchema, Schema): """Component Schema """Component Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading Loading @@ -289,7 +295,7 @@ users_schema = UserSchema(many=True, only=('id', 'username', 'uco', 'email')) password_change_schema = PasswordChangeSchema() password_change_schema = PasswordChangeSchema() submission_schema = SubmissionSchema() submission_schema = SubmissionSchema() submissions_schema = SubmissionSchema(many=True, submissions_schema = SubmissionSchema(many=True, only=('id', 'state', 'project', 'scheduled_for', 'user')) only=('id', 'state', 'project', 'scheduled_for', 'user', 'created_at', 'updated_at')) submission_create_schema = SubmissionCreateSchema() submission_create_schema = SubmissionCreateSchema() submission_state_schema = SubmissionSchema(only=('state',)) submission_state_schema = SubmissionSchema(only=('state',)) reviews_schema = ReviewSchema(many=True) reviews_schema = ReviewSchema(many=True) Loading portal/rest/users/users.py +22 −12 Original line number Original line Diff line number Diff line Loading @@ -7,12 +7,13 @@ from flask_restful import Api, Resource import portal.service.auth import portal.service.auth import portal.service.general import portal.service.general import portal.service.users import portal.service.users from portal.database.models import User from portal.rest import rest_helpers from portal.rest import rest_helpers from portal.rest.schemas import user_schema, user_schema_reduced, users_schema, \ from portal.rest.schemas import user_schema, user_schema_reduced, users_schema, \ password_change_schema, submissions_schema, reviews_schema, roles_schema, courses_schema, \ password_change_schema, submissions_schema, reviews_schema, roles_schema, courses_schema, \ groups_schema groups_schema from portal.service.errors import PortalAPIError, ForbiddenError from portal.service.errors import PortalAPIError, ForbiddenError from portal.service import permissions from portal.service import permissions, general from portal.service.auth import find_client from portal.service.auth import find_client from portal.service.users import find_users_filtered, find_groups_filtered, find_roles_filtered, \ from portal.service.users import find_users_filtered, find_groups_filtered, find_roles_filtered, \ find_reviews, find_submissions_filtered, create_user, update_user, delete_user, \ find_reviews, find_submissions_filtered, create_user, update_user, delete_user, \ Loading Loading @@ -125,30 +126,39 @@ class UserList(Resource): class UserSubmissionList(Resource): class UserSubmissionList(Resource): @staticmethod def find_groups_intersection(user1: User, user2: User): temp = set(user2.groups) res = [value for value in user1.groups if value in temp] return res # needs more tests # needs more tests @error_handler @error_handler @jwt_required @jwt_required def get(self, uid): def get(self, uid): client = portal.service.auth.find_client() client = portal.service.auth.find_client() user = portal.service.general.find_user(uid) user = portal.service.general.find_user(uid) # authorization if not (permissions.check_component(component=client) or permissions.check_sysadmin(client) or client == user): raise ForbiddenError(uid=client.id) course_id = request.args.get('course') course_id = request.args.get('course') project_ids = request.args.getlist('project') # musi brat zoznam projektov project_ids = request.args.getlist('project') course = general.find_course(course_id) if project_ids and not course_id: if project_ids and not course_id: raise PortalAPIError(400, raise PortalAPIError(400, f"Invalid filter combination at " f"Invalid filter combination at " f"/get/users/{uid}/submissions: missing course id.") f"/get/users/{uid}/submissions: missing course id.") # authorization if permissions.check_component(component=client) \ or permissions.check_sysadmin(client) \ or permissions.check_user(client, course, ['read_submissions_all']) \ or (permissions.check_user(client, course, ['read_submissions_groups'] and self.find_groups_intersection(client, user))) \ or (permissions.check_user(client, course, ['read_submissions_own']) and client == user): submissions = find_submissions_filtered(user=user, course_id=course_id, submissions = find_submissions_filtered(user=user, course_id=course_id, project_ids=project_ids) project_ids=project_ids) return submissions_schema.dump(submissions)[0], 200 return submissions_schema.dump(submissions)[0], 200 raise ForbiddenError(uid=client.id) class UserRoleList(Resource): class UserRoleList(Resource): @error_handler @error_handler Loading Loading
portal/rest/schemas.py +20 −14 Original line number Original line Diff line number Diff line Loading @@ -8,7 +8,13 @@ Schemas used to serialize/deserialize and validate of the models in the DB """ """ class UserSchema(Schema): class BaseSchema(object): id = fields.Str(dump_only=True, required=True) created_at = fields.LocalDateTime() updated_at = fields.LocalDateTime() class UserSchema(BaseSchema, Schema): """User schema """User schema """ """ id = fields.Str(dump_only=True, required=True) id = fields.Str(dump_only=True, required=True) Loading @@ -32,7 +38,7 @@ class PasswordChangeSchema(Schema): new_password = fields.String(required=True) new_password = fields.String(required=True) class CourseSchema(Schema): class CourseSchema(BaseSchema, Schema): """Course Schema """Course Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading Loading @@ -85,7 +91,7 @@ class SubmissionCreateSchema(Schema): project_params = fields.Dict() project_params = fields.Dict() class ProjectSchema(Schema): class ProjectSchema(BaseSchema, Schema): """Project Schema """Project Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading @@ -101,7 +107,7 @@ class ProjectSchema(Schema): groups = fields.Nested('portal.rest.schemas.GroupSchema', many=True, only=('id', 'name')) groups = fields.Nested('portal.rest.schemas.GroupSchema', many=True, only=('id', 'name')) class ProjectConfigSchema(Schema): class ProjectConfigSchema(BaseSchema, Schema): """Project config Schema """Project config Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading @@ -117,7 +123,7 @@ class ProjectConfigSchema(Schema): archive_from = fields.LocalDateTime() archive_from = fields.LocalDateTime() class RoleSchema(Schema): class RoleSchema(BaseSchema, Schema): """Role Schema """Role Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading @@ -129,7 +135,7 @@ class RoleSchema(Schema): permissions = fields.Nested('portal.rest.schemas.RolePermissionsSchema') permissions = fields.Nested('portal.rest.schemas.RolePermissionsSchema') class RolePermissionsSchema(Schema): class RolePermissionsSchema(BaseSchema, Schema): """Role Permissions Schema """Role Permissions Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading Loading @@ -168,7 +174,7 @@ class RolePermissionsSchema(Schema): write_reviews_own = fields.Bool() write_reviews_own = fields.Bool() class GroupSchema(Schema): class GroupSchema(BaseSchema, Schema): """Group Schema """Group Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading @@ -178,7 +184,7 @@ class GroupSchema(Schema): projects = fields.Nested(ProjectSchema, only=('id', 'name'), many=True) projects = fields.Nested(ProjectSchema, only=('id', 'name'), many=True) class SubmissionSchema(Schema): class SubmissionSchema(BaseSchema, Schema): """Submission Schema """Submission Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading @@ -190,7 +196,7 @@ class SubmissionSchema(Schema): user = fields.Nested(UserSchema, only=('id', 'username', 'uco', 'name', 'email')) user = fields.Nested(UserSchema, only=('id', 'username', 'uco', 'name', 'email')) class ReviewSchema(Schema): class ReviewSchema(BaseSchema, Schema): """Review Schema """Review Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading @@ -198,7 +204,7 @@ class ReviewSchema(Schema): review_items = fields.Nested('portal.rest.schemas.ReviewItemSchema', many=True) review_items = fields.Nested('portal.rest.schemas.ReviewItemSchema', many=True) class ReviewItemSchema(Schema): class ReviewItemSchema(BaseSchema, Schema): """Review Item Schema """Review Item Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading @@ -209,7 +215,7 @@ class ReviewItemSchema(Schema): user = fields.Nested(UserSchema, only=('id', 'uco', 'email', 'username')) user = fields.Nested(UserSchema, only=('id', 'uco', 'email', 'username')) class ComponentSchema(Schema): class ComponentSchema(BaseSchema, Schema): """Component Schema """Component Schema """ """ id = fields.Str(dump_only=True) id = fields.Str(dump_only=True) Loading Loading @@ -289,7 +295,7 @@ users_schema = UserSchema(many=True, only=('id', 'username', 'uco', 'email')) password_change_schema = PasswordChangeSchema() password_change_schema = PasswordChangeSchema() submission_schema = SubmissionSchema() submission_schema = SubmissionSchema() submissions_schema = SubmissionSchema(many=True, submissions_schema = SubmissionSchema(many=True, only=('id', 'state', 'project', 'scheduled_for', 'user')) only=('id', 'state', 'project', 'scheduled_for', 'user', 'created_at', 'updated_at')) submission_create_schema = SubmissionCreateSchema() submission_create_schema = SubmissionCreateSchema() submission_state_schema = SubmissionSchema(only=('state',)) submission_state_schema = SubmissionSchema(only=('state',)) reviews_schema = ReviewSchema(many=True) reviews_schema = ReviewSchema(many=True) Loading
portal/rest/users/users.py +22 −12 Original line number Original line Diff line number Diff line Loading @@ -7,12 +7,13 @@ from flask_restful import Api, Resource import portal.service.auth import portal.service.auth import portal.service.general import portal.service.general import portal.service.users import portal.service.users from portal.database.models import User from portal.rest import rest_helpers from portal.rest import rest_helpers from portal.rest.schemas import user_schema, user_schema_reduced, users_schema, \ from portal.rest.schemas import user_schema, user_schema_reduced, users_schema, \ password_change_schema, submissions_schema, reviews_schema, roles_schema, courses_schema, \ password_change_schema, submissions_schema, reviews_schema, roles_schema, courses_schema, \ groups_schema groups_schema from portal.service.errors import PortalAPIError, ForbiddenError from portal.service.errors import PortalAPIError, ForbiddenError from portal.service import permissions from portal.service import permissions, general from portal.service.auth import find_client from portal.service.auth import find_client from portal.service.users import find_users_filtered, find_groups_filtered, find_roles_filtered, \ from portal.service.users import find_users_filtered, find_groups_filtered, find_roles_filtered, \ find_reviews, find_submissions_filtered, create_user, update_user, delete_user, \ find_reviews, find_submissions_filtered, create_user, update_user, delete_user, \ Loading Loading @@ -125,30 +126,39 @@ class UserList(Resource): class UserSubmissionList(Resource): class UserSubmissionList(Resource): @staticmethod def find_groups_intersection(user1: User, user2: User): temp = set(user2.groups) res = [value for value in user1.groups if value in temp] return res # needs more tests # needs more tests @error_handler @error_handler @jwt_required @jwt_required def get(self, uid): def get(self, uid): client = portal.service.auth.find_client() client = portal.service.auth.find_client() user = portal.service.general.find_user(uid) user = portal.service.general.find_user(uid) # authorization if not (permissions.check_component(component=client) or permissions.check_sysadmin(client) or client == user): raise ForbiddenError(uid=client.id) course_id = request.args.get('course') course_id = request.args.get('course') project_ids = request.args.getlist('project') # musi brat zoznam projektov project_ids = request.args.getlist('project') course = general.find_course(course_id) if project_ids and not course_id: if project_ids and not course_id: raise PortalAPIError(400, raise PortalAPIError(400, f"Invalid filter combination at " f"Invalid filter combination at " f"/get/users/{uid}/submissions: missing course id.") f"/get/users/{uid}/submissions: missing course id.") # authorization if permissions.check_component(component=client) \ or permissions.check_sysadmin(client) \ or permissions.check_user(client, course, ['read_submissions_all']) \ or (permissions.check_user(client, course, ['read_submissions_groups'] and self.find_groups_intersection(client, user))) \ or (permissions.check_user(client, course, ['read_submissions_own']) and client == user): submissions = find_submissions_filtered(user=user, course_id=course_id, submissions = find_submissions_filtered(user=user, course_id=course_id, project_ids=project_ids) project_ids=project_ids) return submissions_schema.dump(submissions)[0], 200 return submissions_schema.dump(submissions)[0], 200 raise ForbiddenError(uid=client.id) class UserRoleList(Resource): class UserRoleList(Resource): @error_handler @error_handler Loading