forked from open-webui/open-webui
		
	feat: basic RBAC support
This commit is contained in:
		
							parent
							
								
									921eef03b3
								
							
						
					
					
						commit
						8547b7807d
					
				
					 13 changed files with 266 additions and 44 deletions
				
			
		|  | @ -149,6 +149,10 @@ | |||
| 						if (data.error) { | ||||
| 							throw data.error; | ||||
| 						} | ||||
| 
 | ||||
| 						if (data.detail) { | ||||
| 							throw data.detail; | ||||
| 						} | ||||
| 						if (data.status) { | ||||
| 							if (!data.status.includes('downloading')) { | ||||
| 								toast.success(data.status); | ||||
|  | @ -206,6 +210,10 @@ | |||
| 						if (data.error) { | ||||
| 							throw data.error; | ||||
| 						} | ||||
| 						if (data.detail) { | ||||
| 							throw data.detail; | ||||
| 						} | ||||
| 
 | ||||
| 						if (data.status) { | ||||
| 						} | ||||
| 					} else { | ||||
|  |  | |||
|  | @ -388,17 +388,17 @@ | |||
| 				{#if $user !== undefined} | ||||
| 					<button | ||||
| 						class=" flex rounded-md py-3 px-3.5 w-full hover:bg-gray-900 transition" | ||||
| 						on:focus={() => { | ||||
| 							showDropdown = true; | ||||
| 						on:click={() => { | ||||
| 							showDropdown = !showDropdown; | ||||
| 						}} | ||||
| 						on:focusout={() => { | ||||
| 							setTimeout(() => { | ||||
| 								showDropdown = false; | ||||
| 							}, 100); | ||||
| 							}, 150); | ||||
| 						}} | ||||
| 					> | ||||
| 						<div class=" self-center mr-3"> | ||||
| 							<img src="/user.png" class=" max-w-[30px] object-cover rounded-full" /> | ||||
| 							<img src={$user.profile_image_url} class=" max-w-[30px] object-cover rounded-full" /> | ||||
| 						</div> | ||||
| 						<div class=" self-center font-semibold">{$user.name}</div> | ||||
| 					</button> | ||||
|  | @ -406,7 +406,7 @@ | |||
| 					{#if showDropdown} | ||||
| 						<div | ||||
| 							id="dropdownDots" | ||||
| 							class="absolute z-10 bottom-[4.5rem] rounded-lg shadow w-[240px] bg-gray-900" | ||||
| 							class="absolute z-10 bottom-[70px] 4.5rem rounded-lg shadow w-[240px] bg-gray-900" | ||||
| 						> | ||||
| 							<div class="py-2 w-full"> | ||||
| 								<button | ||||
|  | @ -440,14 +440,14 @@ | |||
| 								</button> | ||||
| 							</div> | ||||
| 
 | ||||
| 							<hr class=" dark:border-gray-700 m-0 p-0" /> | ||||
| 							<hr class=" border-gray-700 m-0 p-0" /> | ||||
| 
 | ||||
| 							<div class="py-2 w-full"> | ||||
| 								<button | ||||
| 									class="flex py-2.5 px-3.5 w-full hover:bg-gray-800 transition" | ||||
| 									on:click={() => { | ||||
| 										localStorage.removeItem('token'); | ||||
| 										location.href = '/'; | ||||
| 										location.href = '/auth'; | ||||
| 									}} | ||||
| 								> | ||||
| 									<div class=" self-center mr-3"> | ||||
|  |  | |||
|  | @ -1,12 +1,19 @@ | |||
| <script> | ||||
| 	import { config, user } from '$lib/stores'; | ||||
| 	import { goto } from '$app/navigation'; | ||||
| 	import { onMount, tick } from 'svelte'; | ||||
| 
 | ||||
| 	if ($config && $config.auth && $user === undefined) { | ||||
| 		goto('/auth'); | ||||
| 	} | ||||
| 	let loaded = false; | ||||
| 	onMount(async () => { | ||||
| 		if ($config && $config.auth && $user === undefined) { | ||||
| 			await goto('/auth'); | ||||
| 		} | ||||
| 
 | ||||
| 		await tick(); | ||||
| 		loaded = true; | ||||
| 	}); | ||||
| </script> | ||||
| 
 | ||||
| {#if $config !== undefined} | ||||
| {#if loaded} | ||||
| 	<slot /> | ||||
| {/if} | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ | |||
| 	import Navbar from '$lib/components/layout/Navbar.svelte'; | ||||
| 	import SettingsModal from '$lib/components/chat/SettingsModal.svelte'; | ||||
| 	import Suggestions from '$lib/components/chat/Suggestions.svelte'; | ||||
| 	import { user } from '$lib/stores'; | ||||
| 	import { config, user } from '$lib/stores'; | ||||
| 
 | ||||
| 	let API_BASE_URL = BUILD_TIME_API_BASE_URL; | ||||
| 	let db; | ||||
|  | @ -1224,14 +1224,27 @@ | |||
| 								<div class="flex justify-between px-5 mb-3 max-w-3xl mx-auto rounded-lg group"> | ||||
| 									<div class=" flex w-full"> | ||||
| 										<div class=" mr-4"> | ||||
| 											<img | ||||
| 												src="{message.role == 'user' | ||||
| 													? settings.gravatarUrl | ||||
| 														? settings.gravatarUrl | ||||
| 														: '/user' | ||||
| 													: '/favicon'}.png" | ||||
| 												class=" max-w-[28px] object-cover rounded-full" | ||||
| 											/> | ||||
| 											{#if message.role === 'user'} | ||||
| 												{#if $config === null} | ||||
| 													<img | ||||
| 														src="{settings.gravatarUrl ? settings.gravatarUrl : '/user'}.png" | ||||
| 														class=" max-w-[28px] object-cover rounded-full" | ||||
| 														alt="User profile" | ||||
| 													/> | ||||
| 												{:else} | ||||
| 													<img | ||||
| 														src={$user.profile_image_url} | ||||
| 														class=" max-w-[28px] object-cover rounded-full" | ||||
| 														alt="User profile" | ||||
| 													/> | ||||
| 												{/if} | ||||
| 											{:else} | ||||
| 												<img | ||||
| 													src="/favicon.png" | ||||
| 													class=" max-w-[28px] object-cover rounded-full" | ||||
| 													alt="Ollama profile" | ||||
| 												/> | ||||
| 											{/if} | ||||
| 										</div> | ||||
| 
 | ||||
| 										<div class="w-full"> | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ | |||
| 	let loaded = false; | ||||
| 
 | ||||
| 	onMount(async () => { | ||||
| 		const webBackendStatus = await fetch(`${WEBUI_API_BASE_URL}/`, { | ||||
| 		const resBackend = await fetch(`${WEBUI_API_BASE_URL}/`, { | ||||
| 			method: 'GET', | ||||
| 			headers: { | ||||
| 				'Content-Type': 'application/json' | ||||
|  | @ -26,11 +26,11 @@ | |||
| 				return null; | ||||
| 			}); | ||||
| 
 | ||||
| 		console.log(webBackendStatus); | ||||
| 		await config.set(webBackendStatus); | ||||
| 		console.log(resBackend); | ||||
| 		await config.set(resBackend); | ||||
| 
 | ||||
| 		if (webBackendStatus) { | ||||
| 			if (webBackendStatus.auth) { | ||||
| 		if ($config) { | ||||
| 			if ($config.auth) { | ||||
| 				if (localStorage.token) { | ||||
| 					const res = await fetch(`${WEBUI_API_BASE_URL}/auths`, { | ||||
| 						method: 'GET', | ||||
|  | @ -49,9 +49,14 @@ | |||
| 							return null; | ||||
| 						}); | ||||
| 
 | ||||
| 					await user.set(res); | ||||
| 					if (res) { | ||||
| 						await user.set(res); | ||||
| 					} else { | ||||
| 						localStorage.removeItem('token'); | ||||
| 						await goto('/auth'); | ||||
| 					} | ||||
| 				} else { | ||||
| 					goto('/auth'); | ||||
| 					await goto('/auth'); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  |  | |||
|  | @ -2,8 +2,10 @@ | |||
| 	import { goto } from '$app/navigation'; | ||||
| 	import { WEBUI_API_BASE_URL } from '$lib/constants'; | ||||
| 	import { config, user } from '$lib/stores'; | ||||
| 	import { onMount } from 'svelte'; | ||||
| 	import toast from 'svelte-french-toast'; | ||||
| 
 | ||||
| 	let loaded = false; | ||||
| 	let mode = 'signin'; | ||||
| 
 | ||||
| 	let name = ''; | ||||
|  | @ -33,7 +35,7 @@ | |||
| 
 | ||||
| 		if (res) { | ||||
| 			console.log(res); | ||||
| 			toast.success(`You're now logged in. Redirecting you to the main page."`); | ||||
| 			toast.success(`You're now logged in. Redirecting you to the main page.`); | ||||
| 			localStorage.token = res.token; | ||||
| 			await user.set(res); | ||||
| 			goto('/'); | ||||
|  | @ -71,12 +73,15 @@ | |||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| 	if ($config === null || !$config.auth || ($config.auth && $user !== undefined)) { | ||||
| 		goto('/'); | ||||
| 	} | ||||
| 	onMount(async () => { | ||||
| 		if ($config === null || !$config.auth || ($config.auth && $user !== undefined)) { | ||||
| 			await goto('/'); | ||||
| 		} | ||||
| 		loaded = true; | ||||
| 	}); | ||||
| </script> | ||||
| 
 | ||||
| {#if $config && $config.auth} | ||||
| {#if loaded && $config && $config.auth} | ||||
| 	<div class="fixed m-10 z-50"> | ||||
| 		<div class="flex space-x-2"> | ||||
| 			<div class=" self-center"> | ||||
|  | @ -1065,6 +1070,146 @@ | |||
| 		</div> | ||||
| 	</div> | ||||
| 
 | ||||
| 	<div class=" my-auto pb-36 w-full px-4"> | ||||
| 		<div class=" text-center flex flex-col justify-center"> | ||||
| 			<div class=" text-xl md:text-2xl font-bold">Get Started</div> | ||||
| 
 | ||||
| 			<div | ||||
| 				class=" mt-4 flex flex-col md:flex-row space-y-2 md:space-y-0 md:space-x-1 px-3 justify-center" | ||||
| 			> | ||||
| 				<button class=" flex-1 px-4 py-3.5 bg-blue-700 text-white font-medium rounded-lg"> | ||||
| 					Log in | ||||
| 				</button> | ||||
| 
 | ||||
| 				<button class=" flex-1 px-4 py-3.5 bg-blue-700 text-white font-medium rounded-lg"> | ||||
| 					Sign up | ||||
| 				</button> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</div> | ||||
| </div> --> | ||||
| 	<!-- <div class=" bg-white min-h-screen w-full flex flex-col"> | ||||
| 	<div class=" mt-6 mx-6"> | ||||
| 		<div class="flex space-x-2"> | ||||
| 			<div class=" self-center text-2xl font-semibold">Ollama</div> | ||||
| 			<div class=" self-center"> | ||||
| 				<img src="/ollama.png" class=" w-5" /> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</div> | ||||
| 
 | ||||
| 	<div class=" my-auto pb-36 w-full px-4"> | ||||
| 		<div class=" text-center flex flex-col justify-center"> | ||||
| 			<div class=" text-xl md:text-2xl font-bold">Get Started</div> | ||||
| 
 | ||||
| 			<div | ||||
| 				class=" mt-4 flex flex-col md:flex-row space-y-2 md:space-y-0 md:space-x-1 px-3 justify-center" | ||||
| 			> | ||||
| 				<button class=" flex-1 px-4 py-3.5 bg-blue-700 text-white font-medium rounded-lg"> | ||||
| 					Log in | ||||
| 				</button> | ||||
| 
 | ||||
| 				<button class=" flex-1 px-4 py-3.5 bg-blue-700 text-white font-medium rounded-lg"> | ||||
| 					Sign up | ||||
| 				</button> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</div> | ||||
| </div> --> | ||||
| 	<!-- <div class=" bg-white min-h-screen w-full flex flex-col"> | ||||
| 	<div class=" mt-6 mx-6"> | ||||
| 		<div class="flex space-x-2"> | ||||
| 			<div class=" self-center text-2xl font-semibold">Ollama</div> | ||||
| 			<div class=" self-center"> | ||||
| 				<img src="/ollama.png" class=" w-5" /> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</div> | ||||
| 
 | ||||
| 	<div class=" my-auto pb-36 w-full px-4"> | ||||
| 		<div class=" text-center flex flex-col justify-center"> | ||||
| 			<div class=" text-xl md:text-2xl font-bold">Get Started</div> | ||||
| 
 | ||||
| 			<div | ||||
| 				class=" mt-4 flex flex-col md:flex-row space-y-2 md:space-y-0 md:space-x-1 px-3 justify-center" | ||||
| 			> | ||||
| 				<button class=" flex-1 px-4 py-3.5 bg-blue-700 text-white font-medium rounded-lg"> | ||||
| 					Log in | ||||
| 				</button> | ||||
| 
 | ||||
| 				<button class=" flex-1 px-4 py-3.5 bg-blue-700 text-white font-medium rounded-lg"> | ||||
| 					Sign up | ||||
| 				</button> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</div> | ||||
| </div> --> | ||||
| 	<!-- <div class=" bg-white min-h-screen w-full flex flex-col"> | ||||
| 	<div class=" mt-6 mx-6"> | ||||
| 		<div class="flex space-x-2"> | ||||
| 			<div class=" self-center text-2xl font-semibold">Ollama</div> | ||||
| 			<div class=" self-center"> | ||||
| 				<img src="/ollama.png" class=" w-5" /> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</div> | ||||
| 
 | ||||
| 	<div class=" my-auto pb-36 w-full px-4"> | ||||
| 		<div class=" text-center flex flex-col justify-center"> | ||||
| 			<div class=" text-xl md:text-2xl font-bold">Get Started</div> | ||||
| 
 | ||||
| 			<div | ||||
| 				class=" mt-4 flex flex-col md:flex-row space-y-2 md:space-y-0 md:space-x-1 px-3 justify-center" | ||||
| 			> | ||||
| 				<button class=" flex-1 px-4 py-3.5 bg-blue-700 text-white font-medium rounded-lg"> | ||||
| 					Log in | ||||
| 				</button> | ||||
| 
 | ||||
| 				<button class=" flex-1 px-4 py-3.5 bg-blue-700 text-white font-medium rounded-lg"> | ||||
| 					Sign up | ||||
| 				</button> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</div> | ||||
| </div> --> | ||||
| 	<!-- <div class=" bg-white min-h-screen w-full flex flex-col"> | ||||
| 	<div class=" mt-6 mx-6"> | ||||
| 		<div class="flex space-x-2"> | ||||
| 			<div class=" self-center text-2xl font-semibold">Ollama</div> | ||||
| 			<div class=" self-center"> | ||||
| 				<img src="/ollama.png" class=" w-5" /> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</div> | ||||
| 
 | ||||
| 	<div class=" my-auto pb-36 w-full px-4"> | ||||
| 		<div class=" text-center flex flex-col justify-center"> | ||||
| 			<div class=" text-xl md:text-2xl font-bold">Get Started</div> | ||||
| 
 | ||||
| 			<div | ||||
| 				class=" mt-4 flex flex-col md:flex-row space-y-2 md:space-y-0 md:space-x-1 px-3 justify-center" | ||||
| 			> | ||||
| 				<button class=" flex-1 px-4 py-3.5 bg-blue-700 text-white font-medium rounded-lg"> | ||||
| 					Log in | ||||
| 				</button> | ||||
| 
 | ||||
| 				<button class=" flex-1 px-4 py-3.5 bg-blue-700 text-white font-medium rounded-lg"> | ||||
| 					Sign up | ||||
| 				</button> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</div> | ||||
| </div> --> | ||||
| 	<!-- <div class=" bg-white min-h-screen w-full flex flex-col"> | ||||
| 	<div class=" mt-6 mx-6"> | ||||
| 		<div class="flex space-x-2"> | ||||
| 			<div class=" self-center text-2xl font-semibold">Ollama</div> | ||||
| 			<div class=" self-center"> | ||||
| 				<img src="/ollama.png" class=" w-5" /> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</div> | ||||
| 
 | ||||
| 	<div class=" my-auto pb-36 w-full px-4"> | ||||
| 		<div class=" text-center flex flex-col justify-center"> | ||||
| 			<div class=" text-xl md:text-2xl font-bold">Get Started</div> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy J. Baek
						Timothy J. Baek