From 42c99f3939f93fe1ee6dcbd9a5a8c0da6cce33f5 Mon Sep 17 00:00:00 2001 From: swve Date: Thu, 20 Jul 2023 01:42:20 +0200 Subject: [PATCH] feat: additional verification for anon users --- src/security/rbac/rbac.py | 9 ++++++++- src/services/courses/activities/activities.py | 5 +++++ src/services/courses/chapters.py | 5 +++++ src/services/courses/collections.py | 4 +++- src/services/courses/courses.py | 3 +++ src/services/orgs/orgs.py | 7 ++++++- src/services/roles/roles.py | 3 +++ src/services/users/schemas/users.py | 3 +++ src/services/users/users.py | 11 ++++++++++- 9 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/security/rbac/rbac.py b/src/security/rbac/rbac.py index 8f131cca..fbd81bd1 100644 --- a/src/security/rbac/rbac.py +++ b/src/security/rbac/rbac.py @@ -79,7 +79,6 @@ async def authorization_verify_based_on_roles( element_id: str, ): element_type = await check_element_type(element_id) - print(element_type) element = request.app.db[element_type] roles = request.app.db["roles"] @@ -125,3 +124,11 @@ async def authorization_verify_based_on_roles_and_authorship( status_code=status.HTTP_403_FORBIDDEN, detail="User rights (roles & authorship) : You don't have the right to perform this action", ) + + +async def authorization_verify_if_user_is_anon(user_id: str): + if user_id == "anonymous": + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="You should be logged in to perform this action", + ) diff --git a/src/services/courses/activities/activities.py b/src/services/courses/activities/activities.py index 9551518d..8a8a0aa3 100644 --- a/src/services/courses/activities/activities.py +++ b/src/services/courses/activities/activities.py @@ -3,6 +3,7 @@ from pydantic import BaseModel from src.security.rbac.rbac import ( authorization_verify_based_on_roles, authorization_verify_if_element_is_public, + authorization_verify_if_user_is_anon, ) from src.services.users.schemas.users import AnonymousUser, PublicUser from fastapi import HTTPException, status, Request @@ -214,6 +215,8 @@ async def verify_rights( users = request.app.db["users"] user = await users.find_one({"user_id": current_user.user_id}) + await authorization_verify_if_user_is_anon(current_user.user_id) + await authorization_verify_based_on_roles( request, current_user.user_id, @@ -225,6 +228,8 @@ async def verify_rights( users = request.app.db["users"] user = await users.find_one({"user_id": current_user.user_id}) + await authorization_verify_if_user_is_anon(current_user.user_id) + await authorization_verify_based_on_roles( request, current_user.user_id, diff --git a/src/services/courses/chapters.py b/src/services/courses/chapters.py index ea35905d..470730f8 100644 --- a/src/services/courses/chapters.py +++ b/src/services/courses/chapters.py @@ -7,6 +7,7 @@ from src.security.rbac.rbac import ( authorization_verify_based_on_roles, authorization_verify_based_on_roles_and_authorship, authorization_verify_if_element_is_public, + authorization_verify_if_user_is_anon, ) from src.services.courses.courses import Course from src.services.courses.activities.activities import ActivityInDB @@ -323,6 +324,8 @@ async def verify_rights( users = request.app.db["users"] user = await users.find_one({"user_id": current_user.user_id}) + await authorization_verify_if_user_is_anon(current_user.user_id) + await authorization_verify_based_on_roles_and_authorship( request, current_user.user_id, @@ -333,6 +336,8 @@ async def verify_rights( else: users = request.app.db["users"] user = await users.find_one({"user_id": current_user.user_id}) + + await authorization_verify_if_user_is_anon(current_user.user_id) await authorization_verify_based_on_roles_and_authorship( request, diff --git a/src/services/courses/collections.py b/src/services/courses/collections.py index dbbf9be1..3829e079 100644 --- a/src/services/courses/collections.py +++ b/src/services/courses/collections.py @@ -1,7 +1,7 @@ from typing import List, Literal from uuid import uuid4 from pydantic import BaseModel -from src.security.rbac.rbac import authorization_verify_based_on_roles_and_authorship +from src.security.rbac.rbac import authorization_verify_based_on_roles_and_authorship, authorization_verify_if_user_is_anon from src.services.users.users import PublicUser from fastapi import HTTPException, status, Request @@ -233,6 +233,8 @@ async def verify_collection_rights( if current_user.user_id == "anonymous" and action == "read": return True + await authorization_verify_if_user_is_anon(current_user.user_id) + await authorization_verify_based_on_roles_and_authorship( request, current_user.user_id, action, user["roles"], collection_id ) diff --git a/src/services/courses/courses.py b/src/services/courses/courses.py index eb72b881..86841d26 100644 --- a/src/services/courses/courses.py +++ b/src/services/courses/courses.py @@ -6,6 +6,7 @@ from src.security.rbac.rbac import ( authorization_verify_based_on_roles, authorization_verify_based_on_roles_and_authorship, authorization_verify_if_element_is_public, + authorization_verify_if_user_is_anon, ) from src.services.courses.activities.activities import ActivityInDB from src.services.courses.thumbnails import upload_thumbnail @@ -398,6 +399,8 @@ async def verify_rights( users = request.app.db["users"] user = await users.find_one({"user_id": current_user.user_id}) + await authorization_verify_if_user_is_anon(current_user.user_id) + await authorization_verify_based_on_roles_and_authorship( request, current_user.user_id, diff --git a/src/services/orgs/orgs.py b/src/services/orgs/orgs.py index 17913554..57bbd437 100644 --- a/src/services/orgs/orgs.py +++ b/src/services/orgs/orgs.py @@ -1,7 +1,10 @@ import json from typing import Literal from uuid import uuid4 -from src.security.rbac.rbac import authorization_verify_based_on_roles +from src.security.rbac.rbac import ( + authorization_verify_based_on_roles, + authorization_verify_if_user_is_anon, +) from src.services.orgs.logos import upload_org_logo from src.services.orgs.schemas.orgs import ( Organization, @@ -212,6 +215,8 @@ async def verify_org_rights( status_code=status.HTTP_409_CONFLICT, detail="Organization does not exist" ) + await authorization_verify_if_user_is_anon(current_user.user_id) + await authorization_verify_based_on_roles( request, current_user.user_id, action, user["roles"], org_id ) diff --git a/src/services/roles/roles.py b/src/services/roles/roles.py index 2ef3ee34..cc61c452 100644 --- a/src/services/roles/roles.py +++ b/src/services/roles/roles.py @@ -1,5 +1,6 @@ from typing import Literal from uuid import uuid4 +from src.security.rbac.rbac import authorization_verify_if_user_is_anon from src.services.roles.schemas.roles import Role, RoleInDB from src.services.users.schemas.users import PublicUser from fastapi import HTTPException, status, Request @@ -85,6 +86,8 @@ async def verify_user_permissions_on_roles( status_code=status.HTTP_401_UNAUTHORIZED, detail="Roles : Not authenticated" ) + await authorization_verify_if_user_is_anon(current_user.user_id) + if action == "create": if "owner" in [org.org_role for org in current_user.orgs]: return True diff --git a/src/services/users/schemas/users.py b/src/services/users/schemas/users.py index 940ec703..2dea0e97 100644 --- a/src/services/users/schemas/users.py +++ b/src/services/users/schemas/users.py @@ -57,6 +57,9 @@ class PublicUser(User): class AnonymousUser(BaseModel): user_id: str = "anonymous" username: str = "anonymous" + roles: list[UserRolesInOrganization] = [ + UserRolesInOrganization(org_id="anonymous", role_id="role_anonymous") + ] diff --git a/src/services/users/users.py b/src/services/users/users.py index 5e0e5745..da65b9fd 100644 --- a/src/services/users/users.py +++ b/src/services/users/users.py @@ -2,7 +2,7 @@ from datetime import datetime from typing import Literal from uuid import uuid4 from fastapi import HTTPException, Request, status -from src.security.rbac.rbac import authorization_verify_based_on_roles +from src.security.rbac.rbac import authorization_verify_based_on_roles, authorization_verify_if_user_is_anon from src.security.security import security_hash_password, security_verify_password from src.services.users.schemas.users import ( PasswordChangeForm, @@ -266,6 +266,9 @@ async def verify_user_rights_on_user( return True if action == "read": + + await authorization_verify_if_user_is_anon(current_user.user_id) + if current_user.user_id == user_id: return True @@ -276,6 +279,9 @@ async def verify_user_rights_on_user( return False if action == "update": + + await authorization_verify_if_user_is_anon(current_user.user_id) + if current_user.user_id == user_id: return True @@ -291,6 +297,9 @@ async def verify_user_rights_on_user( return False if action == "delete": + + await authorization_verify_if_user_is_anon(current_user.user_id) + if current_user.user_id == user_id: return True