初始提交:OCI 面板后端(含 GenAI 网关一期)
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// OAuth provider 配置键;client secret 以 AES-GCM 密文落库。
|
||||
const (
|
||||
settingOauthOidcIssuer = "oauth_oidc_issuer"
|
||||
settingOauthOidcClientID = "oauth_oidc_client_id"
|
||||
settingOauthOidcClientSecret = "oauth_oidc_client_secret"
|
||||
settingOauthOidcDisplayName = "oauth_oidc_display_name"
|
||||
settingOauthOidcDisabled = "oauth_oidc_disabled"
|
||||
settingOauthGithubClientID = "oauth_github_client_id"
|
||||
settingOauthGithubClientSecret = "oauth_github_client_secret"
|
||||
settingOauthGithubDisplayName = "oauth_github_display_name"
|
||||
settingOauthGithubDisabled = "oauth_github_disabled"
|
||||
)
|
||||
|
||||
// OAuthProvidersView 是 OAuth provider 配置视图;绝不返回 secret 明文。
|
||||
type OAuthProvidersView struct {
|
||||
OidcIssuer string `json:"oidcIssuer"`
|
||||
OidcClientID string `json:"oidcClientId"`
|
||||
OidcSecretSet bool `json:"oidcSecretSet"`
|
||||
OidcDisplayName string `json:"oidcDisplayName"`
|
||||
OidcDisabled bool `json:"oidcDisabled"`
|
||||
GithubClientID string `json:"githubClientId"`
|
||||
GithubSecretSet bool `json:"githubSecretSet"`
|
||||
GithubDisplayName string `json:"githubDisplayName"`
|
||||
GithubDisabled bool `json:"githubDisabled"`
|
||||
}
|
||||
|
||||
// UpdateOAuthInput 是保存 provider 配置的输入;
|
||||
// secret 为 nil 沿用已存值,非 nil 覆盖(空串清除)。
|
||||
type UpdateOAuthInput struct {
|
||||
OidcIssuer string `json:"oidcIssuer"`
|
||||
OidcClientID string `json:"oidcClientId"`
|
||||
OidcClientSecret *string `json:"oidcClientSecret"`
|
||||
OidcDisplayName string `json:"oidcDisplayName"`
|
||||
OidcDisabled bool `json:"oidcDisabled"`
|
||||
GithubClientID string `json:"githubClientId"`
|
||||
GithubClientSecret *string `json:"githubClientSecret"`
|
||||
GithubDisplayName string `json:"githubDisplayName"`
|
||||
GithubDisabled bool `json:"githubDisabled"`
|
||||
}
|
||||
|
||||
// OAuthView 返回脱敏后的 provider 配置。
|
||||
func (s *SettingService) OAuthView(ctx context.Context) (OAuthProvidersView, error) {
|
||||
var view OAuthProvidersView
|
||||
vals, err := s.getMany(ctx,
|
||||
settingOauthOidcIssuer, settingOauthOidcClientID, settingOauthOidcClientSecret,
|
||||
settingOauthOidcDisplayName, settingOauthOidcDisabled,
|
||||
settingOauthGithubClientID, settingOauthGithubClientSecret,
|
||||
settingOauthGithubDisplayName, settingOauthGithubDisabled)
|
||||
if err != nil {
|
||||
return view, err
|
||||
}
|
||||
view.OidcIssuer = vals[settingOauthOidcIssuer]
|
||||
view.OidcClientID = vals[settingOauthOidcClientID]
|
||||
view.OidcSecretSet = vals[settingOauthOidcClientSecret] != ""
|
||||
view.OidcDisplayName = vals[settingOauthOidcDisplayName]
|
||||
view.OidcDisabled = vals[settingOauthOidcDisabled] == "1"
|
||||
view.GithubClientID = vals[settingOauthGithubClientID]
|
||||
view.GithubSecretSet = vals[settingOauthGithubClientSecret] != ""
|
||||
view.GithubDisplayName = vals[settingOauthGithubDisplayName]
|
||||
view.GithubDisabled = vals[settingOauthGithubDisabled] == "1"
|
||||
return view, nil
|
||||
}
|
||||
|
||||
// boolFlag 把开关序列化为 settings 存储值。
|
||||
func boolFlag(on bool) string {
|
||||
if on {
|
||||
return "1"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// UpdateOAuth 保存 provider 配置;issuer 规范化去尾斜杠,secret 加密落库。
|
||||
func (s *SettingService) UpdateOAuth(ctx context.Context, in UpdateOAuthInput) error {
|
||||
plain := map[string]string{
|
||||
settingOauthOidcIssuer: strings.TrimRight(strings.TrimSpace(in.OidcIssuer), "/"),
|
||||
settingOauthOidcClientID: strings.TrimSpace(in.OidcClientID),
|
||||
settingOauthOidcDisplayName: strings.TrimSpace(in.OidcDisplayName),
|
||||
settingOauthOidcDisabled: boolFlag(in.OidcDisabled),
|
||||
settingOauthGithubClientID: strings.TrimSpace(in.GithubClientID),
|
||||
settingOauthGithubDisplayName: strings.TrimSpace(in.GithubDisplayName),
|
||||
settingOauthGithubDisabled: boolFlag(in.GithubDisabled),
|
||||
}
|
||||
for key, value := range plain {
|
||||
if err := s.set(ctx, key, value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := s.saveOAuthSecret(ctx, settingOauthOidcClientSecret, in.OidcClientSecret); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.saveOAuthSecret(ctx, settingOauthGithubClientSecret, in.GithubClientSecret)
|
||||
}
|
||||
|
||||
// saveOAuthSecret 加密保存 secret;nil 沿用,空串清除。
|
||||
func (s *SettingService) saveOAuthSecret(ctx context.Context, key string, secret *string) error {
|
||||
if secret == nil {
|
||||
return nil
|
||||
}
|
||||
if *secret == "" {
|
||||
return s.set(ctx, key, "")
|
||||
}
|
||||
enc, err := s.cipher.EncryptString(*secret)
|
||||
if err != nil {
|
||||
return fmt.Errorf("encrypt oauth secret: %w", err)
|
||||
}
|
||||
return s.set(ctx, key, enc)
|
||||
}
|
||||
|
||||
// oauthClient 返回 provider 的 clientID/明文 secret/issuer(仅 oidc);未配置时 clientID 为空。
|
||||
func (s *SettingService) oauthClient(ctx context.Context, provider string) (clientID, secret, issuer string, err error) {
|
||||
idKey, secKey := settingOauthGithubClientID, settingOauthGithubClientSecret
|
||||
if provider == "oidc" {
|
||||
idKey, secKey = settingOauthOidcClientID, settingOauthOidcClientSecret
|
||||
if issuer, err = s.get(ctx, settingOauthOidcIssuer); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if clientID, err = s.get(ctx, idKey); err != nil {
|
||||
return
|
||||
}
|
||||
enc, err := s.get(ctx, secKey)
|
||||
if err != nil || enc == "" {
|
||||
return
|
||||
}
|
||||
if secret, err = s.cipher.DecryptString(enc); err != nil {
|
||||
err = fmt.Errorf("decrypt oauth secret: %w", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// oauthProviderMeta 返回 provider 的展示名(空则给默认名)与禁用态。
|
||||
func (s *SettingService) oauthProviderMeta(ctx context.Context, provider string) (display string, disabled bool, err error) {
|
||||
nameKey, offKey, def := settingOauthGithubDisplayName, settingOauthGithubDisabled, "GitHub"
|
||||
if provider == "oidc" {
|
||||
nameKey, offKey, def = settingOauthOidcDisplayName, settingOauthOidcDisabled, "OIDC 单点登录"
|
||||
}
|
||||
if display, err = s.get(ctx, nameKey); err != nil {
|
||||
return
|
||||
}
|
||||
if display == "" {
|
||||
display = def
|
||||
}
|
||||
off, err := s.get(ctx, offKey)
|
||||
disabled = off == "1"
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user