- 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.
79 lines
2.0 KiB
Go
79 lines
2.0 KiB
Go
package ai
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/ultisuite/ulti-backend/internal/auth"
|
|
"github.com/ultisuite/ulti-backend/internal/config"
|
|
"github.com/ultisuite/ulti-backend/internal/permission"
|
|
)
|
|
|
|
const defaultOpenWebUIProfileImage = "/user.png"
|
|
|
|
// SyncOpenWebUIProfile pushes profile_image_url to OpenWebUI via trusted-header auth.
|
|
func SyncOpenWebUIProfile(ctx context.Context, cfg *config.Config, claims *auth.Claims, profileImageURL string) error {
|
|
if cfg == nil || !cfg.AIAssistantEnabled || claims == nil {
|
|
return nil
|
|
}
|
|
email := strings.TrimSpace(claims.Email)
|
|
if email == "" {
|
|
return nil
|
|
}
|
|
|
|
baseURL := strings.TrimRight(strings.TrimSpace(cfg.OpenWebUIInternalURL), "/")
|
|
if baseURL == "" {
|
|
baseURL = "http://openwebui:8080"
|
|
}
|
|
|
|
profileImageURL = strings.TrimSpace(profileImageURL)
|
|
if profileImageURL == "" {
|
|
profileImageURL = defaultOpenWebUIProfileImage
|
|
}
|
|
|
|
body, err := json.Marshal(map[string]string{
|
|
"profile_image_url": profileImageURL,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, baseURL+"/api/v1/auths/update/profile", bytes.NewReader(body))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("X-Ulti-User-Email", email)
|
|
name := strings.TrimSpace(claims.Name)
|
|
if name == "" {
|
|
name = email
|
|
}
|
|
req.Header.Set("X-Ulti-User-Name", name)
|
|
req.Header.Set("X-Ulti-User-Role", openWebUIRoleFromClaims(claims))
|
|
|
|
client := &http.Client{Timeout: 15 * time.Second}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
|
|
return nil
|
|
}
|
|
raw, _ := io.ReadAll(io.LimitReader(resp.Body, 4096))
|
|
return fmt.Errorf("openwebui profile sync: %d %s", resp.StatusCode, strings.TrimSpace(string(raw)))
|
|
}
|
|
|
|
func openWebUIRoleFromClaims(claims *auth.Claims) string {
|
|
if claims != nil && permission.HasRole(claims.Groups, permission.RoleAdmin) {
|
|
return "admin"
|
|
}
|
|
return "user"
|
|
}
|