mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-06-11 08:30:51 +02:00
Fix bug with saml validation (#4522)
* fix bug with saml validation * k
This commit is contained in:
parent
7e7b6e08ff
commit
0d12e96362
@ -1,5 +1,6 @@
|
||||
import contextlib
|
||||
import secrets
|
||||
import string
|
||||
from typing import Any
|
||||
|
||||
from fastapi import APIRouter
|
||||
@ -9,7 +10,6 @@ from fastapi import Request
|
||||
from fastapi import Response
|
||||
from fastapi import status
|
||||
from fastapi_users import exceptions
|
||||
from fastapi_users.password import PasswordHelper
|
||||
from onelogin.saml2.auth import OneLogin_Saml2_Auth # type: ignore
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
@ -38,6 +38,16 @@ router = APIRouter(prefix="/auth/saml")
|
||||
|
||||
|
||||
async def upsert_saml_user(email: str) -> User:
|
||||
"""
|
||||
Creates or updates a user account for SAML authentication.
|
||||
|
||||
For new users or users with non-web-login roles:
|
||||
1. Generates a secure random password that meets validation criteria
|
||||
2. Creates the user with appropriate role and verified status
|
||||
|
||||
SAML users never use this password directly as they authenticate via their
|
||||
Identity Provider, but we need a valid password to satisfy system requirements.
|
||||
"""
|
||||
logger.debug(f"Attempting to upsert SAML user with email: {email}")
|
||||
get_async_session_context = contextlib.asynccontextmanager(
|
||||
get_async_session
|
||||
@ -60,15 +70,41 @@ async def upsert_saml_user(email: str) -> User:
|
||||
user_count = await get_user_count()
|
||||
role = UserRole.ADMIN if user_count == 0 else UserRole.BASIC
|
||||
|
||||
fastapi_users_pw_helper = PasswordHelper()
|
||||
password = fastapi_users_pw_helper.generate()
|
||||
hashed_pass = fastapi_users_pw_helper.hash(password)
|
||||
# Generate a secure random password meeting validation requirements
|
||||
# We use a secure random password since we never need to know what it is
|
||||
# (SAML users authenticate via their IdP)
|
||||
secure_random_password = "".join(
|
||||
[
|
||||
# Ensure minimum requirements are met
|
||||
secrets.choice(
|
||||
string.ascii_uppercase
|
||||
), # at least one uppercase
|
||||
secrets.choice(
|
||||
string.ascii_lowercase
|
||||
), # at least one lowercase
|
||||
secrets.choice(string.digits), # at least one digit
|
||||
secrets.choice(
|
||||
"!@#$%^&*()-_=+[]{}|;:,.<>?"
|
||||
), # at least one special
|
||||
# Fill remaining length with random chars (mix of all types)
|
||||
"".join(
|
||||
secrets.choice(
|
||||
string.ascii_letters
|
||||
+ string.digits
|
||||
+ "!@#$%^&*()-_=+[]{}|;:,.<>?"
|
||||
)
|
||||
for _ in range(12)
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
# Create the user with SAML-appropriate settings
|
||||
user = await user_manager.create(
|
||||
UserCreate(
|
||||
email=email,
|
||||
password=hashed_pass,
|
||||
password=secure_random_password, # Pass raw password, not hash
|
||||
role=role,
|
||||
is_verified=True, # SAML users are pre-verified by their IdP
|
||||
)
|
||||
)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user