- Updated .env.example to include new configuration options for the UltiAI branding and API endpoints. - Enhanced Nginx configuration to support new API routes for the MCP and WebSocket connections. - Introduced sub-filters for branding adjustments in Nginx responses. - Added new JavaScript patch for API endpoint adjustments. - Implemented tests for new API functionalities and improved error handling in the AI gateway.
68 lines
2.1 KiB
Go
68 lines
2.1 KiB
Go
package users
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"strings"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
|
|
"github.com/ultisuite/ulti-backend/internal/ai"
|
|
"github.com/ultisuite/ulti-backend/internal/auth"
|
|
"github.com/ultisuite/ulti-backend/internal/authentik"
|
|
"github.com/ultisuite/ulti-backend/internal/config"
|
|
)
|
|
|
|
// ImportAvatarFromAuthentik copies attributes.avatar into users.avatar_url when PG is empty.
|
|
func ImportAvatarFromAuthentik(ctx context.Context, db *pgxpool.Pool, cfg *config.Config, externalID string) (string, error) {
|
|
if db == nil || cfg == nil || strings.TrimSpace(externalID) == "" {
|
|
return "", nil
|
|
}
|
|
current, err := GetAvatarURL(ctx, db, externalID)
|
|
if err != nil || current != "" {
|
|
return current, err
|
|
}
|
|
client := authentikClient(cfg)
|
|
if client == nil {
|
|
return "", nil
|
|
}
|
|
raw, err := client.GetUserAvatarAttribute(ctx, externalID)
|
|
if err != nil || strings.TrimSpace(raw) == "" {
|
|
return "", err
|
|
}
|
|
normalized, err := normalizeAvatarURL(raw)
|
|
if err != nil {
|
|
slog.Warn("skip authentik avatar import", "sub", externalID, "error", err)
|
|
return "", nil
|
|
}
|
|
if err := SetAvatarURL(ctx, db, externalID, normalized); err != nil {
|
|
return "", err
|
|
}
|
|
return normalized, nil
|
|
}
|
|
|
|
// PropagateAvatarOutbound syncs avatar to Authentik and UltiAI (OpenWebUI).
|
|
func PropagateAvatarOutbound(ctx context.Context, db *pgxpool.Pool, cfg *config.Config, claims *auth.Claims, avatarURL string) {
|
|
if claims == nil || strings.TrimSpace(claims.Sub) == "" {
|
|
return
|
|
}
|
|
avatarURL = strings.TrimSpace(avatarURL)
|
|
|
|
if client := authentikClient(cfg); client != nil {
|
|
if err := client.SetUserAvatarAttribute(ctx, claims.Sub, avatarURL); err != nil {
|
|
slog.Warn("sync avatar to authentik", "sub", claims.Sub, "error", err)
|
|
}
|
|
}
|
|
|
|
if err := ai.SyncOpenWebUIProfile(ctx, cfg, claims, avatarURL); err != nil {
|
|
slog.Warn("sync avatar to openwebui", "sub", claims.Sub, "error", err)
|
|
}
|
|
}
|
|
|
|
func authentikClient(cfg *config.Config) *authentik.Client {
|
|
if cfg == nil || strings.TrimSpace(cfg.AuthentikAPIToken) == "" {
|
|
return nil
|
|
}
|
|
return authentik.NewClient(cfg.AuthentikAPIURL, cfg.AuthentikAPIToken)
|
|
}
|