feat:精简
Some checks failed
Create and publish Docker images with specific build args / build-main-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-main-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Create and publish Docker images with specific build args / build-cuda-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-cuda-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Create and publish Docker images with specific build args / build-cuda126-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-cuda126-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Create and publish Docker images with specific build args / build-ollama-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-ollama-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Create and publish Docker images with specific build args / build-slim-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-slim-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Python CI / Format Backend (3.11.x) (push) Has been cancelled
Python CI / Format Backend (3.12.x) (push) Has been cancelled
Frontend Build / Format & Build Frontend (push) Has been cancelled
Frontend Build / Frontend Unit Tests (push) Has been cancelled
Create and publish Docker images with specific build args / merge-main-images (push) Has been cancelled
Create and publish Docker images with specific build args / merge-cuda-images (push) Has been cancelled
Create and publish Docker images with specific build args / merge-cuda126-images (push) Has been cancelled
Create and publish Docker images with specific build args / merge-ollama-images (push) Has been cancelled
Create and publish Docker images with specific build args / merge-slim-images (push) Has been cancelled
Close inactive issues / close-issues (push) Has been cancelled
Some checks failed
Create and publish Docker images with specific build args / build-main-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-main-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Create and publish Docker images with specific build args / build-cuda-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-cuda-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Create and publish Docker images with specific build args / build-cuda126-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-cuda126-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Create and publish Docker images with specific build args / build-ollama-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-ollama-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Create and publish Docker images with specific build args / build-slim-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-slim-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Python CI / Format Backend (3.11.x) (push) Has been cancelled
Python CI / Format Backend (3.12.x) (push) Has been cancelled
Frontend Build / Format & Build Frontend (push) Has been cancelled
Frontend Build / Frontend Unit Tests (push) Has been cancelled
Create and publish Docker images with specific build args / merge-main-images (push) Has been cancelled
Create and publish Docker images with specific build args / merge-cuda-images (push) Has been cancelled
Create and publish Docker images with specific build args / merge-cuda126-images (push) Has been cancelled
Create and publish Docker images with specific build args / merge-ollama-images (push) Has been cancelled
Create and publish Docker images with specific build args / merge-slim-images (push) Has been cancelled
Close inactive issues / close-issues (push) Has been cancelled
This commit is contained in:
@@ -71,6 +71,9 @@ from open_webui.utils.auth import (
|
||||
get_http_authorization_cred,
|
||||
send_verify_email,
|
||||
verify_email_by_code,
|
||||
apply_branding,
|
||||
send_signup_email_code,
|
||||
verify_signup_email_code,
|
||||
)
|
||||
from open_webui.utils.webhook import post_webhook
|
||||
from open_webui.utils.access_control import get_permissions, has_permission
|
||||
@@ -107,7 +110,6 @@ signin_rate_limiter = RateLimiter(
|
||||
class SessionUserResponse(Token, UserProfileImageResponse):
|
||||
expires_at: Optional[int] = None
|
||||
permissions: Optional[dict] = None
|
||||
credit: Decimal
|
||||
|
||||
|
||||
class SessionUserInfoResponse(SessionUserResponse, UserStatus):
|
||||
@@ -173,7 +175,6 @@ async def get_session_user(
|
||||
"status_message": user.status_message,
|
||||
"status_expires_at": user.status_expires_at,
|
||||
"permissions": user_permissions,
|
||||
"credit": credit.credit,
|
||||
}
|
||||
|
||||
|
||||
@@ -513,7 +514,6 @@ async def ldap_auth(request: Request, response: Response, form_data: LdapForm):
|
||||
"role": user.role,
|
||||
"profile_image_url": user.profile_image_url,
|
||||
"permissions": user_permissions,
|
||||
"credit": credit.credit,
|
||||
}
|
||||
else:
|
||||
raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED)
|
||||
@@ -654,12 +654,39 @@ async def signin(request: Request, response: Response, form_data: SigninForm):
|
||||
"role": user.role,
|
||||
"profile_image_url": user.profile_image_url,
|
||||
"permissions": user_permissions,
|
||||
"credit": credit.credit,
|
||||
}
|
||||
else:
|
||||
raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED)
|
||||
|
||||
|
||||
############################
|
||||
# Send Email Code
|
||||
############################
|
||||
|
||||
|
||||
class SendEmailCodeForm(BaseModel):
|
||||
email: str
|
||||
|
||||
|
||||
@router.post("/send_email_code")
|
||||
async def send_email_code(request: Request, form_data: SendEmailCodeForm):
|
||||
if not validate_email_format(form_data.email.lower()):
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.INVALID_EMAIL_FORMAT
|
||||
)
|
||||
|
||||
# check if email already registered
|
||||
if Users.get_user_by_email(form_data.email.lower()):
|
||||
raise HTTPException(400, detail=ERROR_MESSAGES.EMAIL_TAKEN)
|
||||
|
||||
try:
|
||||
send_signup_email_code(form_data.email.lower())
|
||||
return {"success": True, "message": "Verification code sent"}
|
||||
except Exception as e:
|
||||
log.error(f"Failed to send email code: {e}")
|
||||
raise HTTPException(500, detail="Failed to send verification code")
|
||||
|
||||
|
||||
############################
|
||||
# SignUp
|
||||
############################
|
||||
@@ -706,6 +733,13 @@ async def signup(request: Request, response: Response, form_data: SignupForm):
|
||||
if Users.get_user_by_email(form_data.email.lower()):
|
||||
raise HTTPException(400, detail=ERROR_MESSAGES.EMAIL_TAKEN)
|
||||
|
||||
# verify email code for non-admin signup
|
||||
if has_users and form_data.email_code:
|
||||
if not verify_signup_email_code(form_data.email.lower(), form_data.email_code):
|
||||
raise HTTPException(400, detail="Invalid or expired verification code")
|
||||
elif has_users and not form_data.email_code:
|
||||
raise HTTPException(400, detail="Verification code is required")
|
||||
|
||||
try:
|
||||
try:
|
||||
validate_password(form_data.password)
|
||||
@@ -795,7 +829,6 @@ async def signup(request: Request, response: Response, form_data: SignupForm):
|
||||
"role": user.role,
|
||||
"profile_image_url": user.profile_image_url,
|
||||
"permissions": user_permissions,
|
||||
"credit": credit.credit,
|
||||
}
|
||||
else:
|
||||
raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR)
|
||||
@@ -1250,6 +1283,154 @@ async def update_ldap_config(
|
||||
return {"ENABLE_LDAP": request.app.state.config.ENABLE_LDAP}
|
||||
|
||||
|
||||
############################
|
||||
# Branding Config
|
||||
############################
|
||||
|
||||
|
||||
@router.get("/admin/config/branding")
|
||||
async def get_branding_config(request: Request, user=Depends(get_admin_user)):
|
||||
def get_value(config_obj):
|
||||
if hasattr(config_obj, "value"):
|
||||
return config_obj.value
|
||||
return config_obj
|
||||
|
||||
return {
|
||||
"ORGANIZATION_NAME": get_value(request.app.state.config.BRANDING_ORGANIZATION_NAME),
|
||||
"CUSTOM_NAME": get_value(request.app.state.config.BRANDING_CUSTOM_NAME),
|
||||
"FAVICON_ICO": get_value(request.app.state.config.BRANDING_FAVICON_ICO),
|
||||
"FAVICON_PNG": get_value(request.app.state.config.BRANDING_FAVICON_PNG),
|
||||
"FAVICON_DARK_PNG": get_value(request.app.state.config.BRANDING_FAVICON_DARK_PNG),
|
||||
"FAVICON_SVG": get_value(request.app.state.config.BRANDING_FAVICON_SVG),
|
||||
"AUTH_LOGO_URL": get_value(request.app.state.config.BRANDING_AUTH_LOGO_URL),
|
||||
"SIDEBAR_LOGO_URL": get_value(request.app.state.config.BRANDING_SIDEBAR_LOGO_URL),
|
||||
"AUTH_LOGO_LINK_URL": get_value(request.app.state.config.BRANDING_AUTH_LOGO_LINK_URL),
|
||||
}
|
||||
|
||||
|
||||
class BrandingConfig(BaseModel):
|
||||
ORGANIZATION_NAME: Optional[str] = ""
|
||||
CUSTOM_NAME: Optional[str] = ""
|
||||
FAVICON_ICO: Optional[str] = ""
|
||||
FAVICON_PNG: Optional[str] = ""
|
||||
FAVICON_DARK_PNG: Optional[str] = ""
|
||||
FAVICON_SVG: Optional[str] = ""
|
||||
AUTH_LOGO_URL: Optional[str] = ""
|
||||
SIDEBAR_LOGO_URL: Optional[str] = ""
|
||||
AUTH_LOGO_LINK_URL: Optional[str] = ""
|
||||
|
||||
|
||||
@router.post("/admin/config/branding")
|
||||
async def update_branding_config(
|
||||
request: Request, form_data: BrandingConfig, user=Depends(get_admin_user)
|
||||
):
|
||||
# Helper function to update config value
|
||||
# Must access _state directly to get PersistentConfig object (not the value)
|
||||
def update_config(key: str, new_value):
|
||||
config_obj = request.app.state.config._state.get(key)
|
||||
if config_obj and hasattr(config_obj, "value") and hasattr(config_obj, "save"):
|
||||
config_obj.value = new_value
|
||||
config_obj.save()
|
||||
log.info(f"Branding: Saved config {key} = {new_value}")
|
||||
else:
|
||||
log.warning(f"Branding: config key '{key}' not found or not PersistentConfig")
|
||||
|
||||
# Update config values
|
||||
update_config("BRANDING_ORGANIZATION_NAME", form_data.ORGANIZATION_NAME)
|
||||
update_config("BRANDING_CUSTOM_NAME", form_data.CUSTOM_NAME)
|
||||
update_config("BRANDING_FAVICON_ICO", form_data.FAVICON_ICO)
|
||||
update_config("BRANDING_FAVICON_PNG", form_data.FAVICON_PNG)
|
||||
update_config("BRANDING_FAVICON_DARK_PNG", form_data.FAVICON_DARK_PNG)
|
||||
update_config("BRANDING_FAVICON_SVG", form_data.FAVICON_SVG)
|
||||
update_config("BRANDING_AUTH_LOGO_URL", form_data.AUTH_LOGO_URL)
|
||||
update_config("BRANDING_SIDEBAR_LOGO_URL", form_data.SIDEBAR_LOGO_URL)
|
||||
update_config("BRANDING_AUTH_LOGO_LINK_URL", form_data.AUTH_LOGO_LINK_URL)
|
||||
|
||||
# Apply branding changes immediately
|
||||
apply_branding(request.app)
|
||||
|
||||
# Helper to get value
|
||||
def get_value(config_obj):
|
||||
if hasattr(config_obj, "value"):
|
||||
return config_obj.value
|
||||
return config_obj
|
||||
|
||||
return {
|
||||
"ORGANIZATION_NAME": get_value(request.app.state.config.BRANDING_ORGANIZATION_NAME),
|
||||
"CUSTOM_NAME": get_value(request.app.state.config.BRANDING_CUSTOM_NAME),
|
||||
"FAVICON_ICO": get_value(request.app.state.config.BRANDING_FAVICON_ICO),
|
||||
"FAVICON_PNG": get_value(request.app.state.config.BRANDING_FAVICON_PNG),
|
||||
"FAVICON_DARK_PNG": get_value(request.app.state.config.BRANDING_FAVICON_DARK_PNG),
|
||||
"FAVICON_SVG": get_value(request.app.state.config.BRANDING_FAVICON_SVG),
|
||||
"AUTH_LOGO_URL": get_value(request.app.state.config.BRANDING_AUTH_LOGO_URL),
|
||||
"SIDEBAR_LOGO_URL": get_value(request.app.state.config.BRANDING_SIDEBAR_LOGO_URL),
|
||||
"AUTH_LOGO_LINK_URL": get_value(request.app.state.config.BRANDING_AUTH_LOGO_LINK_URL),
|
||||
}
|
||||
|
||||
|
||||
############################
|
||||
# Email Templates
|
||||
############################
|
||||
|
||||
|
||||
@router.get("/admin/config/email-templates")
|
||||
async def get_email_templates(request: Request, user=Depends(get_admin_user)):
|
||||
from open_webui.config import (
|
||||
DEFAULT_EMAIL_VERIFY_TEMPLATE,
|
||||
DEFAULT_EMAIL_CODE_TEMPLATE,
|
||||
)
|
||||
|
||||
def get_value(config_obj):
|
||||
if hasattr(config_obj, "value"):
|
||||
return config_obj.value
|
||||
return config_obj
|
||||
|
||||
return {
|
||||
"EMAIL_VERIFY_TEMPLATE": get_value(
|
||||
request.app.state.config.EMAIL_VERIFY_TEMPLATE
|
||||
),
|
||||
"EMAIL_CODE_TEMPLATE": get_value(
|
||||
request.app.state.config.EMAIL_CODE_TEMPLATE
|
||||
),
|
||||
"DEFAULT_EMAIL_VERIFY_TEMPLATE": DEFAULT_EMAIL_VERIFY_TEMPLATE,
|
||||
"DEFAULT_EMAIL_CODE_TEMPLATE": DEFAULT_EMAIL_CODE_TEMPLATE,
|
||||
}
|
||||
|
||||
|
||||
class EmailTemplatesConfig(BaseModel):
|
||||
EMAIL_VERIFY_TEMPLATE: Optional[str] = ""
|
||||
EMAIL_CODE_TEMPLATE: Optional[str] = ""
|
||||
|
||||
|
||||
@router.post("/admin/config/email-templates")
|
||||
async def update_email_templates(
|
||||
request: Request, form_data: EmailTemplatesConfig, user=Depends(get_admin_user)
|
||||
):
|
||||
def update_config(key: str, new_value):
|
||||
config_obj = request.app.state.config._state.get(key)
|
||||
if config_obj and hasattr(config_obj, "value") and hasattr(config_obj, "save"):
|
||||
config_obj.value = new_value
|
||||
config_obj.save()
|
||||
log.info(f"Email Templates: Saved config {key}")
|
||||
|
||||
update_config("EMAIL_VERIFY_TEMPLATE", form_data.EMAIL_VERIFY_TEMPLATE)
|
||||
update_config("EMAIL_CODE_TEMPLATE", form_data.EMAIL_CODE_TEMPLATE)
|
||||
|
||||
def get_value(config_obj):
|
||||
if hasattr(config_obj, "value"):
|
||||
return config_obj.value
|
||||
return config_obj
|
||||
|
||||
return {
|
||||
"EMAIL_VERIFY_TEMPLATE": get_value(
|
||||
request.app.state.config.EMAIL_VERIFY_TEMPLATE
|
||||
),
|
||||
"EMAIL_CODE_TEMPLATE": get_value(
|
||||
request.app.state.config.EMAIL_CODE_TEMPLATE
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
############################
|
||||
# API Key
|
||||
############################
|
||||
|
||||
Reference in New Issue
Block a user