mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-18 11:59:26 +00:00
🔒️ use user_id instead of username
This commit is contained in:
parent
3d542b0055
commit
040f91b608
7 changed files with 114 additions and 57 deletions
|
|
@ -26,26 +26,34 @@ async def api_get_user_by_username(username: str):
|
|||
return await get_user(username)
|
||||
|
||||
|
||||
@router.get("/user_id/{user_id}")
|
||||
async def api_get_user_by_userid(user_id: str):
|
||||
"""
|
||||
Get single user by user_id
|
||||
"""
|
||||
return await get_user_by_userid(user_id)
|
||||
|
||||
|
||||
@router.post("/")
|
||||
async def api_create_user(user_object: UserInDB):
|
||||
async def api_create_user(user_object: UserWithPassword):
|
||||
"""
|
||||
Create new user
|
||||
"""
|
||||
return await create_user(user_object)
|
||||
|
||||
|
||||
@router.delete("/username/{username}")
|
||||
async def api_delete_user(username: str):
|
||||
@router.delete("/user_id/{user_id}")
|
||||
async def api_delete_user(user_id: str):
|
||||
"""
|
||||
Delete user by ID
|
||||
"""
|
||||
|
||||
return await delete_user(username)
|
||||
|
||||
return await delete_user(user_id)
|
||||
|
||||
|
||||
@router.put("/username/{username}")
|
||||
async def api_update_user(user_object: UserInDB):
|
||||
@router.put("/user_id/{user_id}")
|
||||
async def api_update_user(user_object: UserWithPassword, user_id: str):
|
||||
"""
|
||||
Update user by ID
|
||||
"""
|
||||
return await update_user(user_object)
|
||||
return await update_user(user_id, user_object)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ class TokenData(BaseModel):
|
|||
#### Classes ####################################################
|
||||
|
||||
|
||||
|
||||
async def authenticate_user(username: str, password: str):
|
||||
user = await security_get_user(username)
|
||||
if not user:
|
||||
|
|
@ -58,7 +57,7 @@ async def get_current_user(token: str = Depends(oauth2_scheme)):
|
|||
token_data = TokenData(username=username)
|
||||
except JWTError:
|
||||
raise credentials_exception
|
||||
user = await get_user(username=token_data.username)
|
||||
user = await security_get_user(username=token_data.username)
|
||||
if user is None:
|
||||
raise credentials_exception
|
||||
return User(**user.dict())
|
||||
return PublicUser(**user.dict())
|
||||
|
|
|
|||
|
|
@ -78,14 +78,14 @@ async def create_course(course_object: Course, current_user: User):
|
|||
# generate course_id with uuid4
|
||||
course_id = str(f"course_{uuid4()}")
|
||||
|
||||
hasRoleRights = await verify_user_rights_with_roles("create", current_user.username, course_id)
|
||||
hasRoleRights = await verify_user_rights_with_roles("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")
|
||||
|
||||
course = CourseInDB(course_id=course_id, authors=[
|
||||
current_user.username], creationDate=str(datetime.now()), updateDate=str(datetime.now()), **course_object.dict())
|
||||
current_user.user_id], creationDate=str(datetime.now()), updateDate=str(datetime.now()), **course_object.dict())
|
||||
|
||||
course_in_db = courses.insert_one(course.dict())
|
||||
|
||||
|
|
@ -185,7 +185,7 @@ async def create_coursechapter(coursechapter_object: CourseChapter, course_id: s
|
|||
# generate coursechapter_id with uuid4
|
||||
coursechapter_id = str(f"coursechapter_{uuid4()}")
|
||||
|
||||
hasRoleRights = await verify_user_rights_with_roles("create", current_user.username, coursechapter_id)
|
||||
hasRoleRights = await verify_user_rights_with_roles("create", current_user.user_id, coursechapter_id)
|
||||
|
||||
if not hasRoleRights:
|
||||
raise HTTPException(
|
||||
|
|
@ -209,7 +209,7 @@ async def update_coursechapter(coursechapter_object: CourseChapter, coursechapt
|
|||
|
||||
coursechapter = coursechapters.find_one(
|
||||
{"coursechapter_id": coursechapter_id})
|
||||
|
||||
|
||||
# verify course rights
|
||||
await verify_rights(coursechapter["course_id"], current_user, "update")
|
||||
creationDate = coursechapter["creationDate"]
|
||||
|
|
@ -237,8 +237,8 @@ async def delete_coursechapter(coursechapter_id: str, current_user: User):
|
|||
|
||||
coursechapter = coursechapters.find_one(
|
||||
{"coursechapter_id": coursechapter_id})
|
||||
|
||||
# verify course rights
|
||||
|
||||
# verify course rights
|
||||
await verify_rights(coursechapter["course_id"], current_user, "delete")
|
||||
|
||||
if not coursechapter:
|
||||
|
|
@ -278,8 +278,8 @@ async def verify_rights(course_id: str, current_user: User, action: str):
|
|||
raise HTTPException(
|
||||
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"]
|
||||
hasRoleRights = await verify_user_rights_with_roles(action, current_user.user_id, course_id)
|
||||
isAuthor = current_user.user_id in course["authors"]
|
||||
|
||||
if not hasRoleRights and not isAuthor:
|
||||
raise HTTPException(
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ async def get_house(house_id: str, current_user: User):
|
|||
house = houses.find_one({"house_id": house_id})
|
||||
|
||||
# verify house rights
|
||||
await verify_house_rights(house_id, current_user,"read")
|
||||
await verify_house_rights(house_id, current_user, "read")
|
||||
|
||||
if not house:
|
||||
raise HTTPException(
|
||||
|
|
@ -58,15 +58,15 @@ async def create_house(house_object: House, current_user: User):
|
|||
# generate house_id with uuid4
|
||||
house_id = str(f"house_{uuid4()}")
|
||||
|
||||
hasRoleRights = await verify_user_rights_with_roles("create", current_user.username, house_id)
|
||||
hasRoleRights = await verify_user_rights_with_roles("create", current_user.user_id, house_id)
|
||||
|
||||
if not hasRoleRights:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action")
|
||||
|
||||
house = HouseInDB(house_id=house_id, owners=[
|
||||
current_user.username], admins=[
|
||||
current_user.username], **house_object.dict())
|
||||
current_user.user_id], admins=[
|
||||
current_user.user_id], **house_object.dict())
|
||||
|
||||
house_in_db = houses.insert_one(house.dict())
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ async def update_house(house_object: House, house_id: str, current_user: User):
|
|||
await check_database()
|
||||
|
||||
# verify house rights
|
||||
await verify_house_rights(house_id, current_user,"update")
|
||||
await verify_house_rights(house_id, current_user, "update")
|
||||
|
||||
houses = learnhouseDB["houses"]
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ async def delete_house(house_id: str, current_user: User):
|
|||
await check_database()
|
||||
|
||||
# verify house rights
|
||||
await verify_house_rights(house_id, current_user,"delete")
|
||||
await verify_house_rights(house_id, current_user, "delete")
|
||||
|
||||
houses = learnhouseDB["houses"]
|
||||
|
||||
|
|
@ -148,8 +148,8 @@ async def verify_house_rights(house_id: str, current_user: User, action: str):
|
|||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="House does not exist")
|
||||
|
||||
hasRoleRights = await verify_user_rights_with_roles(action, current_user.username, house_id)
|
||||
isOwner = current_user.username in house["owners"]
|
||||
hasRoleRights = await verify_user_rights_with_roles(action, current_user.user_id, house_id)
|
||||
isOwner = current_user.user_id in house["owners"]
|
||||
|
||||
if not hasRoleRights and not isOwner:
|
||||
raise HTTPException(
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@ async def create_org(org_object: Organization, current_user: User):
|
|||
org_id = str(f"org_{uuid4()}")
|
||||
|
||||
org = OrganizationInDB(org_id=org_id, owners=[
|
||||
current_user.username], admins=[
|
||||
current_user.username], **org_object.dict())
|
||||
current_user.user_id], admins=[
|
||||
current_user.user_id], **org_object.dict())
|
||||
|
||||
org_in_db = orgs.insert_one(org.dict())
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ async def get_orgs(page: int = 1, limit: int = 10):
|
|||
|
||||
#### Security ####################################################
|
||||
|
||||
async def verify_org_rights(org_id: str, current_user: User, action:str,):
|
||||
async def verify_org_rights(org_id: str, current_user: User, action: str,):
|
||||
await check_database()
|
||||
orgs = learnhouseDB["organizations"]
|
||||
|
||||
|
|
@ -138,8 +138,8 @@ async def verify_org_rights(org_id: str, current_user: User, action:str,):
|
|||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="Organization does not exist")
|
||||
|
||||
isOwner = current_user.username in org["owners"]
|
||||
hasRoleRights = await verify_user_rights_with_roles(action,current_user.username,org_id)
|
||||
isOwner = current_user.user_id in org["owners"]
|
||||
hasRoleRights = await verify_user_rights_with_roles(action, current_user.user_id, org_id)
|
||||
|
||||
if not hasRoleRights and not isOwner:
|
||||
raise HTTPException(
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import json
|
|||
from typing import List
|
||||
from uuid import uuid4
|
||||
from pydantic import BaseModel
|
||||
from src.services.users import User
|
||||
from src.services.users import PublicUser, User
|
||||
from src.services.database import check_database, learnhouseDB, learnhouseDB
|
||||
from src.services.security import *
|
||||
from src.services.houses import House
|
||||
|
|
@ -25,7 +25,7 @@ class Elements(BaseModel):
|
|||
houses: List[str]
|
||||
collections: List[str]
|
||||
organizations: List[str]
|
||||
coursechapters : List[str]
|
||||
coursechapters: List[str]
|
||||
|
||||
|
||||
class Role(BaseModel):
|
||||
|
|
@ -69,7 +69,7 @@ async def create_role(role_object: Role, current_user: User):
|
|||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="Role name already exists")
|
||||
|
||||
await verify_user_permissions("create", current_user)
|
||||
await verify_user_permissions_on_roles("create", current_user)
|
||||
|
||||
# generate house_id with uuid4
|
||||
role_id = str(f"role_{uuid4()}")
|
||||
|
|
@ -90,7 +90,7 @@ async def update_role(role_object: House, role_id: str, current_user: User):
|
|||
await check_database()
|
||||
|
||||
# verify house rights
|
||||
await verify_user_permissions("update", current_user)
|
||||
await verify_user_permissions_on_roles("update", current_user)
|
||||
|
||||
roles = learnhouseDB["roles"]
|
||||
|
||||
|
|
@ -112,7 +112,7 @@ async def delete_role(role_id: str, current_user: User):
|
|||
await check_database()
|
||||
|
||||
# verify house rights
|
||||
await verify_user_permissions("delete", current_user)
|
||||
await verify_user_permissions_on_roles("delete", current_user)
|
||||
|
||||
roles = learnhouseDB["roles"]
|
||||
|
||||
|
|
@ -143,11 +143,11 @@ async def get_roles(page: int = 1, limit: int = 10):
|
|||
|
||||
#### Security ####################################################
|
||||
|
||||
async def verify_user_permissions(action: str, current_user: User):
|
||||
async def verify_user_permissions_on_roles(action: str, current_user: PublicUser):
|
||||
await check_database()
|
||||
users = learnhouseDB["users"]
|
||||
|
||||
user = users.find_one({"username": current_user.username})
|
||||
user = users.find_one({"user_id": current_user.user_id})
|
||||
|
||||
if not user:
|
||||
raise HTTPException(
|
||||
|
|
@ -155,8 +155,8 @@ async def verify_user_permissions(action: str, current_user: User):
|
|||
|
||||
isOwner = "owner" in user["user_type"]
|
||||
isEditor = "editor" in user["user_type"]
|
||||
|
||||
# TODO: verify for all actions.
|
||||
|
||||
# TODO: verify for all actions.
|
||||
if action == "delete":
|
||||
if isEditor:
|
||||
raise HTTPException(
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from uuid import uuid4
|
||||
from pydantic import BaseModel
|
||||
from src.services.database import check_database, learnhouseDB, learnhouseDB
|
||||
from src.services.security import *
|
||||
|
|
@ -14,17 +15,30 @@ class User(BaseModel):
|
|||
disabled: bool | None = None
|
||||
avatar_url: str | None = None
|
||||
verified: bool
|
||||
created_date: str
|
||||
user_type: str
|
||||
bio: str | None = None
|
||||
|
||||
|
||||
class UserInDB(User):
|
||||
class UserWithPassword(User):
|
||||
password: str
|
||||
|
||||
|
||||
class PublicUser(User):
|
||||
user_id: str
|
||||
creationDate: str
|
||||
updateDate: str
|
||||
|
||||
|
||||
class UserInDB(UserWithPassword):
|
||||
user_id: str
|
||||
password: str
|
||||
creationDate: str
|
||||
updateDate: str
|
||||
|
||||
#### Classes ####################################################
|
||||
|
||||
# TODO : user actions security
|
||||
# TODO : user actions security
|
||||
|
||||
|
||||
async def get_user(username: str):
|
||||
check_database()
|
||||
|
|
@ -40,6 +54,20 @@ async def get_user(username: str):
|
|||
return user
|
||||
|
||||
|
||||
async def get_user_by_userid(user_id: str):
|
||||
check_database()
|
||||
users = learnhouseDB["users"]
|
||||
|
||||
user = users.find_one({"user_id": user_id})
|
||||
|
||||
if not user:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="User does not exist")
|
||||
|
||||
user = User(**user)
|
||||
return user
|
||||
|
||||
|
||||
async def security_get_user(username: str):
|
||||
check_database()
|
||||
users = learnhouseDB["users"]
|
||||
|
|
@ -53,40 +81,58 @@ async def security_get_user(username: str):
|
|||
return UserInDB(**user)
|
||||
|
||||
|
||||
async def update_user(user_object: UserInDB):
|
||||
async def get_userid_by_username(username: str):
|
||||
check_database()
|
||||
users = learnhouseDB["users"]
|
||||
|
||||
isUserAvailable = users.find_one({"username": user_object.username})
|
||||
user = users.find_one({"username": username})
|
||||
|
||||
if not isUserAvailable:
|
||||
if not user:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="User does not exist")
|
||||
|
||||
return user["user_id"]
|
||||
|
||||
|
||||
async def update_user(user_id: str, user_object: UserWithPassword):
|
||||
check_database()
|
||||
users = learnhouseDB["users"]
|
||||
|
||||
isUserExists = users.find_one({"user_id": user_id})
|
||||
isUsernameAvailable = users.find_one({"username": user_object.username})
|
||||
|
||||
if not isUserExists:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="User does not exist")
|
||||
|
||||
if isUsernameAvailable:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="Username already used")
|
||||
|
||||
user_object.password = await security_hash_password(user_object.password)
|
||||
|
||||
updated_user = {"$set": user_object.dict()}
|
||||
users.update_one({"username": user_object.username}, updated_user)
|
||||
users.update_one({"user_id": user_id}, updated_user)
|
||||
|
||||
return User(**user_object.dict())
|
||||
|
||||
|
||||
async def delete_user(username: str):
|
||||
async def delete_user(user_id: str):
|
||||
check_database()
|
||||
users = learnhouseDB["users"]
|
||||
|
||||
isUserAvailable = users.find_one({"username": username})
|
||||
isUserAvailable = users.find_one({"user_id": user_id})
|
||||
|
||||
if not isUserAvailable:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="User does not exist")
|
||||
|
||||
users.delete_one({"username": username})
|
||||
users.delete_one({"user_id": user_id})
|
||||
|
||||
return {"detail": "User deleted"}
|
||||
|
||||
|
||||
async def create_user(user_object: UserInDB):
|
||||
async def create_user(user_object: UserWithPassword):
|
||||
check_database()
|
||||
users = learnhouseDB["users"]
|
||||
|
||||
|
|
@ -94,15 +140,19 @@ async def create_user(user_object: UserInDB):
|
|||
|
||||
if isUserAvailable:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT, detail="User already exists")
|
||||
status_code=status.HTTP_409_CONFLICT, detail="Username already exists")
|
||||
|
||||
# generate house_id with uuid4
|
||||
user_id = str(f"user_{uuid4()}")
|
||||
|
||||
# lowercase username
|
||||
user_object.username = user_object.username.lower()
|
||||
|
||||
user_object.created_date = str(datetime.now())
|
||||
|
||||
user_object.password = await security_hash_password(user_object.password)
|
||||
|
||||
users.insert_one(user_object.dict())
|
||||
user = UserInDB(user_id=user_id, creationDate=str(datetime.now()),
|
||||
updateDate=str(datetime.now()), **user_object.dict())
|
||||
|
||||
return User(**user_object.dict())
|
||||
user_in_db = users.insert_one(user.dict())
|
||||
|
||||
return User(**user.dict())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue