Merge pull request #1195 from trheyi/main
Add register configuration support for user management
This commit is contained in:
commit
910770263d
4 changed files with 133 additions and 23 deletions
|
|
@ -33,6 +33,8 @@ var (
|
||||||
defaultConfig *Config
|
defaultConfig *Config
|
||||||
// Team configurations by locale
|
// Team configurations by locale
|
||||||
teamConfigs = make(map[string]*TeamConfig)
|
teamConfigs = make(map[string]*TeamConfig)
|
||||||
|
// Register configurations by locale
|
||||||
|
registerConfigs = make(map[string]*RegisterConfig)
|
||||||
// Mutex for thread safety
|
// Mutex for thread safety
|
||||||
configMutex sync.RWMutex
|
configMutex sync.RWMutex
|
||||||
)
|
)
|
||||||
|
|
@ -48,6 +50,7 @@ func Load(appConfig config.Config) error {
|
||||||
providers = make(map[string]*Provider)
|
providers = make(map[string]*Provider)
|
||||||
defaultConfig = nil
|
defaultConfig = nil
|
||||||
teamConfigs = make(map[string]*TeamConfig)
|
teamConfigs = make(map[string]*TeamConfig)
|
||||||
|
registerConfigs = make(map[string]*RegisterConfig)
|
||||||
|
|
||||||
// Load signin configurations from openapi/user/signin directory
|
// Load signin configurations from openapi/user/signin directory
|
||||||
err := loadSigninConfigs(appConfig.Root)
|
err := loadSigninConfigs(appConfig.Root)
|
||||||
|
|
@ -55,6 +58,12 @@ func Load(appConfig config.Config) error {
|
||||||
return fmt.Errorf("failed to load signin configs: %v", err)
|
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
|
// Load team configurations from openapi/user/team directory
|
||||||
err = loadTeamConfigs(appConfig.Root)
|
err = loadTeamConfigs(appConfig.Root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -357,6 +366,49 @@ func loadTeamConfigs(_ string) error {
|
||||||
return nil
|
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
|
// GetPublicConfig returns the public configuration for a given locale
|
||||||
func GetPublicConfig(locale string) *Config {
|
func GetPublicConfig(locale string) *Config {
|
||||||
configMutex.RLock()
|
configMutex.RLock()
|
||||||
|
|
@ -440,6 +492,34 @@ func GetTeamConfig(locale string) *TeamConfig {
|
||||||
return nil
|
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"
|
// extractEnvVarName extracts the environment variable name from a string like "$ENV.VAR_NAME"
|
||||||
func extractEnvVarName(value string) string {
|
func extractEnvVarName(value string) string {
|
||||||
if value == "" {
|
if value == "" {
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ func getCaptcha(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoginThirdParty is the handler for third party login
|
// 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
|
// Get provider
|
||||||
provider, err := GetProvider(providerID)
|
provider, err := GetProvider(providerID)
|
||||||
|
|
@ -87,6 +87,17 @@ func LoginThirdParty(providerID string, userinfo *oauthtypes.OIDCUserInfo, login
|
||||||
return nil, err
|
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
|
// Check if user exists
|
||||||
userProvider, err := oauth.OAuth.GetUserProvider()
|
userProvider, err := oauth.OAuth.GetUserProvider()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -109,8 +120,8 @@ func LoginThirdParty(providerID string, userinfo *oauthtypes.OIDCUserInfo, login
|
||||||
"given_name": userinfo.GivenName,
|
"given_name": userinfo.GivenName,
|
||||||
"family_name": userinfo.FamilyName,
|
"family_name": userinfo.FamilyName,
|
||||||
"picture": userinfo.Picture,
|
"picture": userinfo.Picture,
|
||||||
"role_id": provider.Register.Role,
|
"role_id": registerConfig.Role,
|
||||||
"type_id": provider.Register.Type,
|
"type_id": registerConfig.Type,
|
||||||
"status": "active",
|
"status": "active",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,14 @@ func authback(c *gin.Context) {
|
||||||
|
|
||||||
// LoginThirdParty(providerID, userInfo)
|
// LoginThirdParty(providerID, userInfo)
|
||||||
loginCtx := makeLoginContext(c)
|
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 {
|
if err != nil {
|
||||||
errorResp := &response.ErrorResponse{
|
errorResp := &response.ErrorResponse{
|
||||||
Code: response.ErrInvalidRequest.Code,
|
Code: response.ErrInvalidRequest.Code,
|
||||||
|
|
|
||||||
|
|
@ -77,11 +77,23 @@ type ThirdParty struct {
|
||||||
Providers []*Provider `json:"providers,omitempty"`
|
Providers []*Provider `json:"providers,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterConfig represents the auto register configuration
|
// ProviderRegisterConfig represents the auto register configuration in provider
|
||||||
type RegisterConfig struct {
|
type ProviderRegisterConfig struct {
|
||||||
Auto bool `json:"auto,omitempty"`
|
Auto bool `json:"auto,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterConfig represents the register configuration
|
||||||
|
type RegisterConfig struct {
|
||||||
|
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"`
|
Role string `json:"role,omitempty"`
|
||||||
Type string `json:"type,omitempty"` // User type id
|
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
|
// YaoClientConfig represents the Yao OpenAPI Client config
|
||||||
|
|
@ -109,7 +121,7 @@ type Provider struct {
|
||||||
UserInfoSource string `json:"user_info_source,omitempty"` // "endpoint" (default) | "id_token" | "access_token"
|
UserInfoSource string `json:"user_info_source,omitempty"` // "endpoint" (default) | "id_token" | "access_token"
|
||||||
Endpoints *Endpoints `json:"endpoints,omitempty"`
|
Endpoints *Endpoints `json:"endpoints,omitempty"`
|
||||||
Mapping interface{} `json:"mapping,omitempty"` // string (preset) | map[string]string (custom) | nil (generic)
|
Mapping interface{} `json:"mapping,omitempty"` // string (preset) | map[string]string (custom) | nil (generic)
|
||||||
Register *RegisterConfig `json:"register,omitempty"`
|
Register *ProviderRegisterConfig `json:"register,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SecretGenerator represents the client secret generator configuration
|
// SecretGenerator represents the client secret generator configuration
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue