fix: public courses & collections bug

This commit is contained in:
swve 2023-12-23 12:20:54 +01:00
parent d3853c69ce
commit d939dc16eb
7 changed files with 87 additions and 46 deletions

View file

@ -21,36 +21,28 @@ async def authorization_verify_if_element_is_public(
# Verifies if the element is public # Verifies if the element is public
if element_nature == ("courses" or "collections") and action == "read": if element_nature == ("courses" or "collections") and action == "read":
if element_nature == "courses": if element_nature == "courses":
print("looking for course")
statement = select(Course).where( 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() course = db_session.exec(statement).first()
if course: if course:
return True return True
else: else:
raise HTTPException( return False
status_code=status.HTTP_403_FORBIDDEN,
detail="User rights (public content) : You don't have the right to perform this action",
)
if element_nature == "collections": if element_nature == "collections":
statement = select(Collection).where( 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() collection = db_session.exec(statement).first()
if collection: if collection:
return True return True
else: else:
raise HTTPException( return False
status_code=status.HTTP_403_FORBIDDEN,
detail="User rights (public content) : You don't have the right to perform this action",
)
else: else:
raise HTTPException( return False
status_code=status.HTTP_403_FORBIDDEN,
detail="User rights (public content) : You don't have the right to perform this action",
)
# Tested and working # Tested and working

View file

@ -3,6 +3,7 @@ from sqlmodel import Session, select
from src.db.chapters import Chapter from src.db.chapters import Chapter
from src.security.rbac.rbac import ( from src.security.rbac.rbac import (
authorization_verify_based_on_roles_and_authorship, authorization_verify_based_on_roles_and_authorship,
authorization_verify_if_element_is_public,
authorization_verify_if_user_is_anon, authorization_verify_if_user_is_anon,
) )
from src.db.activities import ActivityCreate, Activity, ActivityRead, ActivityUpdate from src.db.activities import ActivityCreate, Activity, ActivityRead, ActivityUpdate
@ -212,18 +213,31 @@ async def get_activities(
async def rbac_check( async def rbac_check(
request: Request, request: Request,
course_id: str, course_uuid: str,
current_user: PublicUser | AnonymousUser, current_user: PublicUser | AnonymousUser,
action: Literal["create", "read", "update", "delete"], action: Literal["create", "read", "update", "delete"],
db_session: Session, db_session: Session,
): ):
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_if_user_is_anon(current_user.id)
await authorization_verify_based_on_roles_and_authorship( await authorization_verify_based_on_roles_and_authorship(
request, request,
current_user.id, current_user.id,
action, action,
course_id, course_uuid,
db_session, db_session,
) )

View file

@ -5,6 +5,7 @@ from sqlmodel import Session, select
from src.db.users import AnonymousUser from src.db.users import AnonymousUser
from src.security.rbac.rbac import ( from src.security.rbac.rbac import (
authorization_verify_based_on_roles_and_authorship, authorization_verify_based_on_roles_and_authorship,
authorization_verify_if_element_is_public,
authorization_verify_if_user_is_anon, authorization_verify_if_user_is_anon,
) )
from src.db.course_chapters import CourseChapter from src.db.course_chapters import CourseChapter
@ -541,6 +542,19 @@ async def rbac_check(
action: Literal["create", "read", "update", "delete"], action: Literal["create", "read", "update", "delete"],
db_session: Session, db_session: Session,
): ):
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_if_user_is_anon(current_user.id)
await authorization_verify_based_on_roles_and_authorship( await authorization_verify_based_on_roles_and_authorship(

View file

@ -5,6 +5,7 @@ from sqlmodel import Session, select
from src.db.users import AnonymousUser from src.db.users import AnonymousUser
from src.security.rbac.rbac import ( from src.security.rbac.rbac import (
authorization_verify_based_on_roles_and_authorship, authorization_verify_based_on_roles_and_authorship,
authorization_verify_if_element_is_public,
authorization_verify_if_user_is_anon, authorization_verify_if_user_is_anon,
) )
from src.db.collections import ( from src.db.collections import (
@ -245,20 +246,34 @@ async def get_collections(
async def rbac_check( async def rbac_check(
request: Request, request: Request,
course_id: str, collection_uuid: str,
current_user: PublicUser | AnonymousUser, current_user: PublicUser | AnonymousUser,
action: Literal["create", "read", "update", "delete"], action: Literal["create", "read", "update", "delete"],
db_session: Session, db_session: Session,
): ):
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_if_user_is_anon(current_user.id)
await authorization_verify_based_on_roles_and_authorship( await authorization_verify_based_on_roles_and_authorship(
request, request,
current_user.id, current_user.id,
action, action,
course_id, collection_uuid,
db_session, db_session,
) )
## 🔒 RBAC Utils ## ## 🔒 RBAC Utils ##

View file

@ -327,7 +327,7 @@ async def get_courses_orgslug(
statement_public = ( statement_public = (
select(Course) select(Course)
.join(Organization) .join(Organization)
.where(Organization.slug == org_slug, Course.public is True) .where(Organization.slug == org_slug, Course.public == True)
) )
statement_all = ( statement_all = (
select(Course).join(Organization).where(Organization.slug == org_slug) select(Course).join(Organization).where(Organization.slug == org_slug)
@ -364,7 +364,6 @@ async def get_courses_orgslug(
## 🔒 RBAC Utils ## ## 🔒 RBAC Utils ##
async def rbac_check( async def rbac_check(
request: Request, request: Request,
course_uuid: str, course_uuid: str,
@ -374,13 +373,16 @@ async def rbac_check(
): ):
if action == "read": if action == "read":
if current_user.id == 0: # Anonymous user 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 request, course_uuid, action, db_session
) )
print('res',res)
return res
else: 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 request, current_user.id, action, course_uuid, db_session
) )
return res
else: else:
await authorization_verify_if_user_is_anon(current_user.id) await authorization_verify_if_user_is_anon(current_user.id)

View file

@ -42,7 +42,8 @@ const CourseClient = (props: any) => {
} }
function isCourseStarted() { 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); return runs.some((run: any) => run.status === "STATUS_IN_PROGRESS" && run.course_id === course.id);
} }

View file

@ -24,10 +24,13 @@ function ActivityIndicators(props: Props) {
function isActivityDone(activity: any) { 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) { if (run) {
return run.steps.find((step: any) => step.activity_id == activity.id); return run.steps.find((step: any) => step.activity_id == activity.id);
} }
else {
return false
}
} }