From 9ff5eeb3673d89c8e745283d1dba2143f7248edf Mon Sep 17 00:00:00 2001 From: zurdi Date: Thu, 4 Jul 2024 21:19:20 +0200 Subject: [PATCH 01/12] modified update user endpoint to allow own edition --- backend/endpoints/user.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/backend/endpoints/user.py b/backend/endpoints/user.py index 4abfd83df..6a89246ad 100644 --- a/backend/endpoints/user.py +++ b/backend/endpoints/user.py @@ -89,7 +89,7 @@ def get_user(request: Request, id: int) -> UserSchema: return user -@protected_route(router.put, "/users/{id}", ["users.write"]) +@protected_route(router.put, "/users/{id}") def update_user( request: Request, id: int, form_data: Annotated[UserForm, Depends()] ) -> UserSchema: @@ -108,17 +108,23 @@ def update_user( UserSchema: Updated user info """ - user = db_user_handler.get_user(id) - if not user: - raise HTTPException(status_code=404, detail="User not found") + db_user = db_user_handler.get_user(id) + if not db_user: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail="User not found" + ) + + if not db_user.id == request.user.id: + raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Forbidden") cleaned_data = {} - if form_data.username and form_data.username != user.username: + if form_data.username and form_data.username != db_user.username: existing_user = db_user_handler.get_user_by_username(form_data.username.lower()) if existing_user: raise HTTPException( - status_code=400, detail="Username already in use by another user" + status_code=status.HTTP_400_BAD_REQUEST, + detail="Username already in use by another user", ) cleaned_data["username"] = form_data.username.lower() @@ -137,7 +143,7 @@ def update_user( cleaned_data["enabled"] = form_data.enabled # type: ignore[assignment] if form_data.avatar is not None: - user_avatar_path = fs_asset_handler.build_avatar_path(user=user) + user_avatar_path = fs_asset_handler.build_avatar_path(user=db_user) file_location = f"{user_avatar_path}/{form_data.avatar.filename}" cleaned_data["avatar_path"] = file_location Path(f"{ASSETS_BASE_PATH}/{user_avatar_path}").mkdir( From ca5210a71631248aac01c38f43f46b96217e83b8 Mon Sep 17 00:00:00 2001 From: zurdi Date: Thu, 4 Jul 2024 22:11:32 +0200 Subject: [PATCH 02/12] added new profile option in the settings drawer --- .../src/components/common/Navigation/SettingsDrawer.vue | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frontend/src/components/common/Navigation/SettingsDrawer.vue b/frontend/src/components/common/Navigation/SettingsDrawer.vue index b0bac4978..067e78e04 100644 --- a/frontend/src/components/common/Navigation/SettingsDrawer.vue +++ b/frontend/src/components/common/Navigation/SettingsDrawer.vue @@ -1,4 +1,5 @@ diff --git a/frontend/src/views/Setup.vue b/frontend/src/views/Setup.vue index 73a3d66d6..6ff50a901 100644 --- a/frontend/src/views/Setup.vue +++ b/frontend/src/views/Setup.vue @@ -4,6 +4,7 @@ import userApi from "@/services/api/user"; import storeHeartbeat from "@/stores/heartbeat"; import type { Events } from "@/types/emitter"; import type { Emitter } from "mitt"; +import { useRoute } from "vue-router"; import { computed, inject, ref } from "vue"; import { useDisplay } from "vuetify"; @@ -11,6 +12,7 @@ import { useDisplay } from "vuetify"; const { xs, smAndDown } = useDisplay(); const emitter = inject>("emitter"); const heartbeat = storeHeartbeat(); +const route = useRoute() const visiblePassword = ref(false); // Use a computed property to reactively update metadataOptions based on heartbeat const metadataOptions = computed(() => [ @@ -71,7 +73,7 @@ async function finishWizard() { - + @@ -106,7 +108,7 @@ async function finishWizard() { - Create admin user + Create an admin user @@ -119,7 +121,6 @@ async function finishWizard() { type="text" label="Username" variant="underlined" - @keyup.enter="" /> Date: Thu, 4 Jul 2024 23:45:44 +0200 Subject: [PATCH 05/12] fixes from trunk --- backend/handler/auth/base_handler.py | 4 +--- backend/main.py | 2 -- frontend/src/services/api/index.ts | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/backend/handler/auth/base_handler.py b/backend/handler/auth/base_handler.py index 79bb7ae5e..60999e5ca 100644 --- a/backend/handler/auth/base_handler.py +++ b/backend/handler/auth/base_handler.py @@ -1,15 +1,13 @@ from datetime import datetime, timedelta from typing import Final -from config import ROMM_AUTH_PASSWORD, ROMM_AUTH_SECRET_KEY, ROMM_AUTH_USERNAME +from config import ROMM_AUTH_SECRET_KEY from exceptions.auth_exceptions import OAuthCredentialsException from fastapi import HTTPException, status from joserfc import jwt from joserfc.errors import BadSignatureError from joserfc.jwk import OctKey -from logger.logger import log from passlib.context import CryptContext -from sqlalchemy.exc import IntegrityError from starlette.requests import HTTPConnection ALGORITHM: Final = "HS256" diff --git a/backend/main.py b/backend/main.py index aac9f1aae..c1aac2d95 100644 --- a/backend/main.py +++ b/backend/main.py @@ -25,11 +25,9 @@ ) from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware -from handler.auth import auth_handler from handler.auth.base_handler import ALGORITHM from handler.auth.hybrid_auth import HybridAuthBackend from handler.auth.middleware import CustomCSRFMiddleware, SessionMiddleware -from handler.database import db_user_handler from handler.socket_handler import socket_handler from starlette.middleware.authentication import AuthenticationMiddleware from utils import get_version diff --git a/frontend/src/services/api/index.ts b/frontend/src/services/api/index.ts index 27741a99d..33adc1a67 100644 --- a/frontend/src/services/api/index.ts +++ b/frontend/src/services/api/index.ts @@ -39,7 +39,7 @@ api.interceptors.response.use( (error) => { if (error.response?.status === 403) { const allCookies = Cookies.get(); // Get all cookies - for (let cookie in allCookies) { + for (const cookie in allCookies) { Cookies.remove(cookie); // Remove each cookie } router.push({ From eda1c9486860ecf5a9989fe29c07e772ff2185a0 Mon Sep 17 00:00:00 2001 From: Zurdi Date: Fri, 5 Jul 2024 19:16:47 +0200 Subject: [PATCH 06/12] fixed user endpoint tests --- backend/endpoints/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/endpoints/user.py b/backend/endpoints/user.py index 6a89246ad..557896771 100644 --- a/backend/endpoints/user.py +++ b/backend/endpoints/user.py @@ -114,7 +114,7 @@ def update_user( status_code=status.HTTP_404_NOT_FOUND, detail="User not found" ) - if not db_user.id == request.user.id: + if not db_user.id == request.user.id and request.user.role != Role.ADMIN: raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Forbidden") cleaned_data = {} From 9ca60f28e6e4cf91e65a4f4bcbb849b00e974903 Mon Sep 17 00:00:00 2001 From: zurdi Date: Fri, 5 Jul 2024 00:04:14 +0200 Subject: [PATCH 07/12] fixed add to collection for non-admin users --- frontend/src/components/Details/ActionBar.vue | 8 +- .../src/components/common/Game/AdminMenu.vue | 82 ++++++++++--------- .../components/common/Game/Card/ActionBar.vue | 3 - frontend/src/components/common/Game/Table.vue | 8 +- 4 files changed, 46 insertions(+), 55 deletions(-) diff --git a/frontend/src/components/Details/ActionBar.vue b/frontend/src/components/Details/ActionBar.vue index f210dcf08..5c9140919 100644 --- a/frontend/src/components/Details/ActionBar.vue +++ b/frontend/src/components/Details/ActionBar.vue @@ -1,7 +1,6 @@ diff --git a/frontend/src/components/common/Game/Card/ActionBar.vue b/frontend/src/components/common/Game/Card/ActionBar.vue index c3b8e9720..618f54621 100644 --- a/frontend/src/components/common/Game/Card/ActionBar.vue +++ b/frontend/src/components/common/Game/Card/ActionBar.vue @@ -1,14 +1,12 @@ @@ -44,7 +42,6 @@ const downloadStore = storeDownload();