Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
open-webui
Commits
fbd3854f
Unverified
Commit
fbd3854f
authored
Jan 01, 2024
by
Timothy Jaeryang Baek
Committed by
GitHub
Jan 01, 2024
Browse files
Merge pull request #338 from ollama-webui/disable-signup
feat: toggle signup enable from admin panel
parents
e2d74096
bb5bf396
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
171 additions
and
30 deletions
+171
-30
Dockerfile
Dockerfile
+0
-1
backend/apps/web/main.py
backend/apps/web/main.py
+2
-0
backend/apps/web/routers/auths.py
backend/apps/web/routers/auths.py
+59
-28
backend/apps/web/routers/users.py
backend/apps/web/routers/users.py
+1
-0
src/lib/apis/auths/index.ts
src/lib/apis/auths/index.ts
+54
-0
src/routes/(app)/admin/+page.svelte
src/routes/(app)/admin/+page.svelte
+55
-1
No files found.
Dockerfile
View file @
fbd3854f
...
...
@@ -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
...
...
backend/apps/web/main.py
View file @
fbd3854f
...
...
@@ -8,6 +8,8 @@ app = FastAPI()
origins
=
[
"*"
]
app
.
state
.
ENABLE_SIGNUP
=
True
app
.
add_middleware
(
CORSMiddleware
,
allow_origins
=
origins
,
...
...
backend/apps/web/routers/auths.py
View file @
fbd3854f
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
)
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
))
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)
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
.
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
(
400
,
detail
=
ERROR_MESSAGES
.
EMAIL_TAKEN
)
raise
HTTPException
(
status_code
=
status
.
HTTP_403_FORBIDDEN
,
detail
=
ERROR_MESSAGES
.
ACCESS_PROHIBITED
,
)
backend/apps/web/routers/users.py
View file @
fbd3854f
...
...
@@ -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
()
############################
...
...
src/lib/apis/auths/index.ts
View file @
fbd3854f
...
...
@@ -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
;
};
src/routes/(app)/admin/+page.svelte
View file @
fbd3854f
...
...
@@ -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 @@
<div class="w-full max-w-3xl px-10 md:px-16 min-h-screen flex flex-col">
<div class="py-10 w-full">
<div class=" flex flex-col justify-center">
<div class=" text-2xl font-semibold">Users ({users.length})</div>
<div class=" flex justify-between items-center">
<div class=" text-2xl font-semibold">Users ({users.length})</div>
<div>
<button
class="flex items-center space-x-1 border border-gray-200 px-3 py-1 rounded-lg"
type="button"
on:click={() => {
toggleSignUpEnabled();
}}
>
{#if signUpEnabled}
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="w-4 h-4"
>
<path
d="M11.5 1A3.5 3.5 0 0 0 8 4.5V7H2.5A1.5 1.5 0 0 0 1 8.5v5A1.5 1.5 0 0 0 2.5 15h7a1.5 1.5 0 0 0 1.5-1.5v-5A1.5 1.5 0 0 0 9.5 7V4.5a2 2 0 1 1 4 0v1.75a.75.75 0 0 0 1.5 0V4.5A3.5 3.5 0 0 0 11.5 1Z"
/>
</svg>
<div class=" text-xs">
New Sign Up <span class=" font-semibold">Enabled</span>
</div>
{:else}
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="w-4 h-4"
>
<path
fill-rule="evenodd"
d="M8 1a3.5 3.5 0 0 0-3.5 3.5V7A1.5 1.5 0 0 0 3 8.5v5A1.5 1.5 0 0 0 4.5 15h7a1.5 1.5 0 0 0 1.5-1.5v-5A1.5 1.5 0 0 0 11.5 7V4.5A3.5 3.5 0 0 0 8 1Zm2 6V4.5a2 2 0 1 0-4 0V7h4Z"
clip-rule="evenodd"
/>
</svg>
<div class=" text-xs">
New Sign Up <span class=" font-semibold">Disabled</span>
</div>
{/if}
</button>
</div>
</div>
<div class=" text-gray-500 text-xs font-medium mt-1">
Click on the user role cell in the table to change a user's role.
</div>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment