feat: verify org_id for courses & lectures

This commit is contained in:
swve 2023-03-22 22:28:24 +01:00
parent 48cf26790a
commit 98b470f2ab
5 changed files with 55 additions and 50 deletions

View file

@ -9,7 +9,7 @@ router = APIRouter()
@router.post("/")
async def api_create_course(request: Request,org_id: str, name: str = Form(), mini_description: str = Form(), description: str = Form(), public: bool = Form(), current_user: PublicUser = Depends(get_current_user), thumbnail: UploadFile | None = None):
async def api_create_course(request: Request, org_id: str, name: str = Form(), mini_description: str = Form(), description: str = Form(), public: bool = Form(), current_user: PublicUser = Depends(get_current_user), thumbnail: UploadFile | None = None):
"""
Create new Course
"""
@ -19,7 +19,7 @@ async def api_create_course(request: Request,org_id: str, name: str = Form(), mi
@router.put("/thumbnail/{course_id}")
async def api_create_course_thumbnail(request: Request,course_id: str, thumbnail: UploadFile | None = None, current_user: PublicUser = Depends(get_current_user)):
async def api_create_course_thumbnail(request: Request, course_id: str, thumbnail: UploadFile | None = None, current_user: PublicUser = Depends(get_current_user)):
"""
Update new Course Thumbnail
"""
@ -27,7 +27,7 @@ async def api_create_course_thumbnail(request: Request,course_id: str, thumbnail
@router.get("/{course_id}")
async def api_get_course(request: Request,course_id: str, current_user: PublicUser = Depends(get_current_user)):
async def api_get_course(request: Request, course_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Get single Course by course_id
"""
@ -35,7 +35,7 @@ async def api_get_course(request: Request,course_id: str, current_user: PublicU
@router.get("/meta/{course_id}")
async def api_get_course_meta(request: Request,course_id: str, current_user: PublicUser = Depends(get_current_user)):
async def api_get_course_meta(request: Request, course_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Get single Course Metadata (chapters, lectures) by course_id
"""
@ -43,30 +43,31 @@ async def api_get_course_meta(request: Request,course_id: str, current_user: Pu
@router.get("/org_id/{org_id}/page/{page}/limit/{limit}")
async def api_get_course_by(request: Request,page: int, limit: int, org_id: str):
async def api_get_course_by(request: Request, page: int, limit: int, org_id: str):
"""
Get houses by page and limit
"""
return await get_courses(request,page, limit, org_id)
return await get_courses(request, page, limit, org_id)
@router.get("/org_slug/{org_slug}/page/{page}/limit/{limit}")
async def api_get_course_by_orgslug(request: Request,page: int, limit: int, org_slug: str):
async def api_get_course_by_orgslug(request: Request, page: int, limit: int, org_slug: str):
"""
Get houses by page and limit
"""
return await get_courses_orgslug(request,page, limit, org_slug)
return await get_courses_orgslug(request, page, limit, org_slug)
@router.put("/{course_id}")
async def api_update_course(request: Request,course_object: Course, course_id: str, current_user: PublicUser = Depends(get_current_user)):
async def api_update_course(request: Request, course_object: Course, course_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Update Course by course_id
"""
return await update_course(request,course_object, course_id, current_user)
return await update_course(request, course_object, course_id, current_user)
@router.delete("/{course_id}")
async def api_delete_course(request: Request,course_id: str, current_user: PublicUser = Depends(get_current_user)):
async def api_delete_course(request: Request, course_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Delete Course by ID
"""

View file

@ -7,15 +7,15 @@ router = APIRouter()
@router.post("/")
async def api_create_lecture(request: Request,lecture_object: Lecture, coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
async def api_create_lecture(request: Request, lecture_object: Lecture, org_id: str, coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Create new lecture
"""
return await create_lecture(request,lecture_object, coursechapter_id, current_user)
return await create_lecture(request, lecture_object, org_id, coursechapter_id, current_user)
@router.get("/{lecture_id}")
async def api_get_lecture(request: Request,lecture_id: str, current_user: PublicUser = Depends(get_current_user)):
async def api_get_lecture(request: Request, lecture_id: str, org_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Get single lecture by lecture_id
"""
@ -23,32 +23,34 @@ async def api_get_lecture(request: Request,lecture_id: str, current_user: Public
@router.get("/coursechapter/{coursechapter_id}")
async def api_get_lectures(request: Request,coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
async def api_get_lectures(request: Request, coursechapter_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Get CourseChapter lectures
"""
return await get_lectures(request,coursechapter_id, current_user)
return await get_lectures(request, coursechapter_id, current_user)
@router.put("/{lecture_id}")
async def api_update_lecture(request: Request,lecture_object: Lecture, lecture_id: str, current_user: PublicUser = Depends(get_current_user)):
async def api_update_lecture(request: Request, lecture_object: Lecture, lecture_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Update lecture by lecture_id
"""
return await update_lecture(request,lecture_object, lecture_id, current_user)
return await update_lecture(request, lecture_object, lecture_id, current_user)
@router.delete("/{lecture_id}")
async def api_delete_lecture(request: Request,lecture_id: str, current_user: PublicUser = Depends(get_current_user)):
async def api_delete_lecture(request: Request, lecture_id: str, org_id: str, current_user: PublicUser = Depends(get_current_user)):
"""
Delete lecture by lecture_id
"""
return await delete_lecture(request,lecture_id, current_user)
return await delete_lecture(request, lecture_id, current_user)
# Video play
@router.post("/video")
async def api_create_video_lecture(request: Request,name: str = Form(), coursechapter_id: str = Form(), current_user: PublicUser = Depends(get_current_user), video_file: UploadFile | None = None):
async def api_create_video_lecture(request: Request, org_id: str, name: str = Form(), coursechapter_id: str = Form(), current_user: PublicUser = Depends(get_current_user), video_file: UploadFile | None = None):
"""
Create new lecture
"""
return await create_video_lecture(request,name, coursechapter_id, current_user, video_file)
return await create_video_lecture(request, name, coursechapter_id, current_user, video_file)

View file

@ -141,12 +141,9 @@ async def create_course(request: Request, course_object: Course, org_id: str, cu
# TODO(fix) : the implementation here is clearly not the best one (this entire function)
course_object.org_id = org_id
hasRoleRights = await verify_user_rights_with_roles(request, "create", current_user.user_id, course_id)
if not hasRoleRights:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action")
await verify_user_rights_with_roles(request, "create", current_user.user_id, course_id,org_id)
if thumbnail_file:
name_in_disk = f"{course_id}_thumbnail_{uuid4()}.{thumbnail_file.filename.split('.')[-1]}"
await upload_thumbnail(thumbnail_file, name_in_disk)
@ -290,7 +287,7 @@ async def verify_rights(request: Request, course_id: str, current_user: PublicUs
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail=f"Course/CourseChapter does not exist")
hasRoleRights = await verify_user_rights_with_roles(request, action, current_user.user_id, course_id)
hasRoleRights = await verify_user_rights_with_roles(request, action, current_user.user_id, course_id, course["org_id"])
isAuthor = current_user.user_id in course["authors"]
if not hasRoleRights and not isAuthor:

View file

@ -29,14 +29,14 @@ class LectureInDB(Lecture):
####################################################
async def create_lecture(request: Request,lecture_object: Lecture, coursechapter_id: str, current_user: PublicUser):
async def create_lecture(request: Request, lecture_object: Lecture, org_id: str, coursechapter_id: str, current_user: PublicUser):
lectures = request.app.db["lectures"]
coursechapters = request.app.db["coursechapters"]
# generate lecture_id
lecture_id = str(f"lecture_{uuid4()}")
hasRoleRights = await verify_user_rights_with_roles(request, "create", current_user.user_id, lecture_id)
hasRoleRights = await verify_user_rights_with_roles(request, "create", current_user.user_id, lecture_id, org_id)
if not hasRoleRights:
raise HTTPException(
@ -49,18 +49,18 @@ async def create_lecture(request: Request,lecture_object: Lecture, coursechapter
# update chapter
await coursechapters.update_one({"coursechapter_id": coursechapter_id}, {
"$addToSet": {"lectures": lecture_id}})
"$addToSet": {"lectures": lecture_id}})
return lecture
async def get_lecture(request: Request,lecture_id: str, current_user: PublicUser):
async def get_lecture(request: Request, lecture_id: str, current_user: PublicUser):
lectures = request.app.db["lectures"]
lecture = await lectures.find_one({"lecture_id": lecture_id})
# verify course rights
hasRoleRights = await verify_user_rights_with_roles(request,"read", current_user.user_id, lecture_id)
hasRoleRights = await verify_user_rights_with_roles(request, "read", current_user.user_id, lecture_id, element_org_id=lecture["org_id"])
if not hasRoleRights:
raise HTTPException(
@ -74,14 +74,13 @@ async def get_lecture(request: Request,lecture_id: str, current_user: PublicUser
return lecture
async def update_lecture(request: Request,lecture_object: Lecture, lecture_id: str, current_user: PublicUser):
# verify course rights
await verify_user_rights_with_roles(request, "update", current_user.user_id, lecture_id)
async def update_lecture(request: Request, lecture_object: Lecture, lecture_id: str, current_user: PublicUser):
lectures = request.app.db["lectures"]
lecture = await lectures.find_one({"lecture_id": lecture_id})
# verify course rights
await verify_user_rights_with_roles(request, "update", current_user.user_id, lecture_id, element_org_id=lecture["org_id"])
if lecture:
creationDate = lecture["creationDate"]
@ -102,15 +101,15 @@ async def update_lecture(request: Request,lecture_object: Lecture, lecture_id: s
status_code=status.HTTP_409_CONFLICT, detail="lecture does not exist")
async def delete_lecture(request: Request,lecture_id: str, current_user: PublicUser):
# verify course rights
await verify_user_rights_with_roles(request,"delete", current_user.user_id, lecture_id)
async def delete_lecture(request: Request, lecture_id: str, current_user: PublicUser):
lectures = request.app.db["lectures"]
lecture = await lectures.find_one({"lecture_id": lecture_id})
# verify course rights
await verify_user_rights_with_roles(request, "delete", current_user.user_id, lecture_id, element_org_id=lecture["org_id"])
if not lecture:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="lecture does not exist")
@ -128,18 +127,19 @@ async def delete_lecture(request: Request,lecture_id: str, current_user: PublicU
####################################################
async def get_lectures(request: Request,coursechapter_id: str, current_user: PublicUser):
async def get_lectures(request: Request, coursechapter_id: str, current_user: PublicUser):
lectures = request.app.db["lectures"]
# verify course rights
await verify_user_rights_with_roles(request,"read", current_user.user_id, coursechapter_id)
# TODO : TERRIBLE SECURITY ISSUE HERE, NEED TO FIX ASAP
# TODO : TERRIBLE SECURITY ISSUE HERE, NEED TO FIX ASAP
# TODO : TERRIBLE SECURITY ISSUE HERE, NEED TO FIX ASAP
lectures = lectures.find({"coursechapter_id": coursechapter_id})
if not lectures:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist")
lectures = [LectureInDB(**lecture) for lecture in await lectures.to_list(length=100)]
return lectures

View file

@ -58,7 +58,8 @@ async def verify_user_rights_with_roles(request: Request, action: str, user_id:
# TODO: Check if the org_id of the role is the same as the org_id of the element using find
await check_user_role_org_with_element_org(request, element_id, user_roles)
if action != "create":
await check_user_role_org_with_element_org(request, element_id, user_roles)
# Check if user has the right role
@ -105,12 +106,16 @@ async def check_user_role_org_with_element_org(request: Request, element_id: str
# get singular element type
singular_form_element = element_type[:-1]
element_org_id = await element.find_one({singular_form_element + "_id": element_id}, {"org_id": 1})
element_type_id = singular_form_element + "_id"
element_org = await element.find_one({element_type_id: element_id})
for role_id in roles_list:
role = RoleInDB(**await roles.find_one({"role_id": role_id}))
if role.org_id == element_org_id:
if role.org_id == element_org["org_id"]:
return True
if role.org_id == "*":
return True
else: