From bb5bf3964e6ceda26c0cd734561547458ee50744 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Mon, 1 Jan 2024 12:32:28 -0800 Subject: [PATCH] feat: toggle signup enable from admin panel --- Dockerfile | 1 - backend/apps/web/main.py | 2 + backend/apps/web/routers/auths.py | 83 ++++++++++++++++++++--------- backend/apps/web/routers/users.py | 1 + src/lib/apis/auths/index.ts | 54 +++++++++++++++++++ src/routes/(app)/admin/+page.svelte | 56 ++++++++++++++++++- 6 files changed, 169 insertions(+), 28 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9521c600..2dd89813 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,7 +22,6 @@ ARG OLLAMA_API_BASE_URL='/ollama/api' ENV ENV=prod ENV OLLAMA_API_BASE_URL $OLLAMA_API_BASE_URL -ENV WEBUI_AUTH "" ENV WEBUI_JWT_SECRET_KEY "SECRET_KEY" WORKDIR /app diff --git a/backend/apps/web/main.py b/backend/apps/web/main.py index b3d90381..f62857b7 100644 --- a/backend/apps/web/main.py +++ b/backend/apps/web/main.py @@ -8,6 +8,8 @@ app = FastAPI() origins = ["*"] +app.state.ENABLE_SIGNUP = True + app.add_middleware( CORSMiddleware, allow_origins=origins, diff --git a/backend/apps/web/routers/auths.py b/backend/apps/web/routers/auths.py index 24e9f426..fb113989 100644 --- a/backend/apps/web/routers/auths.py +++ b/backend/apps/web/routers/auths.py @@ -1,4 +1,4 @@ -from fastapi import Response +from fastapi import Response, Request from fastapi import Depends, FastAPI, HTTPException, status from datetime import datetime, timedelta from typing import List, Union @@ -93,31 +93,62 @@ async def signin(form_data: SigninForm): @router.post("/signup", response_model=SigninResponse) -async def signup(form_data: SignupForm): - if not Users.get_user_by_email(form_data.email.lower()): - try: - role = "admin" if Users.get_num_users() == 0 else "pending" - hashed = get_password_hash(form_data.password) - user = Auths.insert_new_auth( - form_data.email.lower(), hashed, form_data.name, role - ) +async def signup(request: Request, form_data: SignupForm): + if request.app.state.ENABLE_SIGNUP: + if not Users.get_user_by_email(form_data.email.lower()): + try: + role = "admin" if Users.get_num_users() == 0 else "pending" + hashed = get_password_hash(form_data.password) + user = Auths.insert_new_auth( + form_data.email.lower(), hashed, form_data.name, role + ) - if user: - token = create_token(data={"email": user.email}) - # response.set_cookie(key='token', value=token, httponly=True) + if user: + token = create_token(data={"email": user.email}) + # response.set_cookie(key='token', value=token, httponly=True) - return { - "token": token, - "token_type": "Bearer", - "id": user.id, - "email": user.email, - "name": user.name, - "role": user.role, - "profile_image_url": user.profile_image_url, - } - else: - raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR) - except Exception as err: - raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err)) + return { + "token": token, + "token_type": "Bearer", + "id": user.id, + "email": user.email, + "name": user.name, + "role": user.role, + "profile_image_url": user.profile_image_url, + } + else: + raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR) + except Exception as err: + raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err)) + else: + raise HTTPException(400, detail=ERROR_MESSAGES.EMAIL_TAKEN) else: - raise HTTPException(400, detail=ERROR_MESSAGES.EMAIL_TAKEN) + raise HTTPException(400, detail=ERROR_MESSAGES.ACCESS_PROHIBITED) + + +############################ +# ToggleSignUp +############################ + + +@router.get("/signup/enabled", response_model=bool) +async def get_sign_up_status(request: Request, user=Depends(get_current_user)): + if user.role == "admin": + return request.app.state.ENABLE_SIGNUP + else: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) + + +@router.get("/signup/enabled/toggle", response_model=bool) +async def toggle_sign_up(request: Request, user=Depends(get_current_user)): + if user.role == "admin": + request.app.state.ENABLE_SIGNUP = not request.app.state.ENABLE_SIGNUP + return request.app.state.ENABLE_SIGNUP + else: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail=ERROR_MESSAGES.ACCESS_PROHIBITED, + ) diff --git a/backend/apps/web/routers/users.py b/backend/apps/web/routers/users.py index 950b23fa..b3b55268 100644 --- a/backend/apps/web/routers/users.py +++ b/backend/apps/web/routers/users.py @@ -15,6 +15,7 @@ from apps.web.models.auths import Auths from utils.utils import get_current_user from constants import ERROR_MESSAGES + router = APIRouter() ############################ diff --git a/src/lib/apis/auths/index.ts b/src/lib/apis/auths/index.ts index 73934055..8734a588 100644 --- a/src/lib/apis/auths/index.ts +++ b/src/lib/apis/auths/index.ts @@ -119,3 +119,57 @@ export const updateUserPassword = async (token: string, password: string, newPas return res; }; + +export const getSignUpEnabledStatus = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/signup/enabled`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const toggleSignUpEnabledStatus = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/auths/signup/enabled/toggle`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; diff --git a/src/routes/(app)/admin/+page.svelte b/src/routes/(app)/admin/+page.svelte index 5f5beeae..5e331c1a 100644 --- a/src/routes/(app)/admin/+page.svelte +++ b/src/routes/(app)/admin/+page.svelte @@ -7,10 +7,13 @@ import toast from 'svelte-french-toast'; import { updateUserRole, getUsers, deleteUserById } from '$lib/apis/users'; + import { getSignUpEnabledStatus, toggleSignUpEnabledStatus } from '$lib/apis/auths'; let loaded = false; let users = []; + let signUpEnabled = true; + const updateRoleHandler = async (id, role) => { const res = await updateUserRole(localStorage.token, id, role).catch((error) => { toast.error(error); @@ -32,11 +35,17 @@ } }; + const toggleSignUpEnabled = async () => { + signUpEnabled = await toggleSignUpEnabledStatus(localStorage.token); + }; + onMount(async () => { if ($user?.role !== 'admin') { await goto('/'); } else { users = await getUsers(localStorage.token); + + signUpEnabled = await getSignUpEnabledStatus(localStorage.token); } loaded = true; }); @@ -49,7 +58,52 @@
-
Users ({users.length})
+
+
Users ({users.length})
+
+ +
+
Click on the user role cell in the table to change a user's role.