From 976b730de5f544d4f46ec14d654b0c6a1b642353 Mon Sep 17 00:00:00 2001 From: swve Date: Sun, 10 Jul 2022 00:53:27 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20init=20coursechapters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/routers/courses.py | 45 +++++++++++- src/services/courses.py | 145 +++++++++++++++++++++++++++++++++++++-- src/services/roles.py | 1 + src/services/security.py | 2 + 4 files changed, 186 insertions(+), 7 deletions(-) diff --git a/src/routers/courses.py b/src/routers/courses.py index 3341a014..200bee65 100644 --- a/src/routers/courses.py +++ b/src/routers/courses.py @@ -1,7 +1,7 @@ from fastapi import APIRouter, Depends from src.services.auth import get_current_user -from src.services.courses import Course, create_course, get_course, get_courses, update_course, delete_course +from src.services.courses import Course, CourseChapter, create_course, create_coursechapter, delete_coursechapter, get_course, get_coursechapter, get_coursechapters, get_courses, update_course, delete_course, update_coursechapter from src.services.users import User @@ -47,3 +47,46 @@ async def api_delete_course(course_id: str, current_user: User = Depends(get_cur """ return await delete_course(course_id, current_user) + +# CoursesChapters + + +@router.post("/chapters/") +async def api_create_coursechapter(coursechapter_object: CourseChapter, course_id: str, current_user: User = Depends(get_current_user)): + """ + Create new CourseChapter + """ + return await create_coursechapter(coursechapter_object, course_id, current_user) + + +@router.get("/chapters/{coursechapter_id}") +async def api_get_coursechapter(coursechapter_id: str, current_user: User = Depends(get_current_user)): + """ + Get single CourseChapter by coursechapter_id + """ + return await get_coursechapter(coursechapter_id, current_user=current_user) + + +@router.get("/chapters/{course_id}/page/{page}/limit/{limit}") +async def api_get_coursechapter_by(course_id: str, page: int, limit: int): + """ + Get CourseChapters by page and limit + """ + return await get_coursechapters(course_id, page, limit) + + +@router.put("/chapters/{coursechapter_id}") +async def api_update_coursechapter(coursechapter_object: CourseChapter, coursechapter_id: str, current_user: User = Depends(get_current_user)): + """ + Update CourseChapters by course_id + """ + return await update_coursechapter(coursechapter_object, coursechapter_id, current_user) + + +@router.delete("/chapters/{coursechapter_id}") +async def api_delete_coursechapter(coursechapter_id: str, current_user: User = Depends(get_current_user)): + """ + Delete CourseChapters by ID + """ + + return await delete_coursechapter(coursechapter_id, current_user) diff --git a/src/services/courses.py b/src/services/courses.py index 6cd1ea83..38185977 100644 --- a/src/services/courses.py +++ b/src/services/courses.py @@ -27,8 +27,32 @@ class CourseInDB(Course): updateDate: str authors: List[str] +##### + + +class CourseElement(BaseModel): + element_id: str + position: int + + +class CourseChapter(BaseModel): + name: str + description: str + course: str + elements: List[CourseElement] + position: int + + +class CourseChapterInDB(CourseChapter): + coursechapter_id: str + course_id: str + creationDate: str + updateDate: str + + #### Classes #################################################### +# Courses async def get_course(course_id: str, current_user: User): await check_database() @@ -51,8 +75,6 @@ async def create_course(course_object: Course, current_user: User): await check_database() courses = learnhouseDB["courses"] - - # generate course_id with uuid4 course_id = str(f"course_{uuid4()}") @@ -63,7 +85,7 @@ async def create_course(course_object: Course, current_user: User): status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action") course = CourseInDB(course_id=course_id, authors=[ - current_user.username], creationDate= str(datetime.now()), updateDate= str(datetime.now()), **course_object.dict()) + current_user.username], creationDate=str(datetime.now()), updateDate=str(datetime.now()), **course_object.dict()) course_in_db = courses.insert_one(course.dict()) @@ -86,7 +108,7 @@ async def update_course(course_object: Course, course_id: str, current_user: Use creationDate = course["creationDate"] authors = course["authors"] - + # get today's date datetime_object = datetime.now() @@ -97,7 +119,8 @@ async def update_course(course_object: Course, course_id: str, current_user: Use updated_course = CourseInDB( course_id=course_id, creationDate=creationDate, authors=authors, updateDate=str(datetime_object), **course_object.dict()) - courses.update_one({"course_id": course_id}, {"$set": updated_course.dict()}) + courses.update_one({"course_id": course_id}, { + "$set": updated_course.dict()}) return CourseInDB(**updated_course.dict()) @@ -134,9 +157,119 @@ async def get_courses(page: int = 1, limit: int = 10): return [json.loads(json.dumps(course, default=str)) for course in all_courses] +# CoursesChapters + + +async def get_coursechapter(coursechapter_id: str, current_user: User): + await check_database() + coursechapters = learnhouseDB["coursechapters"] + + coursechapter = coursechapters.find_one( + {"coursechapter_id": coursechapter_id}) + + # verify course rights + await verify_rights(coursechapter["course_id"], current_user, "read") + + if not coursechapter: + raise HTTPException( + status_code=status.HTTP_409_CONFLICT, detail="CourseChapter does not exist") + + coursechapter = CourseChapter(**coursechapter) + return coursechapter + + +async def create_coursechapter(coursechapter_object: CourseChapter, course_id: str, current_user: User): + await check_database() + coursechapters = learnhouseDB["coursechapters"] + + # generate coursechapter_id with uuid4 + coursechapter_id = str(f"coursechapter_{uuid4()}") + + hasRoleRights = await verify_user_rights_with_roles("create", current_user.username, coursechapter_id) + + if not hasRoleRights: + raise HTTPException( + status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action") + + coursechapter = CourseChapterInDB(coursechapter_id=coursechapter_id, creationDate=str( + datetime.now()), updateDate=str(datetime.now()), course_id=course_id, **coursechapter_object.dict()) + + coursechapter_in_db = coursechapters.insert_one(coursechapter.dict()) + + if not coursechapter_in_db: + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database") + + return coursechapter.dict() + + +async def update_coursechapter(coursechapter_object: CourseChapter, coursechapter_id: str, current_user: User): + await check_database() + coursechapters = learnhouseDB["coursechapters"] + + coursechapter = coursechapters.find_one( + {"coursechapter_id": coursechapter_id}) + + # verify course rights + await verify_rights(coursechapter["course_id"], current_user, "update") + creationDate = coursechapter["creationDate"] + + # get today's date + datetime_object = datetime.now() + + if not coursechapter: + raise HTTPException( + status_code=status.HTTP_409_CONFLICT, detail="Coursechapter does not exist") + + updated_coursechapter = CourseChapterInDB( + coursechapter_id=coursechapter_id, creationDate=creationDate, course_id=coursechapter["course_id"], updateDate=str(datetime_object), **coursechapter_object.dict()) + + coursechapters.update_one({"coursechapter_id": coursechapter_id}, { + "$set": updated_coursechapter.dict()}) + + return CourseChapterInDB(**updated_coursechapter.dict()) + + +async def delete_coursechapter(coursechapter_id: str, current_user: User): + await check_database() + + + + coursechapters = learnhouseDB["coursechapters"] + + coursechapter = coursechapters.find_one( + {"coursechapter_id": coursechapter_id}) + + # verify course rights + await verify_rights(coursechapter["course_id"], current_user, "delete") + + if not coursechapter: + raise HTTPException( + status_code=status.HTTP_409_CONFLICT, detail="Course does not exist") + + isDeleted = coursechapters.delete_one( + {"coursechapter_id": coursechapter_id}) + + if isDeleted: + return {"detail": "coursechapter deleted"} + else: + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Unavailable database") + + +async def get_coursechapters(course_id: str, page: int = 1, limit: int = 10): + await check_database() + courses = learnhouseDB["coursechapters"] + # TODO : Get only courses that user is admin/has roles of + # get all courses from database + all_coursechapters = courses.find({"course_id": course_id}).sort( + "name", 1).skip(10 * (page - 1)).limit(limit) + + return [json.loads(json.dumps(coursechapter, default=str)) for coursechapter in all_coursechapters] #### Security #################################################### + async def verify_rights(course_id: str, current_user: User, action: str): await check_database() courses = learnhouseDB["courses"] @@ -145,7 +278,7 @@ async def verify_rights(course_id: str, current_user: User, action: str): if not course: raise HTTPException( - status_code=status.HTTP_409_CONFLICT, detail="Course does not exist") + status_code=status.HTTP_409_CONFLICT, detail=f"Course/CourseChapter does not exist") hasRoleRights = await verify_user_rights_with_roles(action, current_user.username, course_id) isAuthor = current_user.username in course["authors"] diff --git a/src/services/roles.py b/src/services/roles.py index 4278d698..4ffb0d1e 100644 --- a/src/services/roles.py +++ b/src/services/roles.py @@ -25,6 +25,7 @@ class Elements(BaseModel): houses: List[str] collections: List[str] organizations: List[str] + coursechapters : List[str] class Role(BaseModel): diff --git a/src/services/security.py b/src/services/security.py index 8a61e51a..9519d0b9 100644 --- a/src/services/security.py +++ b/src/services/security.py @@ -72,6 +72,8 @@ async def check_element_type(element_id): return "houses" elif element_id.startswith("org_"): return "organizations" + elif element_id.startswith("coursechapter_"): + return "courses" elif element_id.startswith("collection_"): return "collections" else: