diff --git a/apps/api/src/security/rbac/rbac.py b/apps/api/src/security/rbac/rbac.py index 3d6872b5..34098744 100644 --- a/apps/api/src/security/rbac/rbac.py +++ b/apps/api/src/security/rbac/rbac.py @@ -21,36 +21,28 @@ async def authorization_verify_if_element_is_public( # Verifies if the element is public if element_nature == ("courses" or "collections") and action == "read": if element_nature == "courses": + print("looking for course") statement = select(Course).where( - Course.public is True, Course.course_uuid == element_uuid + Course.public == True, Course.course_uuid == element_uuid ) course = db_session.exec(statement).first() if course: return True else: - raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail="User rights (public content) : You don't have the right to perform this action", - ) + return False if element_nature == "collections": statement = select(Collection).where( - Collection.public is True, Collection.collection_uuid == element_uuid + Collection.public == True, Collection.collection_uuid == element_uuid ) collection = db_session.exec(statement).first() if collection: return True else: - raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail="User rights (public content) : You don't have the right to perform this action", - ) + return False else: - raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail="User rights (public content) : You don't have the right to perform this action", - ) + return False # Tested and working diff --git a/apps/api/src/services/courses/activities/activities.py b/apps/api/src/services/courses/activities/activities.py index 0acae6b3..58e7de7d 100644 --- a/apps/api/src/services/courses/activities/activities.py +++ b/apps/api/src/services/courses/activities/activities.py @@ -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 ## diff --git a/apps/api/src/services/courses/chapters.py b/apps/api/src/services/courses/chapters.py index bb128c44..5d5b78ca 100644 --- a/apps/api/src/services/courses/chapters.py +++ b/apps/api/src/services/courses/chapters.py @@ -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 @@ -541,15 +542,28 @@ async def rbac_check( 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_uuid, - db_session, - ) + await authorization_verify_based_on_roles_and_authorship( + request, + current_user.id, + action, + course_uuid, + db_session, + ) ## 🔒 RBAC Utils ## diff --git a/apps/api/src/services/courses/collections.py b/apps/api/src/services/courses/collections.py index 3a8c8810..e04e5c3d 100644 --- a/apps/api/src/services/courses/collections.py +++ b/apps/api/src/services/courses/collections.py @@ -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 ## + diff --git a/apps/api/src/services/courses/courses.py b/apps/api/src/services/courses/courses.py index eabc85c2..df69ce75 100644 --- a/apps/api/src/services/courses/courses.py +++ b/apps/api/src/services/courses/courses.py @@ -327,7 +327,7 @@ async def get_courses_orgslug( statement_public = ( select(Course) .join(Organization) - .where(Organization.slug == org_slug, Course.public is True) + .where(Organization.slug == org_slug, Course.public == True) ) statement_all = ( select(Course).join(Organization).where(Organization.slug == org_slug) @@ -364,7 +364,6 @@ async def get_courses_orgslug( ## 🔒 RBAC Utils ## - async def rbac_check( request: Request, course_uuid: str, @@ -374,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) diff --git a/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/course.tsx b/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/course.tsx index 365404da..bd391921 100644 --- a/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/course.tsx +++ b/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/course.tsx @@ -42,7 +42,8 @@ const CourseClient = (props: any) => { } function isCourseStarted() { - const runs = course.trail.runs; + const runs = course.trail?.runs; + if (!runs) return false; return runs.some((run: any) => run.status === "STATUS_IN_PROGRESS" && run.course_id === course.id); } diff --git a/apps/web/components/Pages/Courses/ActivityIndicators.tsx b/apps/web/components/Pages/Courses/ActivityIndicators.tsx index dad0fb4e..c8d0668e 100644 --- a/apps/web/components/Pages/Courses/ActivityIndicators.tsx +++ b/apps/web/components/Pages/Courses/ActivityIndicators.tsx @@ -24,10 +24,13 @@ function ActivityIndicators(props: Props) { function isActivityDone(activity: any) { - let run = props.course.trail.runs.find((run: any) => run.course_id == props.course.id); + let run = props.course.trail?.runs.find((run: any) => run.course_id == props.course.id); if (run) { return run.steps.find((step: any) => step.activity_id == activity.id); } + else { + return false + } }