Add register configuration support for user management
- Introduced register configuration loading from the openapi/user/register directory, enhancing user management capabilities. - Updated LoginThirdParty function to utilize locale-specific register configurations, improving localization support. - Refactored RegisterConfig structure to include additional fields for better configuration management. - Enhanced GetRegisterConfig function to provide fallback options for missing locale configurations, ensuring robustness in user registration processes.
This commit is contained in:
parent
87465379be
commit
a4c628f3c2
4 changed files with 133 additions and 23 deletions
|
|
@ -33,6 +33,8 @@ var (
|
|||
defaultConfig *Config
|
||||
// Team configurations by locale
|
||||
teamConfigs = make(map[string]*TeamConfig)
|
||||
// Register configurations by locale
|
||||
registerConfigs = make(map[string]*RegisterConfig)
|
||||
// Mutex for thread safety
|
||||
configMutex sync.RWMutex
|
||||
)
|
||||
|
|
@ -48,6 +50,7 @@ func Load(appConfig config.Config) error {
|
|||
providers = make(map[string]*Provider)
|
||||
defaultConfig = nil
|
||||
teamConfigs = make(map[string]*TeamConfig)
|
||||
registerConfigs = make(map[string]*RegisterConfig)
|
||||
|
||||
// Load signin configurations from openapi/user/signin directory
|
||||
err := loadSigninConfigs(appConfig.Root)
|
||||
|
|
@ -55,6 +58,12 @@ func Load(appConfig config.Config) error {
|
|||
return fmt.Errorf("failed to load signin configs: %v", err)
|
||||
}
|
||||
|
||||
// Load register configurations from openapi/user/register directory
|
||||
err = loadRegisterConfigs(appConfig.Root)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load register configs: %v", err)
|
||||
}
|
||||
|
||||
// Load team configurations from openapi/user/team directory
|
||||
err = loadTeamConfigs(appConfig.Root)
|
||||
if err != nil {
|
||||
|
|
@ -357,6 +366,49 @@ func loadTeamConfigs(_ string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// loadRegisterConfigs loads all register configurations from the openapi/user/register directory
|
||||
func loadRegisterConfigs(_ string) error {
|
||||
// Use Walk to find all configuration files in the register directory
|
||||
err := application.App.Walk("openapi/user/register", func(root, filename string, isdir bool) error {
|
||||
if isdir {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Only process .yao files
|
||||
if !strings.HasSuffix(filename, ".yao") {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Extract locale from filename (basename without extension)
|
||||
baseName := filepath.Base(filename)
|
||||
locale := strings.ToLower(strings.TrimSuffix(baseName, ".yao"))
|
||||
|
||||
// Read configuration
|
||||
configRaw, err := application.App.Read(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read register config %s: %v", filename, err)
|
||||
}
|
||||
|
||||
// Parse the configuration
|
||||
var config RegisterConfig
|
||||
err = application.Parse(filename, configRaw, &config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse register config %s: %v", filename, err)
|
||||
}
|
||||
|
||||
// Store register configuration
|
||||
registerConfigs[locale] = &config
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to walk register directory: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetPublicConfig returns the public configuration for a given locale
|
||||
func GetPublicConfig(locale string) *Config {
|
||||
configMutex.RLock()
|
||||
|
|
@ -440,6 +492,34 @@ func GetTeamConfig(locale string) *TeamConfig {
|
|||
return nil
|
||||
}
|
||||
|
||||
// GetRegisterConfig returns the register configuration for a given locale
|
||||
func GetRegisterConfig(locale string) *RegisterConfig {
|
||||
configMutex.RLock()
|
||||
defer configMutex.RUnlock()
|
||||
|
||||
// Normalize language code to lowercase
|
||||
if locale != "" {
|
||||
locale = strings.TrimSpace(strings.ToLower(locale))
|
||||
}
|
||||
|
||||
// Try to get the specific locale configuration
|
||||
if config, exists := registerConfigs[locale]; exists {
|
||||
return config
|
||||
}
|
||||
|
||||
// If no specific locale, try to get "en" as default
|
||||
if config, exists := registerConfigs["en"]; exists {
|
||||
return config
|
||||
}
|
||||
|
||||
// If "en" is not available, try to get any available configuration
|
||||
for _, config := range registerConfigs {
|
||||
return config
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// extractEnvVarName extracts the environment variable name from a string like "$ENV.VAR_NAME"
|
||||
func extractEnvVarName(value string) string {
|
||||
if value == "" {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ func getCaptcha(c *gin.Context) {
|
|||
}
|
||||
|
||||
// LoginThirdParty is the handler for third party login
|
||||
func LoginThirdParty(providerID string, userinfo *oauthtypes.OIDCUserInfo, loginCtx *LoginContext) (*LoginResponse, error) {
|
||||
func LoginThirdParty(providerID string, userinfo *oauthtypes.OIDCUserInfo, loginCtx *LoginContext, locale string) (*LoginResponse, error) {
|
||||
|
||||
// Get provider
|
||||
provider, err := GetProvider(providerID)
|
||||
|
|
@ -87,6 +87,17 @@ func LoginThirdParty(providerID string, userinfo *oauthtypes.OIDCUserInfo, login
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Get register configuration for role and type
|
||||
registerConfig := GetRegisterConfig(locale)
|
||||
if registerConfig == nil {
|
||||
// If no register config found, try to get default register config
|
||||
log.Warn("Register configuration not found for locale '%s', trying default locale 'en'", locale)
|
||||
registerConfig = GetRegisterConfig("en")
|
||||
if registerConfig == nil {
|
||||
return nil, fmt.Errorf("register configuration not found. Please create register config files in openapi/user/register/")
|
||||
}
|
||||
}
|
||||
|
||||
// Check if user exists
|
||||
userProvider, err := oauth.OAuth.GetUserProvider()
|
||||
if err != nil {
|
||||
|
|
@ -109,8 +120,8 @@ func LoginThirdParty(providerID string, userinfo *oauthtypes.OIDCUserInfo, login
|
|||
"given_name": userinfo.GivenName,
|
||||
"family_name": userinfo.FamilyName,
|
||||
"picture": userinfo.Picture,
|
||||
"role_id": provider.Register.Role,
|
||||
"type_id": provider.Register.Type,
|
||||
"role_id": registerConfig.Role,
|
||||
"type_id": registerConfig.Type,
|
||||
"status": "active",
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -174,7 +174,14 @@ func authback(c *gin.Context) {
|
|||
|
||||
// LoginThirdParty(providerID, userInfo)
|
||||
loginCtx := makeLoginContext(c)
|
||||
loginResponse, err := LoginThirdParty(providerID, userInfo, loginCtx)
|
||||
|
||||
// Use locale from params, fallback to "en" if not provided
|
||||
locale := params.Locale
|
||||
if locale == "" {
|
||||
locale = "en"
|
||||
}
|
||||
|
||||
loginResponse, err := LoginThirdParty(providerID, userInfo, loginCtx, locale)
|
||||
if err != nil {
|
||||
errorResp := &response.ErrorResponse{
|
||||
Code: response.ErrInvalidRequest.Code,
|
||||
|
|
|
|||
|
|
@ -77,11 +77,23 @@ type ThirdParty struct {
|
|||
Providers []*Provider `json:"providers,omitempty"`
|
||||
}
|
||||
|
||||
// RegisterConfig represents the auto register configuration
|
||||
// ProviderRegisterConfig represents the auto register configuration in provider
|
||||
type ProviderRegisterConfig struct {
|
||||
Auto bool `json:"auto,omitempty"`
|
||||
}
|
||||
|
||||
// RegisterConfig represents the register configuration
|
||||
type RegisterConfig struct {
|
||||
Auto bool `json:"auto,omitempty"`
|
||||
Role string `json:"role,omitempty"`
|
||||
Type string `json:"type,omitempty"` // User type id
|
||||
Title string `json:"title,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Default bool `json:"default,omitempty"`
|
||||
SuccessURL string `json:"success_url,omitempty"`
|
||||
FailureURL string `json:"failure_url,omitempty"`
|
||||
AutoLogin bool `json:"auto_login,omitempty"`
|
||||
Role string `json:"role,omitempty"`
|
||||
Type string `json:"type,omitempty"` // User type id
|
||||
Form *FormConfig `json:"form,omitempty"`
|
||||
ConfirmPassword *PasswordConfig `json:"confirm_password,omitempty"`
|
||||
}
|
||||
|
||||
// YaoClientConfig represents the Yao OpenAPI Client config
|
||||
|
|
@ -95,21 +107,21 @@ type YaoClientConfig struct {
|
|||
|
||||
// Provider represents a third party login provider
|
||||
type Provider struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Label string `json:"label,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Logo string `json:"logo,omitempty"`
|
||||
Color string `json:"color,omitempty"`
|
||||
TextColor string `json:"text_color,omitempty"`
|
||||
ClientID string `json:"client_id,omitempty"`
|
||||
ClientSecret string `json:"client_secret,omitempty"`
|
||||
ClientSecretGenerator *SecretGenerator `json:"client_secret_generator,omitempty"`
|
||||
Scopes []string `json:"scopes,omitempty"`
|
||||
ResponseMode string `json:"response_mode,omitempty"`
|
||||
UserInfoSource string `json:"user_info_source,omitempty"` // "endpoint" (default) | "id_token" | "access_token"
|
||||
Endpoints *Endpoints `json:"endpoints,omitempty"`
|
||||
Mapping interface{} `json:"mapping,omitempty"` // string (preset) | map[string]string (custom) | nil (generic)
|
||||
Register *RegisterConfig `json:"register,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Label string `json:"label,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Logo string `json:"logo,omitempty"`
|
||||
Color string `json:"color,omitempty"`
|
||||
TextColor string `json:"text_color,omitempty"`
|
||||
ClientID string `json:"client_id,omitempty"`
|
||||
ClientSecret string `json:"client_secret,omitempty"`
|
||||
ClientSecretGenerator *SecretGenerator `json:"client_secret_generator,omitempty"`
|
||||
Scopes []string `json:"scopes,omitempty"`
|
||||
ResponseMode string `json:"response_mode,omitempty"`
|
||||
UserInfoSource string `json:"user_info_source,omitempty"` // "endpoint" (default) | "id_token" | "access_token"
|
||||
Endpoints *Endpoints `json:"endpoints,omitempty"`
|
||||
Mapping interface{} `json:"mapping,omitempty"` // string (preset) | map[string]string (custom) | nil (generic)
|
||||
Register *ProviderRegisterConfig `json:"register,omitempty"`
|
||||
}
|
||||
|
||||
// SecretGenerator represents the client secret generator configuration
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue