mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +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)
|
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("/")
|
@router.post("/")
|
||||||
async def api_create_user(user_object: UserInDB):
|
async def api_create_user(user_object: UserWithPassword):
|
||||||
"""
|
"""
|
||||||
Create new user
|
Create new user
|
||||||
"""
|
"""
|
||||||
return await create_user(user_object)
|
return await create_user(user_object)
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/username/{username}")
|
@router.delete("/user_id/{user_id}")
|
||||||
async def api_delete_user(username: str):
|
async def api_delete_user(user_id: str):
|
||||||
"""
|
"""
|
||||||
Delete user by ID
|
Delete user by ID
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return await delete_user(username)
|
return await delete_user(user_id)
|
||||||
|
|
||||||
|
|
||||||
@router.put("/username/{username}")
|
@router.put("/user_id/{user_id}")
|
||||||
async def api_update_user(user_object: UserInDB):
|
async def api_update_user(user_object: UserWithPassword, user_id: str):
|
||||||
"""
|
"""
|
||||||
Update user by ID
|
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 ####################################################
|
#### Classes ####################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def authenticate_user(username: str, password: str):
|
async def authenticate_user(username: str, password: str):
|
||||||
user = await security_get_user(username)
|
user = await security_get_user(username)
|
||||||
if not user:
|
if not user:
|
||||||
|
|
@ -58,7 +57,7 @@ async def get_current_user(token: str = Depends(oauth2_scheme)):
|
||||||
token_data = TokenData(username=username)
|
token_data = TokenData(username=username)
|
||||||
except JWTError:
|
except JWTError:
|
||||||
raise credentials_exception
|
raise credentials_exception
|
||||||
user = await get_user(username=token_data.username)
|
user = await security_get_user(username=token_data.username)
|
||||||
if user is None:
|
if user is None:
|
||||||
raise credentials_exception
|
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
|
# generate course_id with uuid4
|
||||||
course_id = str(f"course_{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:
|
if not hasRoleRights:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action")
|
status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action")
|
||||||
|
|
||||||
course = CourseInDB(course_id=course_id, authors=[
|
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())
|
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
|
# generate coursechapter_id with uuid4
|
||||||
coursechapter_id = str(f"coursechapter_{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:
|
if not hasRoleRights:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
@ -238,7 +238,7 @@ async def delete_coursechapter(coursechapter_id: str, current_user: User):
|
||||||
coursechapter = coursechapters.find_one(
|
coursechapter = coursechapters.find_one(
|
||||||
{"coursechapter_id": coursechapter_id})
|
{"coursechapter_id": coursechapter_id})
|
||||||
|
|
||||||
# verify course rights
|
# verify course rights
|
||||||
await verify_rights(coursechapter["course_id"], current_user, "delete")
|
await verify_rights(coursechapter["course_id"], current_user, "delete")
|
||||||
|
|
||||||
if not coursechapter:
|
if not coursechapter:
|
||||||
|
|
@ -278,8 +278,8 @@ async def verify_rights(course_id: str, current_user: User, action: str):
|
||||||
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(action, current_user.username, course_id)
|
hasRoleRights = await verify_user_rights_with_roles(action, current_user.user_id, course_id)
|
||||||
isAuthor = current_user.username in course["authors"]
|
isAuthor = current_user.user_id in course["authors"]
|
||||||
|
|
||||||
if not hasRoleRights and not isAuthor:
|
if not hasRoleRights and not isAuthor:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ async def get_house(house_id: str, current_user: User):
|
||||||
house = houses.find_one({"house_id": house_id})
|
house = houses.find_one({"house_id": house_id})
|
||||||
|
|
||||||
# verify house rights
|
# verify house rights
|
||||||
await verify_house_rights(house_id, current_user,"read")
|
await verify_house_rights(house_id, current_user, "read")
|
||||||
|
|
||||||
if not house:
|
if not house:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
@ -58,15 +58,15 @@ async def create_house(house_object: House, current_user: User):
|
||||||
# generate house_id with uuid4
|
# generate house_id with uuid4
|
||||||
house_id = str(f"house_{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:
|
if not hasRoleRights:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action")
|
status_code=status.HTTP_409_CONFLICT, detail="Roles : Insufficient rights to perform this action")
|
||||||
|
|
||||||
house = HouseInDB(house_id=house_id, owners=[
|
house = HouseInDB(house_id=house_id, owners=[
|
||||||
current_user.username], admins=[
|
current_user.user_id], admins=[
|
||||||
current_user.username], **house_object.dict())
|
current_user.user_id], **house_object.dict())
|
||||||
|
|
||||||
house_in_db = houses.insert_one(house.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()
|
await check_database()
|
||||||
|
|
||||||
# verify house rights
|
# verify house rights
|
||||||
await verify_house_rights(house_id, current_user,"update")
|
await verify_house_rights(house_id, current_user, "update")
|
||||||
|
|
||||||
houses = learnhouseDB["houses"]
|
houses = learnhouseDB["houses"]
|
||||||
|
|
||||||
|
|
@ -107,7 +107,7 @@ async def delete_house(house_id: str, current_user: User):
|
||||||
await check_database()
|
await check_database()
|
||||||
|
|
||||||
# verify house rights
|
# verify house rights
|
||||||
await verify_house_rights(house_id, current_user,"delete")
|
await verify_house_rights(house_id, current_user, "delete")
|
||||||
|
|
||||||
houses = learnhouseDB["houses"]
|
houses = learnhouseDB["houses"]
|
||||||
|
|
||||||
|
|
@ -148,8 +148,8 @@ async def verify_house_rights(house_id: str, current_user: User, action: str):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="House does not exist")
|
status_code=status.HTTP_409_CONFLICT, detail="House does not exist")
|
||||||
|
|
||||||
hasRoleRights = await verify_user_rights_with_roles(action, current_user.username, house_id)
|
hasRoleRights = await verify_user_rights_with_roles(action, current_user.user_id, house_id)
|
||||||
isOwner = current_user.username in house["owners"]
|
isOwner = current_user.user_id in house["owners"]
|
||||||
|
|
||||||
if not hasRoleRights and not isOwner:
|
if not hasRoleRights and not isOwner:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,8 @@ async def create_org(org_object: Organization, current_user: User):
|
||||||
org_id = str(f"org_{uuid4()}")
|
org_id = str(f"org_{uuid4()}")
|
||||||
|
|
||||||
org = OrganizationInDB(org_id=org_id, owners=[
|
org = OrganizationInDB(org_id=org_id, owners=[
|
||||||
current_user.username], admins=[
|
current_user.user_id], admins=[
|
||||||
current_user.username], **org_object.dict())
|
current_user.user_id], **org_object.dict())
|
||||||
|
|
||||||
org_in_db = orgs.insert_one(org.dict())
|
org_in_db = orgs.insert_one(org.dict())
|
||||||
|
|
||||||
|
|
@ -128,7 +128,7 @@ async def get_orgs(page: int = 1, limit: int = 10):
|
||||||
|
|
||||||
#### Security ####################################################
|
#### 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()
|
await check_database()
|
||||||
orgs = learnhouseDB["organizations"]
|
orgs = learnhouseDB["organizations"]
|
||||||
|
|
||||||
|
|
@ -138,8 +138,8 @@ async def verify_org_rights(org_id: str, current_user: User, action:str,):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="Organization does not exist")
|
status_code=status.HTTP_409_CONFLICT, detail="Organization does not exist")
|
||||||
|
|
||||||
isOwner = current_user.username in org["owners"]
|
isOwner = current_user.user_id in org["owners"]
|
||||||
hasRoleRights = await verify_user_rights_with_roles(action,current_user.username,org_id)
|
hasRoleRights = await verify_user_rights_with_roles(action, current_user.user_id, org_id)
|
||||||
|
|
||||||
if not hasRoleRights and not isOwner:
|
if not hasRoleRights and not isOwner:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import json
|
||||||
from typing import List
|
from typing import List
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from pydantic import BaseModel
|
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.database import check_database, learnhouseDB, learnhouseDB
|
||||||
from src.services.security import *
|
from src.services.security import *
|
||||||
from src.services.houses import House
|
from src.services.houses import House
|
||||||
|
|
@ -25,7 +25,7 @@ class Elements(BaseModel):
|
||||||
houses: List[str]
|
houses: List[str]
|
||||||
collections: List[str]
|
collections: List[str]
|
||||||
organizations: List[str]
|
organizations: List[str]
|
||||||
coursechapters : List[str]
|
coursechapters: List[str]
|
||||||
|
|
||||||
|
|
||||||
class Role(BaseModel):
|
class Role(BaseModel):
|
||||||
|
|
@ -69,7 +69,7 @@ async def create_role(role_object: Role, current_user: User):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="Role name already exists")
|
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
|
# generate house_id with uuid4
|
||||||
role_id = str(f"role_{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()
|
await check_database()
|
||||||
|
|
||||||
# verify house rights
|
# verify house rights
|
||||||
await verify_user_permissions("update", current_user)
|
await verify_user_permissions_on_roles("update", current_user)
|
||||||
|
|
||||||
roles = learnhouseDB["roles"]
|
roles = learnhouseDB["roles"]
|
||||||
|
|
||||||
|
|
@ -112,7 +112,7 @@ async def delete_role(role_id: str, current_user: User):
|
||||||
await check_database()
|
await check_database()
|
||||||
|
|
||||||
# verify house rights
|
# verify house rights
|
||||||
await verify_user_permissions("delete", current_user)
|
await verify_user_permissions_on_roles("delete", current_user)
|
||||||
|
|
||||||
roles = learnhouseDB["roles"]
|
roles = learnhouseDB["roles"]
|
||||||
|
|
||||||
|
|
@ -143,11 +143,11 @@ async def get_roles(page: int = 1, limit: int = 10):
|
||||||
|
|
||||||
#### Security ####################################################
|
#### 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()
|
await check_database()
|
||||||
users = learnhouseDB["users"]
|
users = learnhouseDB["users"]
|
||||||
|
|
||||||
user = users.find_one({"username": current_user.username})
|
user = users.find_one({"user_id": current_user.user_id})
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
from uuid import uuid4
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from src.services.database import check_database, learnhouseDB, learnhouseDB
|
from src.services.database import check_database, learnhouseDB, learnhouseDB
|
||||||
from src.services.security import *
|
from src.services.security import *
|
||||||
|
|
@ -14,18 +15,31 @@ class User(BaseModel):
|
||||||
disabled: bool | None = None
|
disabled: bool | None = None
|
||||||
avatar_url: str | None = None
|
avatar_url: str | None = None
|
||||||
verified: bool
|
verified: bool
|
||||||
created_date: str
|
|
||||||
user_type: str
|
user_type: str
|
||||||
bio: str | None = None
|
bio: str | None = None
|
||||||
|
|
||||||
|
|
||||||
class UserInDB(User):
|
class UserWithPassword(User):
|
||||||
password: str
|
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 ####################################################
|
#### Classes ####################################################
|
||||||
|
|
||||||
# TODO : user actions security
|
# TODO : user actions security
|
||||||
|
|
||||||
|
|
||||||
async def get_user(username: str):
|
async def get_user(username: str):
|
||||||
check_database()
|
check_database()
|
||||||
users = learnhouseDB["users"]
|
users = learnhouseDB["users"]
|
||||||
|
|
@ -40,6 +54,20 @@ async def get_user(username: str):
|
||||||
return user
|
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):
|
async def security_get_user(username: str):
|
||||||
check_database()
|
check_database()
|
||||||
users = learnhouseDB["users"]
|
users = learnhouseDB["users"]
|
||||||
|
|
@ -53,40 +81,58 @@ async def security_get_user(username: str):
|
||||||
return UserInDB(**user)
|
return UserInDB(**user)
|
||||||
|
|
||||||
|
|
||||||
async def update_user(user_object: UserInDB):
|
async def get_userid_by_username(username: str):
|
||||||
check_database()
|
check_database()
|
||||||
users = learnhouseDB["users"]
|
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(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="User does not exist")
|
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)
|
user_object.password = await security_hash_password(user_object.password)
|
||||||
|
|
||||||
updated_user = {"$set": user_object.dict()}
|
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())
|
return User(**user_object.dict())
|
||||||
|
|
||||||
|
|
||||||
async def delete_user(username: str):
|
async def delete_user(user_id: str):
|
||||||
check_database()
|
check_database()
|
||||||
users = learnhouseDB["users"]
|
users = learnhouseDB["users"]
|
||||||
|
|
||||||
isUserAvailable = users.find_one({"username": username})
|
isUserAvailable = users.find_one({"user_id": user_id})
|
||||||
|
|
||||||
if not isUserAvailable:
|
if not isUserAvailable:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_409_CONFLICT, detail="User does not exist")
|
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"}
|
return {"detail": "User deleted"}
|
||||||
|
|
||||||
|
|
||||||
async def create_user(user_object: UserInDB):
|
async def create_user(user_object: UserWithPassword):
|
||||||
check_database()
|
check_database()
|
||||||
users = learnhouseDB["users"]
|
users = learnhouseDB["users"]
|
||||||
|
|
||||||
|
|
@ -94,15 +140,19 @@ async def create_user(user_object: UserInDB):
|
||||||
|
|
||||||
if isUserAvailable:
|
if isUserAvailable:
|
||||||
raise HTTPException(
|
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
|
# lowercase username
|
||||||
user_object.username = user_object.username.lower()
|
user_object.username = user_object.username.lower()
|
||||||
|
|
||||||
user_object.created_date = str(datetime.now())
|
|
||||||
|
|
||||||
user_object.password = await security_hash_password(user_object.password)
|
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