Loading Pipfile +1 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ python-dotenv = "*" pyyaml = "*" muni-is-api = {editable = true,git = "https://git@gitlab.fi.muni.cz/grp-kontr2/is-api.git"} authlib = "*" pip = "*" [dev-packages] pylint = "*" Loading portal/__init__.py +3 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ from portal import logger, rest from portal.config import CONFIGURATIONS from portal.logger import Logging from portal.tools.gitlab_client import GitlabFactory from portal.tools.is_api_adapter import IsApiFactory from portal.tools.ldap_client import LDAPWrapper from portal.tools.paths import ROOT_DIR Loading @@ -29,7 +30,7 @@ storage = Storage() migrate = Migrate(db=db) gitlab_factory = GitlabFactory() ldap_wrapper = LDAPWrapper() is_api_factory = IsApiFactory() log = logger.get_logger(__name__) Loading Loading @@ -104,6 +105,7 @@ def configure_extensions(app: Flask): cors.init_app(app) gitlab_factory.init_app(app) ldap_wrapper.init_app(app) is_api_factory.init_app(app) return app Loading portal/database/models.py +1 −3 Original line number Diff line number Diff line Loading @@ -11,7 +11,6 @@ from flask_sqlalchemy import BaseQuery from sqlalchemy import event from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.sql.base import ImmutableColumnCollection from werkzeug.security import check_password_hash, generate_password_hash from portal import db Loading Loading @@ -357,7 +356,6 @@ class Course(db.Model, EntityBase, NamedMixin): uuid.uuid4()), primary_key=True) notes_access_token = db.Column(db.String(256)) faculty_id = db.Column(db.Integer) roles = db.relationship("Role", back_populates="course", cascade="all, delete-orphan", passive_deletes=True) groups = db.relationship("Group", back_populates="course", cascade="all, delete-orphan", Loading portal/rest/users.py +21 −0 Original line number Diff line number Diff line Loading @@ -229,6 +229,27 @@ class UserEffectivePermissions(CustomResource): return perm @users_namespace.route('/<string:uid>/is_notes') @users_namespace.param('uid', "User's id") @users_namespace.response(404, 'User not found') class UserNotes(CustomResource): @jwt_required @users_namespace.response(200, 'Effective permissions') def get(self, uid: str): user = self.find.user(uid) course_id = request.args.get('course') project_id = request.args.get('project') course = self.find.course(course_id) project = self.find.project(course, project_id) # authorization log.debug(f"[REST] Get user notes for project {project.log_name}" f" for {user.log_name} by {self.client.log_name} in course={course_id}") self.permissions().require.sysadmin_or_self(uid) perm = self.permissions(client=user).get_effective_permissions(course_id) return perm # # Helper functions # Loading portal/service/errors.py +8 −2 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ Errors in the service layer import json from typing import Union from portal.database import Project, User from portal.database import Course, Project, User from portal.tools import time Loading Loading @@ -183,3 +183,9 @@ class ResultsAreNotUploaded(PortalAPIError): def __init__(self, submission): message = f"Submission {submission.log_name} results are not ready." super().__init__(code=404, message=message) class AccessTokenForCourseMissingError(PortalServiceError): def __init__(self, course: Course): message = f"Course's {course.log_name} is api access token has not been set." super().__init__(message=message) Loading
Pipfile +1 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ python-dotenv = "*" pyyaml = "*" muni-is-api = {editable = true,git = "https://git@gitlab.fi.muni.cz/grp-kontr2/is-api.git"} authlib = "*" pip = "*" [dev-packages] pylint = "*" Loading
portal/__init__.py +3 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ from portal import logger, rest from portal.config import CONFIGURATIONS from portal.logger import Logging from portal.tools.gitlab_client import GitlabFactory from portal.tools.is_api_adapter import IsApiFactory from portal.tools.ldap_client import LDAPWrapper from portal.tools.paths import ROOT_DIR Loading @@ -29,7 +30,7 @@ storage = Storage() migrate = Migrate(db=db) gitlab_factory = GitlabFactory() ldap_wrapper = LDAPWrapper() is_api_factory = IsApiFactory() log = logger.get_logger(__name__) Loading Loading @@ -104,6 +105,7 @@ def configure_extensions(app: Flask): cors.init_app(app) gitlab_factory.init_app(app) ldap_wrapper.init_app(app) is_api_factory.init_app(app) return app Loading
portal/database/models.py +1 −3 Original line number Diff line number Diff line Loading @@ -11,7 +11,6 @@ from flask_sqlalchemy import BaseQuery from sqlalchemy import event from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.sql.base import ImmutableColumnCollection from werkzeug.security import check_password_hash, generate_password_hash from portal import db Loading Loading @@ -357,7 +356,6 @@ class Course(db.Model, EntityBase, NamedMixin): uuid.uuid4()), primary_key=True) notes_access_token = db.Column(db.String(256)) faculty_id = db.Column(db.Integer) roles = db.relationship("Role", back_populates="course", cascade="all, delete-orphan", passive_deletes=True) groups = db.relationship("Group", back_populates="course", cascade="all, delete-orphan", Loading
portal/rest/users.py +21 −0 Original line number Diff line number Diff line Loading @@ -229,6 +229,27 @@ class UserEffectivePermissions(CustomResource): return perm @users_namespace.route('/<string:uid>/is_notes') @users_namespace.param('uid', "User's id") @users_namespace.response(404, 'User not found') class UserNotes(CustomResource): @jwt_required @users_namespace.response(200, 'Effective permissions') def get(self, uid: str): user = self.find.user(uid) course_id = request.args.get('course') project_id = request.args.get('project') course = self.find.course(course_id) project = self.find.project(course, project_id) # authorization log.debug(f"[REST] Get user notes for project {project.log_name}" f" for {user.log_name} by {self.client.log_name} in course={course_id}") self.permissions().require.sysadmin_or_self(uid) perm = self.permissions(client=user).get_effective_permissions(course_id) return perm # # Helper functions # Loading
portal/service/errors.py +8 −2 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ Errors in the service layer import json from typing import Union from portal.database import Project, User from portal.database import Course, Project, User from portal.tools import time Loading Loading @@ -183,3 +183,9 @@ class ResultsAreNotUploaded(PortalAPIError): def __init__(self, submission): message = f"Submission {submission.log_name} results are not ready." super().__init__(code=404, message=message) class AccessTokenForCourseMissingError(PortalServiceError): def __init__(self, course: Course): message = f"Course's {course.log_name} is api access token has not been set." super().__init__(message=message)