mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
Merge pull request #135 from learnhouse/fix/post-migration-bugs
Post Migration Bug Fixes
This commit is contained in:
commit
a7e2bda41e
44 changed files with 580 additions and 336 deletions
|
|
@ -3,6 +3,7 @@ from sqlmodel import Session, select
|
|||
from src.db.chapters import Chapter
|
||||
from src.security.rbac.rbac import (
|
||||
authorization_verify_based_on_roles_and_authorship,
|
||||
authorization_verify_if_element_is_public,
|
||||
authorization_verify_if_user_is_anon,
|
||||
)
|
||||
from src.db.activities import ActivityCreate, Activity, ActivityRead, ActivityUpdate
|
||||
|
|
@ -212,20 +213,33 @@ async def get_activities(
|
|||
|
||||
async def rbac_check(
|
||||
request: Request,
|
||||
course_id: str,
|
||||
course_uuid: str,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
action: Literal["create", "read", "update", "delete"],
|
||||
db_session: Session,
|
||||
):
|
||||
await authorization_verify_if_user_is_anon(current_user.id)
|
||||
if action == "read":
|
||||
if current_user.id == 0: # Anonymous user
|
||||
res = await authorization_verify_if_element_is_public(
|
||||
request, course_uuid, action, db_session
|
||||
)
|
||||
print('res',res)
|
||||
return res
|
||||
else:
|
||||
res = await authorization_verify_based_on_roles_and_authorship(
|
||||
request, current_user.id, action, course_uuid, db_session
|
||||
)
|
||||
return res
|
||||
else:
|
||||
await authorization_verify_if_user_is_anon(current_user.id)
|
||||
|
||||
await authorization_verify_based_on_roles_and_authorship(
|
||||
request,
|
||||
current_user.id,
|
||||
action,
|
||||
course_id,
|
||||
db_session,
|
||||
)
|
||||
await authorization_verify_based_on_roles_and_authorship(
|
||||
request,
|
||||
current_user.id,
|
||||
action,
|
||||
course_uuid,
|
||||
db_session,
|
||||
)
|
||||
|
||||
|
||||
## 🔒 RBAC Utils ##
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from sqlmodel import Session, select
|
|||
from src.db.users import AnonymousUser
|
||||
from src.security.rbac.rbac import (
|
||||
authorization_verify_based_on_roles_and_authorship,
|
||||
authorization_verify_if_element_is_public,
|
||||
authorization_verify_if_user_is_anon,
|
||||
)
|
||||
from src.db.course_chapters import CourseChapter
|
||||
|
|
@ -207,6 +208,10 @@ async def get_course_chapters(
|
|||
page: int = 1,
|
||||
limit: int = 10,
|
||||
) -> List[ChapterRead]:
|
||||
|
||||
statement = select(Course).where(Course.id == course_id)
|
||||
course = db_session.exec(statement).first()
|
||||
|
||||
statement = (
|
||||
select(Chapter)
|
||||
.join(CourseChapter, Chapter.id == CourseChapter.chapter_id)
|
||||
|
|
@ -220,7 +225,7 @@ async def get_course_chapters(
|
|||
chapters = [ChapterRead(**chapter.dict(), activities=[]) for chapter in chapters]
|
||||
|
||||
# RBAC check
|
||||
await rbac_check(request, "chapter_x", current_user, "read", db_session)
|
||||
await rbac_check(request, course.course_uuid, current_user, "read", db_session)
|
||||
|
||||
# Get activities for each chapter
|
||||
for chapter in chapters:
|
||||
|
|
@ -532,20 +537,33 @@ async def reorder_chapters_and_activities(
|
|||
|
||||
async def rbac_check(
|
||||
request: Request,
|
||||
course_id: str,
|
||||
course_uuid: str,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
action: Literal["create", "read", "update", "delete"],
|
||||
db_session: Session,
|
||||
):
|
||||
await authorization_verify_if_user_is_anon(current_user.id)
|
||||
if action == "read":
|
||||
if current_user.id == 0: # Anonymous user
|
||||
res = await authorization_verify_if_element_is_public(
|
||||
request, course_uuid, action, db_session
|
||||
)
|
||||
print('res',res)
|
||||
return res
|
||||
else:
|
||||
res = await authorization_verify_based_on_roles_and_authorship(
|
||||
request, current_user.id, action, course_uuid, db_session
|
||||
)
|
||||
return res
|
||||
else:
|
||||
await authorization_verify_if_user_is_anon(current_user.id)
|
||||
|
||||
await authorization_verify_based_on_roles_and_authorship(
|
||||
request,
|
||||
current_user.id,
|
||||
action,
|
||||
course_id,
|
||||
db_session,
|
||||
)
|
||||
await authorization_verify_based_on_roles_and_authorship(
|
||||
request,
|
||||
current_user.id,
|
||||
action,
|
||||
course_uuid,
|
||||
db_session,
|
||||
)
|
||||
|
||||
|
||||
## 🔒 RBAC Utils ##
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from sqlmodel import Session, select
|
|||
from src.db.users import AnonymousUser
|
||||
from src.security.rbac.rbac import (
|
||||
authorization_verify_based_on_roles_and_authorship,
|
||||
authorization_verify_if_element_is_public,
|
||||
authorization_verify_if_user_is_anon,
|
||||
)
|
||||
from src.db.collections import (
|
||||
|
|
@ -245,20 +246,34 @@ async def get_collections(
|
|||
|
||||
async def rbac_check(
|
||||
request: Request,
|
||||
course_id: str,
|
||||
collection_uuid: str,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
action: Literal["create", "read", "update", "delete"],
|
||||
db_session: Session,
|
||||
):
|
||||
await authorization_verify_if_user_is_anon(current_user.id)
|
||||
if action == "read":
|
||||
if current_user.id == 0: # Anonymous user
|
||||
res = await authorization_verify_if_element_is_public(
|
||||
request, collection_uuid, action, db_session
|
||||
)
|
||||
print('res',res)
|
||||
return res
|
||||
else:
|
||||
res = await authorization_verify_based_on_roles_and_authorship(
|
||||
request, current_user.id, action, collection_uuid, db_session
|
||||
)
|
||||
return res
|
||||
else:
|
||||
await authorization_verify_if_user_is_anon(current_user.id)
|
||||
|
||||
await authorization_verify_based_on_roles_and_authorship(
|
||||
request,
|
||||
current_user.id,
|
||||
action,
|
||||
course_id,
|
||||
db_session,
|
||||
)
|
||||
await authorization_verify_based_on_roles_and_authorship(
|
||||
request,
|
||||
current_user.id,
|
||||
action,
|
||||
collection_uuid,
|
||||
db_session,
|
||||
)
|
||||
|
||||
|
||||
## 🔒 RBAC Utils ##
|
||||
|
||||
|
|
|
|||
|
|
@ -96,11 +96,16 @@ async def get_course_meta(
|
|||
chapters = await get_course_chapters(request, course.id, db_session, current_user)
|
||||
|
||||
# Trail
|
||||
trail = await get_user_trail_with_orgid(
|
||||
request, current_user, course.org_id, db_session
|
||||
)
|
||||
trail = None
|
||||
|
||||
if isinstance(current_user, AnonymousUser):
|
||||
trail = None
|
||||
else:
|
||||
trail = await get_user_trail_with_orgid(
|
||||
request, current_user, course.org_id, db_session
|
||||
)
|
||||
trail = TrailRead.from_orm(trail)
|
||||
|
||||
trail = TrailRead.from_orm(trail)
|
||||
|
||||
return FullCourseReadWithTrail(
|
||||
**course.dict(),
|
||||
|
|
@ -359,7 +364,6 @@ async def get_courses_orgslug(
|
|||
|
||||
## 🔒 RBAC Utils ##
|
||||
|
||||
|
||||
async def rbac_check(
|
||||
request: Request,
|
||||
course_uuid: str,
|
||||
|
|
@ -369,13 +373,16 @@ async def rbac_check(
|
|||
):
|
||||
if action == "read":
|
||||
if current_user.id == 0: # Anonymous user
|
||||
await authorization_verify_if_element_is_public(
|
||||
res = await authorization_verify_if_element_is_public(
|
||||
request, course_uuid, action, db_session
|
||||
)
|
||||
print('res',res)
|
||||
return res
|
||||
else:
|
||||
await authorization_verify_based_on_roles_and_authorship(
|
||||
res = await authorization_verify_based_on_roles_and_authorship(
|
||||
request, current_user.id, action, course_uuid, db_session
|
||||
)
|
||||
return res
|
||||
else:
|
||||
await authorization_verify_if_user_is_anon(current_user.id)
|
||||
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ async def update_install_instance(
|
|||
|
||||
|
||||
# Install Default roles
|
||||
async def install_default_elements(request: Request, data: dict, db_session: Session):
|
||||
async def install_default_elements( data: dict, db_session: Session):
|
||||
# remove all default roles
|
||||
statement = select(Role).where(Role.role_type == RoleTypeEnum.TYPE_GLOBAL)
|
||||
roles = db_session.exec(statement).all()
|
||||
|
|
@ -279,7 +279,7 @@ async def install_default_elements(request: Request, data: dict, db_session: Ses
|
|||
|
||||
# Organization creation
|
||||
async def install_create_organization(
|
||||
request: Request, org_object: OrganizationCreate, db_session: Session
|
||||
org_object: OrganizationCreate, db_session: Session
|
||||
):
|
||||
org = Organization.from_orm(org_object)
|
||||
|
||||
|
|
@ -296,7 +296,7 @@ async def install_create_organization(
|
|||
|
||||
|
||||
async def install_create_organization_user(
|
||||
request: Request, user_object: UserCreate, org_slug: str, db_session: Session
|
||||
user_object: UserCreate, org_slug: str, db_session: Session
|
||||
):
|
||||
user = User.from_orm(user_object)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from src.db.courses import Course
|
|||
from src.db.trail_runs import TrailRun, TrailRunRead
|
||||
from src.db.trail_steps import TrailStep
|
||||
from src.db.trails import Trail, TrailCreate, TrailRead
|
||||
from src.db.users import PublicUser
|
||||
from src.db.users import AnonymousUser, PublicUser
|
||||
|
||||
|
||||
async def create_user_trail(
|
||||
|
|
@ -17,7 +17,7 @@ async def create_user_trail(
|
|||
trail_object: TrailCreate,
|
||||
db_session: Session,
|
||||
) -> Trail:
|
||||
statement = select(Trail).where(Trail.org_id == trail_object.org_id)
|
||||
statement = select(Trail).where(Trail.org_id == trail_object.org_id, Trail.user_id == user.id)
|
||||
trail = db_session.exec(statement).first()
|
||||
|
||||
if trail:
|
||||
|
|
@ -103,7 +103,7 @@ async def check_trail_presence(
|
|||
user: PublicUser,
|
||||
db_session: Session,
|
||||
):
|
||||
statement = select(Trail).where(Trail.org_id == org_id, Trail.user_id == user.id)
|
||||
statement = select(Trail).where(Trail.org_id == org_id, Trail.user_id == user_id)
|
||||
trail = db_session.exec(statement).first()
|
||||
|
||||
if not trail:
|
||||
|
|
@ -122,9 +122,15 @@ async def check_trail_presence(
|
|||
|
||||
|
||||
async def get_user_trail_with_orgid(
|
||||
request: Request, user: PublicUser, org_id: int, db_session: Session
|
||||
request: Request, user: PublicUser | AnonymousUser, org_id: int, db_session: Session
|
||||
) -> TrailRead:
|
||||
|
||||
if isinstance(user, AnonymousUser):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Anonymous users cannot access this endpoint",
|
||||
)
|
||||
|
||||
trail = await check_trail_presence(
|
||||
org_id=org_id,
|
||||
user_id=user.id,
|
||||
|
|
|
|||
|
|
@ -3,17 +3,20 @@ from typing import Literal
|
|||
from uuid import uuid4
|
||||
from fastapi import HTTPException, Request, status
|
||||
from sqlmodel import Session, select
|
||||
from src.db.roles import Role, RoleRead
|
||||
from src.security.rbac.rbac import (
|
||||
authorization_verify_based_on_roles_and_authorship,
|
||||
authorization_verify_if_user_is_anon,
|
||||
)
|
||||
from src.db.organizations import Organization
|
||||
from src.db.organizations import Organization, OrganizationRead
|
||||
from src.db.users import (
|
||||
AnonymousUser,
|
||||
PublicUser,
|
||||
User,
|
||||
UserCreate,
|
||||
UserRead,
|
||||
UserRoleWithOrg,
|
||||
UserSession,
|
||||
UserUpdate,
|
||||
UserUpdatePassword,
|
||||
)
|
||||
|
|
@ -279,6 +282,57 @@ async def read_user_by_uuid(
|
|||
return user
|
||||
|
||||
|
||||
async def get_user_session(
|
||||
request: Request,
|
||||
db_session: Session,
|
||||
current_user: PublicUser | AnonymousUser,
|
||||
) -> UserSession:
|
||||
# Get user
|
||||
statement = select(User).where(User.user_uuid == current_user.user_uuid)
|
||||
user = db_session.exec(statement).first()
|
||||
|
||||
if not user:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="User does not exist",
|
||||
)
|
||||
|
||||
user = UserRead.from_orm(user)
|
||||
|
||||
# Get roles and orgs
|
||||
statement = (
|
||||
select(UserOrganization)
|
||||
.where(UserOrganization.user_id == user.id)
|
||||
.join(Organization)
|
||||
)
|
||||
user_organizations = db_session.exec(statement).all()
|
||||
|
||||
roles = []
|
||||
|
||||
for user_organization in user_organizations:
|
||||
role_statement = select(Role).where(Role.id == user_organization.role_id)
|
||||
role = db_session.exec(role_statement).first()
|
||||
|
||||
org_statement = select(Organization).where(
|
||||
Organization.id == user_organization.org_id
|
||||
)
|
||||
org = db_session.exec(org_statement).first()
|
||||
|
||||
roles.append(
|
||||
UserRoleWithOrg(
|
||||
role=RoleRead.from_orm(role),
|
||||
org=OrganizationRead.from_orm(org),
|
||||
)
|
||||
)
|
||||
|
||||
user_session = UserSession(
|
||||
user=user,
|
||||
roles=roles,
|
||||
)
|
||||
|
||||
return user_session
|
||||
|
||||
|
||||
async def authorize_user_action(
|
||||
request: Request,
|
||||
db_session: Session,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue