mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
feat: verify org_id for courses & lectures
This commit is contained in:
parent
48cf26790a
commit
98b470f2ab
5 changed files with 55 additions and 50 deletions
|
|
@ -9,7 +9,7 @@ router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.post("/")
|
@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
|
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}")
|
@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
|
Update new Course Thumbnail
|
||||||
"""
|
"""
|
||||||
|
|
@ -27,7 +27,7 @@ async def api_create_course_thumbnail(request: Request,course_id: str, thumbnail
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{course_id}")
|
@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
|
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}")
|
@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
|
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}")
|
@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
|
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}")
|
@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
|
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}")
|
@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
|
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}")
|
@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
|
Delete Course by ID
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,15 @@ router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@router.post("/")
|
@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
|
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}")
|
@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
|
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}")
|
@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
|
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}")
|
@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
|
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}")
|
@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
|
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
|
# Video play
|
||||||
|
|
||||||
|
|
||||||
@router.post("/video")
|
@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
|
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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
# TODO(fix) : the implementation here is clearly not the best one (this entire function)
|
||||||
course_object.org_id = org_id
|
course_object.org_id = org_id
|
||||||
hasRoleRights = await verify_user_rights_with_roles(request, "create", current_user.user_id, course_id)
|
await verify_user_rights_with_roles(request, "create", current_user.user_id, course_id,org_id)
|
||||||
|
|
||||||
if not hasRoleRights:
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action")
|
|
||||||
|
|
||||||
|
|
||||||
if thumbnail_file:
|
if thumbnail_file:
|
||||||
name_in_disk = f"{course_id}_thumbnail_{uuid4()}.{thumbnail_file.filename.split('.')[-1]}"
|
name_in_disk = f"{course_id}_thumbnail_{uuid4()}.{thumbnail_file.filename.split('.')[-1]}"
|
||||||
await upload_thumbnail(thumbnail_file, name_in_disk)
|
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(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_409_CONFLICT, detail=f"Course/CourseChapter does not exist")
|
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"]
|
isAuthor = current_user.user_id in course["authors"]
|
||||||
|
|
||||||
if not hasRoleRights and not isAuthor:
|
if not hasRoleRights and not isAuthor:
|
||||||
|
|
|
||||||
|
|
@ -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"]
|
lectures = request.app.db["lectures"]
|
||||||
coursechapters = request.app.db["coursechapters"]
|
coursechapters = request.app.db["coursechapters"]
|
||||||
|
|
||||||
# generate lecture_id
|
# generate lecture_id
|
||||||
lecture_id = str(f"lecture_{uuid4()}")
|
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:
|
if not hasRoleRights:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
@ -49,18 +49,18 @@ async def create_lecture(request: Request,lecture_object: Lecture, coursechapter
|
||||||
|
|
||||||
# update chapter
|
# update chapter
|
||||||
await coursechapters.update_one({"coursechapter_id": coursechapter_id}, {
|
await coursechapters.update_one({"coursechapter_id": coursechapter_id}, {
|
||||||
"$addToSet": {"lectures": lecture_id}})
|
"$addToSet": {"lectures": lecture_id}})
|
||||||
|
|
||||||
return lecture
|
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"]
|
lectures = request.app.db["lectures"]
|
||||||
|
|
||||||
lecture = await lectures.find_one({"lecture_id": lecture_id})
|
lecture = await lectures.find_one({"lecture_id": lecture_id})
|
||||||
|
|
||||||
# verify course rights
|
# 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:
|
if not hasRoleRights:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
@ -74,14 +74,13 @@ async def get_lecture(request: Request,lecture_id: str, current_user: PublicUser
|
||||||
return lecture
|
return lecture
|
||||||
|
|
||||||
|
|
||||||
async def update_lecture(request: Request,lecture_object: Lecture, lecture_id: str, current_user: PublicUser):
|
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)
|
|
||||||
|
|
||||||
lectures = request.app.db["lectures"]
|
lectures = request.app.db["lectures"]
|
||||||
|
|
||||||
lecture = await lectures.find_one({"lecture_id": lecture_id})
|
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:
|
if lecture:
|
||||||
creationDate = lecture["creationDate"]
|
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")
|
status_code=status.HTTP_409_CONFLICT, detail="lecture does not exist")
|
||||||
|
|
||||||
|
|
||||||
async def delete_lecture(request: Request,lecture_id: str, current_user: PublicUser):
|
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)
|
|
||||||
|
|
||||||
lectures = request.app.db["lectures"]
|
lectures = request.app.db["lectures"]
|
||||||
|
|
||||||
lecture = await lectures.find_one({"lecture_id": lecture_id})
|
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:
|
if not lecture:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="lecture does not exist")
|
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"]
|
lectures = request.app.db["lectures"]
|
||||||
|
|
||||||
# verify course rights
|
# TODO : TERRIBLE SECURITY ISSUE HERE, NEED TO FIX ASAP
|
||||||
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
|
||||||
|
|
||||||
lectures = lectures.find({"coursechapter_id": coursechapter_id})
|
lectures = lectures.find({"coursechapter_id": coursechapter_id})
|
||||||
|
|
||||||
if not lectures:
|
if not lectures:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist")
|
status_code=status.HTTP_409_CONFLICT, detail="Course does not exist")
|
||||||
|
|
||||||
lectures = [LectureInDB(**lecture) for lecture in await lectures.to_list(length=100)]
|
lectures = [LectureInDB(**lecture) for lecture in await lectures.to_list(length=100)]
|
||||||
|
|
||||||
return lectures
|
return lectures
|
||||||
|
|
|
||||||
|
|
@ -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
|
# 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
|
# 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
|
# get singular element type
|
||||||
singular_form_element = element_type[:-1]
|
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:
|
for role_id in roles_list:
|
||||||
role = RoleInDB(**await roles.find_one({"role_id": role_id}))
|
role = RoleInDB(**await roles.find_one({"role_id": role_id}))
|
||||||
|
if role.org_id == element_org["org_id"]:
|
||||||
if role.org_id == element_org_id:
|
return True
|
||||||
|
if role.org_id == "*":
|
||||||
return True
|
return True
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue