mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
feat: implement comprehensive RBAC checks for courses, chapters, collections, and activities, enhancing user rights management and security documentation
This commit is contained in:
parent
887046203e
commit
3ce019abec
22 changed files with 1788 additions and 598 deletions
|
|
@ -4,7 +4,8 @@ from sqlmodel import Session, select, and_
|
|||
from src.db.users import PublicUser, AnonymousUser, User, UserRead
|
||||
from src.db.courses.courses import Course
|
||||
from src.db.resource_authors import ResourceAuthor, ResourceAuthorshipEnum, ResourceAuthorshipStatusEnum
|
||||
from src.security.rbac.rbac import authorization_verify_if_user_is_anon, authorization_verify_based_on_roles_and_authorship
|
||||
from src.security.rbac.rbac import authorization_verify_if_user_is_anon, authorization_verify_based_on_org_admin_status
|
||||
from src.security.courses_security import courses_rbac_check
|
||||
from typing import List
|
||||
|
||||
|
||||
|
|
@ -14,6 +15,14 @@ async def apply_course_contributor(
|
|||
current_user: PublicUser | AnonymousUser,
|
||||
db_session: Session,
|
||||
):
|
||||
"""
|
||||
Apply to become a course contributor
|
||||
|
||||
SECURITY NOTES:
|
||||
- Any authenticated user can apply to become a contributor
|
||||
- Applications are created with PENDING status
|
||||
- Only course owners (CREATOR, MAINTAINER) or admins can approve applications
|
||||
"""
|
||||
# Verify user is not anonymous
|
||||
await authorization_verify_if_user_is_anon(current_user.id)
|
||||
|
||||
|
|
@ -73,21 +82,17 @@ async def update_course_contributor(
|
|||
):
|
||||
"""
|
||||
Update a course contributor's role and status
|
||||
Only administrators can perform this action
|
||||
|
||||
SECURITY NOTES:
|
||||
- Only course owners (CREATOR, MAINTAINER) or admins can update contributors
|
||||
- Cannot modify the role of the course creator
|
||||
- Requires strict course ownership checks
|
||||
"""
|
||||
# Verify user is not anonymous
|
||||
await authorization_verify_if_user_is_anon(current_user.id)
|
||||
|
||||
# RBAC check - verify if user has admin rights
|
||||
authorized = await authorization_verify_based_on_roles_and_authorship(
|
||||
request, current_user.id, "update", course_uuid, db_session
|
||||
)
|
||||
|
||||
if not authorized:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="You are not authorized to update course contributors",
|
||||
)
|
||||
# SECURITY: Require course ownership or admin role for updating contributors
|
||||
await courses_rbac_check(request, course_uuid, current_user, "update", db_session)
|
||||
|
||||
# Check if course exists
|
||||
statement = select(Course).where(Course.course_uuid == course_uuid)
|
||||
|
|
@ -115,7 +120,7 @@ async def update_course_contributor(
|
|||
detail="Contributor not found for this course",
|
||||
)
|
||||
|
||||
# Don't allow changing the role of the creator
|
||||
# SECURITY: Don't allow changing the role of the creator
|
||||
if existing_authorship.authorship == ResourceAuthorshipEnum.CREATOR:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
|
|
@ -144,6 +149,10 @@ async def get_course_contributors(
|
|||
) -> List[dict]:
|
||||
"""
|
||||
Get all contributors for a course with their user information
|
||||
|
||||
SECURITY NOTES:
|
||||
- Requires read access to the course
|
||||
- Contributors are visible to anyone with course read access
|
||||
"""
|
||||
# Check if course exists
|
||||
statement = select(Course).where(Course.course_uuid == course_uuid)
|
||||
|
|
@ -155,6 +164,9 @@ async def get_course_contributors(
|
|||
detail="Course not found",
|
||||
)
|
||||
|
||||
# SECURITY: Require read access to the course
|
||||
await courses_rbac_check(request, course_uuid, current_user, "read", db_session)
|
||||
|
||||
# Get all contributors for this course with user information
|
||||
statement = (
|
||||
select(ResourceAuthor, User)
|
||||
|
|
@ -184,21 +196,17 @@ async def add_bulk_course_contributors(
|
|||
):
|
||||
"""
|
||||
Add multiple contributors to a course by their usernames
|
||||
Only administrators can perform this action
|
||||
|
||||
SECURITY NOTES:
|
||||
- Only course owners (CREATOR, MAINTAINER) or admins can add contributors
|
||||
- Requires strict course ownership checks
|
||||
- Cannot add contributors to courses the user doesn't own
|
||||
"""
|
||||
# Verify user is not anonymous
|
||||
await authorization_verify_if_user_is_anon(current_user.id)
|
||||
|
||||
# RBAC check - verify if user has admin rights
|
||||
authorized = await authorization_verify_based_on_roles_and_authorship(
|
||||
request, current_user.id, "update", course_uuid, db_session
|
||||
)
|
||||
|
||||
if not authorized:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="You are not authorized to add contributors",
|
||||
)
|
||||
# SECURITY: Require course ownership or admin role for adding contributors
|
||||
await courses_rbac_check(request, course_uuid, current_user, "update", db_session)
|
||||
|
||||
# Check if course exists
|
||||
statement = select(Course).where(Course.course_uuid == course_uuid)
|
||||
|
|
@ -284,21 +292,18 @@ async def remove_bulk_course_contributors(
|
|||
):
|
||||
"""
|
||||
Remove multiple contributors from a course by their usernames
|
||||
Only administrators can perform this action
|
||||
|
||||
SECURITY NOTES:
|
||||
- Only course owners (CREATOR, MAINTAINER) or admins can remove contributors
|
||||
- Requires strict course ownership checks
|
||||
- Cannot remove contributors from courses the user doesn't own
|
||||
- Cannot remove the course creator
|
||||
"""
|
||||
# Verify user is not anonymous
|
||||
await authorization_verify_if_user_is_anon(current_user.id)
|
||||
|
||||
# RBAC check - verify if user has admin rights
|
||||
authorized = await authorization_verify_based_on_roles_and_authorship(
|
||||
request, current_user.id, "update", course_uuid, db_session
|
||||
)
|
||||
|
||||
if not authorized:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="You are not authorized to remove contributors",
|
||||
)
|
||||
# SECURITY: Require course ownership or admin role for removing contributors
|
||||
await courses_rbac_check(request, course_uuid, current_user, "update", db_session)
|
||||
|
||||
# Check if course exists
|
||||
statement = select(Course).where(Course.course_uuid == course_uuid)
|
||||
|
|
@ -346,7 +351,7 @@ async def remove_bulk_course_contributors(
|
|||
})
|
||||
continue
|
||||
|
||||
# Don't allow removing the creator
|
||||
# SECURITY: Don't allow removing the creator
|
||||
if existing_authorship.authorship == ResourceAuthorshipEnum.CREATOR:
|
||||
results["failed"].append({
|
||||
"username": username,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue