added functional groups api + started pictures
This commit is contained in:
@ -22,6 +22,11 @@ async def add_admin(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
if db.check_user_existence(conn, username):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="User already exists",
|
||||
)
|
||||
hashed_password = get_password_hash(password)
|
||||
return db.create_user(conn, username, hashed_password, "admin")
|
||||
|
||||
@ -36,5 +41,10 @@ async def add_user(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
if db.check_user_existence(conn, username):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="User already exists",
|
||||
)
|
||||
hashed_password = get_password_hash(password)
|
||||
return db.create_user(conn, username, hashed_password, "user")
|
||||
|
||||
@ -8,6 +8,7 @@ from psycopg2._psycopg import connection
|
||||
from api.models import Token
|
||||
from api.utils import authenticate_user, create_access_token
|
||||
from db.internal import get_db_connection
|
||||
from db.users import check_user_disabled
|
||||
from settings import startup_settings
|
||||
|
||||
auth_router = APIRouter(prefix="/api", tags=["auth"])
|
||||
@ -26,6 +27,14 @@ async def login(
|
||||
headers={"WWW-Authenticate": "Bearer"},
|
||||
)
|
||||
|
||||
user_disabled = check_user_disabled(conn, form_data.username)
|
||||
if user_disabled:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="User acoount is disabled",
|
||||
headers={"WWW-Authenticate": "Bearer"},
|
||||
)
|
||||
|
||||
access_token_expire_time = timedelta(minutes=startup_settings.access_token_expiration_time)
|
||||
access_token = create_access_token(
|
||||
data={"sub": form_data.username}, expires_delta=access_token_expire_time
|
||||
|
||||
0
src/api/feeds.py
Normal file
0
src/api/feeds.py
Normal file
@ -10,17 +10,22 @@ from settings.settings import load_settings, reset_settings, save_settings
|
||||
general_router = APIRouter(prefix="/api", tags=["general"])
|
||||
|
||||
|
||||
@general_router.get('/ping')
|
||||
@general_router.get("/ping")
|
||||
async def ping():
|
||||
return {'ok'}
|
||||
return {"ok"}
|
||||
|
||||
|
||||
@general_router.get('/settings/get')
|
||||
async def get_settings():
|
||||
@general_router.get("/settings/get")
|
||||
async def get_settings(current_user: Annotated[User, Depends(get_current_user)]):
|
||||
if current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
return settings.settings
|
||||
|
||||
|
||||
@general_router.post('/settings/update')
|
||||
@general_router.post("/settings/update")
|
||||
async def update_settings(data: dict, current_user: Annotated[User, Depends(get_current_user)]):
|
||||
if current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
@ -32,7 +37,7 @@ async def update_settings(data: dict, current_user: Annotated[User, Depends(get_
|
||||
return settings.settings
|
||||
|
||||
|
||||
@general_router.get('/settings/reset')
|
||||
@general_router.get("/settings/reset")
|
||||
async def reset_settings_api(current_user: Annotated[User, Depends(get_current_user)]):
|
||||
if current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
@ -43,7 +48,7 @@ async def reset_settings_api(current_user: Annotated[User, Depends(get_current_u
|
||||
return settings.settings
|
||||
|
||||
|
||||
@general_router.get('/settings/load_from_file')
|
||||
@general_router.get("/settings/load_from_file")
|
||||
async def load_settings_api(current_user: Annotated[User, Depends(get_current_user)]):
|
||||
if current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
@ -53,7 +58,7 @@ async def load_settings_api(current_user: Annotated[User, Depends(get_current_us
|
||||
load_settings()
|
||||
return settings.settings
|
||||
|
||||
@general_router.get('/settings/save_to_file')
|
||||
@general_router.get("/settings/save_to_file")
|
||||
async def save_settings_api(current_user: Annotated[User, Depends(get_current_user)]):
|
||||
if current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
|
||||
@ -1,24 +1,24 @@
|
||||
import secrets
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from psycopg2._psycopg import connection
|
||||
|
||||
import db.users as db
|
||||
import db.groups as db
|
||||
import settings.settings as settings
|
||||
from api.models import User
|
||||
from api.utils import get_current_user
|
||||
import settings.startup_settings as startup_settings
|
||||
from api.models import Group, User
|
||||
from api.utils import get_current_user, get_group_by_name
|
||||
from db.internal import get_db_connection
|
||||
from db.memberships import check_membership_exists
|
||||
from settings.consts import JOIN_CODE_SYMBOLS
|
||||
|
||||
groups_router = APIRouter(prefix="/api/groups", tags=["groups"])
|
||||
|
||||
|
||||
@groups_router.get("/my")
|
||||
async def read_users_groups(current_user: Annotated[User, Depends(get_current_user)]):
|
||||
return current_user
|
||||
|
||||
@groups_router.post("/user")
|
||||
async def read_users_any_groups(
|
||||
username: str,
|
||||
@groups_router.post("/group")
|
||||
async def read_any_group(
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
@ -27,46 +27,186 @@ async def read_users_any_groups(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
user = User()
|
||||
user_data = db.get_user(conn, username)
|
||||
if user_data is None:
|
||||
group = Group()
|
||||
group_data = db.get_group(conn, groupname)
|
||||
if group_data is None:
|
||||
return HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No such user",
|
||||
detail="No such group",
|
||||
)
|
||||
user.fill(user_data)
|
||||
return user
|
||||
group.fill(group_data)
|
||||
return group
|
||||
|
||||
@groups_router.post("/invite_code")
|
||||
async def read_group_invite_code(
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if not check_membership_exists(conn, current_user.username, groupname) and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
invite_code = db.get_group_invite_code(conn, groupname)
|
||||
if invite_code is None:
|
||||
return HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No such group",
|
||||
)
|
||||
return invite_code
|
||||
|
||||
|
||||
@groups_router.post("/add")
|
||||
async def add_group(
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
current_user: Annotated[User, Depends(get_current_user)],
|
||||
groupname: str,
|
||||
allow_skips: bool = True,
|
||||
feed_interval_minutes: int = 1440,
|
||||
):
|
||||
# TODO
|
||||
pass
|
||||
# if not settings.settings.allow_create_admins_by_admins:
|
||||
# if current_user.role not in settings.settings.admin_roles:
|
||||
# raise HTTPException(
|
||||
# status_code=status.HTTP_403_FORBIDDEN,
|
||||
# detail="Not allowed",
|
||||
# )
|
||||
# return db.create_user(conn, username, hashed_password, "admin")
|
||||
if not settings.settings.allow_create_groups and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
if db.check_group_existence(conn, groupname):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="Group already exists",
|
||||
)
|
||||
|
||||
invite_code = "".join(secrets.choice(JOIN_CODE_SYMBOLS) for _ in range(startup_settings.join_code_length))
|
||||
while db.check_invite_code(conn, invite_code):
|
||||
invite_code = "".join(secrets.choice(JOIN_CODE_SYMBOLS) for _ in range(startup_settings.join_code_length))
|
||||
return {
|
||||
"result": db.create_group(conn, groupname, invite_code, current_user.username, allow_skips, feed_interval_minutes),
|
||||
"invite code": invite_code
|
||||
}
|
||||
|
||||
@groups_router.post("/delete")
|
||||
async def delete_user(
|
||||
async def delete_group(
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
# TODO
|
||||
pass
|
||||
# if current_user.username == username or current_user.role in settings.settings.admin_roles:
|
||||
# return db.delete_user(conn, groupname)
|
||||
# else:
|
||||
# raise HTTPException(
|
||||
# status_code=status.HTTP_403_FORBIDDEN,
|
||||
# detail="Not allowed",
|
||||
# )
|
||||
group = get_group_by_name(conn, groupname)
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.delete_group(conn, groupname)
|
||||
if current_user.username == group.author:
|
||||
return db.delete_group(conn, groupname)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
|
||||
@groups_router.post("/update/groupname")
|
||||
async def update_groupname(
|
||||
groupname: str,
|
||||
new_groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if db.check_group_existence(conn, new_groupname):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="Groupname is already taken",
|
||||
)
|
||||
group = get_group_by_name(conn, groupname)
|
||||
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.update_group_groupname(conn, groupname, new_groupname)
|
||||
if current_user.username == group.author:
|
||||
return db.update_group_groupname(conn, groupname, new_groupname)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
@groups_router.post("/update/author")
|
||||
async def update_author(
|
||||
groupname: str,
|
||||
new_author: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
group = get_group_by_name(conn, groupname)
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.update_group_author(conn, groupname, new_author)
|
||||
if current_user.username == group.author:
|
||||
return db.update_group_author(conn, groupname, new_author)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
@groups_router.get("/update/invite_code")
|
||||
async def update_invite_code(
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
group = get_group_by_name(conn, groupname)
|
||||
|
||||
invite_code = "".join(secrets.choice(JOIN_CODE_SYMBOLS) for _ in range(startup_settings.join_code_length))
|
||||
while db.check_invite_code(conn, invite_code):
|
||||
invite_code = "".join(secrets.choice(JOIN_CODE_SYMBOLS) for _ in range(startup_settings.join_code_length))
|
||||
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return {
|
||||
"result": db.update_group_invite_code(conn, groupname, invite_code),
|
||||
"invite code": invite_code
|
||||
}
|
||||
if current_user.username == group.author:
|
||||
return {
|
||||
"result": db.update_group_invite_code(conn, groupname, invite_code),
|
||||
"invite code": invite_code
|
||||
}
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
|
||||
@groups_router.get("/update/allow_skips")
|
||||
async def update_allow_skips(
|
||||
groupname: str,
|
||||
allow_skips: bool,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
group = get_group_by_name(conn, groupname)
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.update_group_allow_skips(conn, groupname, allow_skips)
|
||||
if current_user.username == group.author:
|
||||
return db.update_group_allow_skips(conn, groupname, allow_skips)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
|
||||
@groups_router.get("/update/feed_interval")
|
||||
async def update_feed_interval(
|
||||
groupname: str,
|
||||
feed_interval: int,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
group = get_group_by_name(conn, groupname)
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.update_group_feed_interval(conn, groupname, feed_interval)
|
||||
if current_user.username == group.author:
|
||||
return db.update_group_feed_interval(conn, groupname, feed_interval)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
117
src/api/memberships.py
Normal file
117
src/api/memberships.py
Normal file
@ -0,0 +1,117 @@
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from psycopg2._psycopg import connection
|
||||
|
||||
import db.memberships as db
|
||||
import settings.settings as settings
|
||||
from api.models import User
|
||||
from api.utils import get_current_user, get_group_by_name
|
||||
from db.groups import check_group_existence, get_groupname_by_invite_code
|
||||
from db.internal import get_db_connection
|
||||
from db.users import check_user_existence
|
||||
|
||||
memberships_router = APIRouter(prefix="/api/membership", tags=["memberships"])
|
||||
|
||||
|
||||
@memberships_router.get("/me")
|
||||
async def read_users_groups(
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
return db.get_memberships_by_username(conn, current_user.username)
|
||||
|
||||
@memberships_router.post("/user")
|
||||
async def read_users_any_memberships(
|
||||
username: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if not check_user_existence(conn, username):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="User does not exist",
|
||||
)
|
||||
|
||||
if not username == current_user.username and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
return db.get_memberships_by_username(conn, username)
|
||||
|
||||
@memberships_router.post("/group")
|
||||
async def read_any_group_members(
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
user_is_in_group = db.check_membership_exists(conn, current_user.username, groupname)
|
||||
if not user_is_in_group and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
if not check_group_existence(conn, groupname):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No such group",
|
||||
)
|
||||
|
||||
return db.get_memberships_by_groupname(conn, groupname)
|
||||
|
||||
|
||||
@memberships_router.post("/add")
|
||||
async def add_membership(
|
||||
username: str,
|
||||
invite_code: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if username != current_user.username and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
groupname = get_groupname_by_invite_code(conn, invite_code)
|
||||
if groupname is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Invite code is incorrect",
|
||||
)
|
||||
|
||||
if not check_user_existence(conn, username):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="User does not exist",
|
||||
)
|
||||
|
||||
if db.check_membership_exists(conn, username, groupname):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="User is already a member",
|
||||
)
|
||||
|
||||
return db.create_membership(conn, username, groupname)
|
||||
|
||||
@memberships_router.post("/delete")
|
||||
async def delete_membership(
|
||||
username: str,
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.delete_membership(conn, username, groupname)
|
||||
|
||||
group = get_group_by_name(conn, groupname)
|
||||
if current_user.username == group.author:
|
||||
return db.delete_membership(conn, username, groupname)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
@ -14,17 +14,61 @@ class TokenData(BaseModel):
|
||||
|
||||
class User(BaseModel):
|
||||
def fill(self, params):
|
||||
self.username = params['username']
|
||||
self.password = params['password']
|
||||
self.role = params['role']
|
||||
self.disabled = params['disabled']
|
||||
self.groups_ids = params['groups_ids']
|
||||
self.last_seen_at = params['last_seen_at']
|
||||
self.created_at = params['created_at']
|
||||
username: str = ''
|
||||
password: str = ''
|
||||
role: str = 'user'
|
||||
self.username = params["username"]
|
||||
self.password = params["password"]
|
||||
self.role = params["role"]
|
||||
self.disabled = params["disabled"]
|
||||
self.groups_ids = params["groups_ids"]
|
||||
self.last_seen_at = params["last_seen_at"]
|
||||
self.created_at = params["created_at"]
|
||||
username: str = ""
|
||||
password: str = ""
|
||||
role: str = "user"
|
||||
disabled: bool = False
|
||||
groups_ids: list[str] | None = None
|
||||
last_seen_at: datetime | None = None
|
||||
created_at: datetime | None = None
|
||||
|
||||
|
||||
class Group(BaseModel):
|
||||
def fill(self, params):
|
||||
self.groupname = params["groupname"]
|
||||
self.author = params["author"]
|
||||
self.invite_code = params["invite_code"]
|
||||
self.allow_skips = params["allow_skips"]
|
||||
self.feed_interval_minutes = params["feed_interval_minutes"]
|
||||
self.last_feed_id = params["last_feed_id"]
|
||||
self.created_at = params["created_at"]
|
||||
groupname: str = ""
|
||||
author: str = ""
|
||||
invite_code: str = ""
|
||||
allow_skips: bool = True
|
||||
feed_interval_minutes: int = 1440
|
||||
last_feed_id: int | None = None
|
||||
created_at: datetime | None = None
|
||||
|
||||
|
||||
class Membership(BaseModel):
|
||||
def fill(self, params):
|
||||
self.groupname = params["groupname"]
|
||||
self.username = params["username"]
|
||||
self.joined_at = params["joined_at"]
|
||||
groupname: str = ""
|
||||
username: str = ""
|
||||
joined_at: datetime | None = None
|
||||
|
||||
|
||||
class Picture(BaseModel):
|
||||
def fill(self, params):
|
||||
self.id = params["id"]
|
||||
self.source = params["source"]
|
||||
self.external_id = params["external_id"]
|
||||
self.url = params["url"]
|
||||
self.metadata = params["metadata"]
|
||||
self.created_at = params["created_at"]
|
||||
id: int = -1
|
||||
source: str = ""
|
||||
external_id: str = ""
|
||||
url: str = ""
|
||||
metadata: dict | None = None
|
||||
created_at: datetime | None = None
|
||||
|
||||
103
src/api/pictures.py
Normal file
103
src/api/pictures.py
Normal file
@ -0,0 +1,103 @@
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from psycopg2._psycopg import connection
|
||||
|
||||
import db.pictures as db
|
||||
import settings.settings as settings
|
||||
from api.models import Picture, User
|
||||
from api.utils import get_current_user
|
||||
from db.internal import get_db_connection
|
||||
|
||||
pictures_router = APIRouter(prefix="/api/pictures", tags=["pictures"])
|
||||
|
||||
|
||||
# maybe to delete
|
||||
@pictures_router.post("/picture/url")
|
||||
async def read_picture_by_url(
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
picture = Picture()
|
||||
picture_data = db.get_picture_by_url(conn, groupname)
|
||||
if picture_data is None:
|
||||
return HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No such picture",
|
||||
)
|
||||
picture.fill(picture_data)
|
||||
return picture
|
||||
|
||||
|
||||
@pictures_router.post("/picture/id")
|
||||
async def read_picture_by_id(
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
picture = Picture()
|
||||
picture_data = db.get_picture_by_id(conn, groupname)
|
||||
if picture_data is None:
|
||||
return HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No such picture",
|
||||
)
|
||||
picture.fill(picture_data)
|
||||
return picture
|
||||
|
||||
|
||||
@pictures_router.post("/add")
|
||||
async def add_picture(
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)],
|
||||
source: str,
|
||||
external_id: str,
|
||||
url: str,
|
||||
metadata: dict
|
||||
):
|
||||
if not settings.settings.allow_create_pictures and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
# if db.check_picture_existence(conn, groupname):
|
||||
# raise HTTPException(
|
||||
# status_code=status.HTTP_409_CONFLICT,
|
||||
# detail="Picture already exists",
|
||||
# )
|
||||
|
||||
return {
|
||||
"id": db.create_picture(conn, source, external_id, url, metadata)
|
||||
}
|
||||
|
||||
|
||||
# maybe to delete
|
||||
@pictures_router.post("/delete/url")
|
||||
async def delete_picture_by_url(
|
||||
picture_url: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.delete_picture_by_url(conn, picture_url)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
@pictures_router.post("/delete/id")
|
||||
async def delete_picture_by_id(
|
||||
picture_id: int,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.delete_picture_by_id(conn, picture_id)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
@ -46,11 +46,20 @@ async def add_admin(
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if not settings.settings.allow_create_admins_by_admins:
|
||||
if current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
if current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
if db.check_user_existence(conn, username):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="User already exists",
|
||||
)
|
||||
hashed_password = get_password_hash(password)
|
||||
return db.create_user(conn, username, hashed_password, "admin")
|
||||
|
||||
@ -61,11 +70,16 @@ async def add_user(
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if not settings.settings.allow_create_users or current_user.role not in settings.settings.admin_roles:
|
||||
if not settings.settings.allow_create_users and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
if db.check_user_existence(conn, username):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="User already exists",
|
||||
)
|
||||
hashed_password = get_password_hash(password)
|
||||
return db.create_user(conn, username, hashed_password, "user")
|
||||
|
||||
@ -119,12 +133,17 @@ async def update_role(
|
||||
@users_router.post("/update/username")
|
||||
async def update_username(
|
||||
username: str,
|
||||
password: str,
|
||||
new_username: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if db.check_user_existence(conn, new_username):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="Username is already taken",
|
||||
)
|
||||
if current_user.username == username or current_user.role in settings.settings.admin_roles:
|
||||
return db.update_user_username(conn, username, password)
|
||||
return db.update_user_username(conn, username, new_username)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
|
||||
@ -10,9 +10,10 @@ from jwt.exceptions import InvalidTokenError
|
||||
# from passlib.context import CryptContext
|
||||
from psycopg2._psycopg import connection
|
||||
|
||||
import db.groups
|
||||
import db.users
|
||||
import settings.startup_settings as startup_settings
|
||||
from api.models import TokenData, User
|
||||
from api.models import Group, TokenData, User
|
||||
from db.internal import get_db_connection
|
||||
|
||||
# pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
||||
@ -38,9 +39,13 @@ def authenticate_user(
|
||||
username: str,
|
||||
user_password: str
|
||||
):
|
||||
db_user_password = db.users.get_user_password(conn, username)
|
||||
if not user_password:
|
||||
return False
|
||||
|
||||
db_user_password = db.users.get_user_password(conn, username)
|
||||
if db_user_password is None:
|
||||
return False
|
||||
|
||||
if not verify_password(user_password, db_user_password):
|
||||
return False
|
||||
return True
|
||||
@ -64,7 +69,7 @@ async def get_current_user(
|
||||
credentials_exception = HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Could not validate credentials",
|
||||
headers={"WWW-Authenticate": "Bearer"},
|
||||
headers={"WWW-Authenticate": "Bearer"}
|
||||
)
|
||||
|
||||
try:
|
||||
@ -90,3 +95,19 @@ async def get_current_user(
|
||||
)
|
||||
|
||||
return user
|
||||
|
||||
def get_group_by_name(
|
||||
conn: connection,
|
||||
groupname: str
|
||||
):
|
||||
group_exception = HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No such group"
|
||||
)
|
||||
group = Group()
|
||||
group_data = db.groups.get_group(conn, groupname)
|
||||
if group_data is None:
|
||||
raise group_exception
|
||||
|
||||
group.fill(group_data)
|
||||
return group
|
||||
|
||||
Reference in New Issue
Block a user