mirror of
https://github.com/open-webui/open-webui.git
synced 2026-08-13 01:02:25 -06:00
refac
This commit is contained in:
@@ -2649,7 +2649,7 @@ async def oauth_client_authorize(
|
||||
detail='OAuth client registration is still invalid after re-registration',
|
||||
)
|
||||
|
||||
return await oauth_client_manager.handle_authorize(request, client_id=client_id)
|
||||
return await oauth_client_manager.handle_authorize(request, client_id=client_id, user_id=user.id)
|
||||
|
||||
|
||||
@app.get('/oauth/clients/{client_id}/callback')
|
||||
@@ -2657,12 +2657,10 @@ async def oauth_client_callback(
|
||||
client_id: str,
|
||||
request: Request,
|
||||
response: Response,
|
||||
user=Depends(get_verified_user),
|
||||
):
|
||||
return await oauth_client_manager.handle_callback(
|
||||
request,
|
||||
client_id=client_id,
|
||||
user_id=user.id if user else None,
|
||||
response=response,
|
||||
)
|
||||
|
||||
|
||||
@@ -966,6 +966,11 @@ async def signout(request: Request, response: Response, db: AsyncSession = Depen
|
||||
)
|
||||
|
||||
response.delete_cookie('token')
|
||||
try:
|
||||
request.session.clear()
|
||||
except Exception:
|
||||
pass
|
||||
response.delete_cookie('owui-session')
|
||||
response.delete_cookie('oui-session')
|
||||
response.delete_cookie('oauth_id_token')
|
||||
|
||||
|
||||
@@ -519,6 +519,39 @@ async def get_verified_user_by_token(token: str, redis=None):
|
||||
return user
|
||||
|
||||
|
||||
async def get_verified_user_by_id(user_id: str | None):
|
||||
if not user_id:
|
||||
return None
|
||||
|
||||
user = await Users.get_user_by_id(user_id)
|
||||
if user is None or user.role not in VERIFIED_USER_ROLES:
|
||||
return None
|
||||
|
||||
return user
|
||||
|
||||
|
||||
async def get_optional_verified_user_from_request(request: Request):
|
||||
token = None
|
||||
auth_token = get_http_authorization_cred(request.headers.get('Authorization'))
|
||||
if auth_token:
|
||||
token = auth_token.credentials
|
||||
if token is None:
|
||||
token = request.cookies.get('token')
|
||||
if token is None and getattr(request.state, 'token', None):
|
||||
token = request.state.token.credentials
|
||||
if not token:
|
||||
return None
|
||||
|
||||
try:
|
||||
if token.startswith('sk-'):
|
||||
user = await get_current_user_by_api_key(request, token)
|
||||
return user if user.role in VERIFIED_USER_ROLES else None
|
||||
|
||||
return await get_verified_user_by_token(token, getattr(request.app.state, 'redis', None))
|
||||
except HTTPException:
|
||||
return None
|
||||
|
||||
|
||||
def get_admin_user(user=Depends(get_current_user)):
|
||||
if user.role != 'admin':
|
||||
raise HTTPException(
|
||||
|
||||
@@ -84,7 +84,12 @@ from open_webui.models.groups import GroupForm, GroupModel, Groups, GroupUpdateF
|
||||
from open_webui.models.oauth_sessions import OAuthSessions
|
||||
from open_webui.models.users import Users
|
||||
from open_webui.retrieval.web.utils import get_ssrf_safe_session, validate_url
|
||||
from open_webui.utils.auth import create_token, get_password_hash
|
||||
from open_webui.utils.auth import (
|
||||
create_token,
|
||||
get_password_hash,
|
||||
get_optional_verified_user_from_request,
|
||||
get_verified_user_by_id,
|
||||
)
|
||||
from open_webui.utils.groups import apply_default_group_assignment
|
||||
from open_webui.utils.misc import parse_duration
|
||||
from open_webui.utils.validate import validate_profile_image_url
|
||||
@@ -1167,7 +1172,7 @@ class OAuthClientManager:
|
||||
log.error(f'Exception during token refresh for client_id {client_id}: {e}')
|
||||
return None
|
||||
|
||||
async def handle_authorize(self, request, client_id: str) -> RedirectResponse:
|
||||
async def handle_authorize(self, request, client_id: str, user_id: str) -> RedirectResponse:
|
||||
client = await self.get_client(client_id)
|
||||
if client is None:
|
||||
raise HTTPException(404)
|
||||
@@ -1183,7 +1188,15 @@ class OAuthClientManager:
|
||||
# Pass explicit scope/resource parameters for providers that require them.
|
||||
kwargs = build_oauth_request_params(client_info)
|
||||
try:
|
||||
return await client.authorize_redirect(request, redirect_uri_str, **kwargs)
|
||||
auth_data = await client.create_authorization_url(redirect_uri_str, **kwargs)
|
||||
if not auth_data.get('state'):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail='OAuth authorization state was not generated',
|
||||
)
|
||||
auth_data['user_id'] = user_id
|
||||
await client.save_authorize_data(request, redirect_uri=redirect_uri_str, **auth_data)
|
||||
return RedirectResponse(auth_data['url'], status_code=302)
|
||||
except RuntimeError as e:
|
||||
# authlib raises RuntimeError('Missing "authorize_url" value') when the
|
||||
# authorization endpoint could not be resolved from server metadata.
|
||||
@@ -1199,14 +1212,36 @@ class OAuthClientManager:
|
||||
),
|
||||
)
|
||||
|
||||
async def handle_callback(self, request, client_id: str, user_id: str, response):
|
||||
async def handle_callback(self, request, client_id: str, response):
|
||||
client = await self.get_client(client_id)
|
||||
if client is None:
|
||||
raise HTTPException(404)
|
||||
|
||||
error_message = None
|
||||
state = request.query_params.get('state')
|
||||
user_id = None
|
||||
try:
|
||||
client_info = await self.get_client_info(client_id)
|
||||
state_data = await client.framework.get_state_data(request.session, state) if state else None
|
||||
user_id = state_data.get('user_id') if state_data else None
|
||||
if not user_id:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail='OAuth callback state is invalid or expired',
|
||||
)
|
||||
|
||||
if not await get_verified_user_by_id(user_id):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail='OAuth callback user is not authorized',
|
||||
)
|
||||
|
||||
request_user = await get_optional_verified_user_from_request(request)
|
||||
if request_user and request_user.id != user_id:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail='OAuth callback user does not match authenticated session',
|
||||
)
|
||||
|
||||
# Note: Do NOT pass client_id/client_secret explicitly here.
|
||||
# The Authlib client already has these configured during add_client().
|
||||
@@ -1257,6 +1292,9 @@ class OAuthClientManager:
|
||||
error_message,
|
||||
exc_info=True,
|
||||
)
|
||||
finally:
|
||||
if state and client is not None:
|
||||
await client.framework.clear_state_data(request.session, state)
|
||||
|
||||
webui_url = await Config.get('webui.url')
|
||||
redirect_url = (str(webui_url or request.base_url)).rstrip('/')
|
||||
|
||||
Reference in New Issue
Block a user