fix: 支持系统域名完整邮箱标识直接解析有效账号与协议认证
Some checks are pending
Security Checks / security (push) Waiting to run
Some checks are pending
Security Checks / security (push) Waiting to run
This commit is contained in:
parent
875b83fa2a
commit
343d038ee3
@ -72,24 +72,44 @@ func ResolveIdentifier(identifier string) (ResolvedIdentity, error) {
|
||||
Find(&bindings); err != nil {
|
||||
return ResolvedIdentity{}, fmt.Errorf("load login email binding: %w", err)
|
||||
}
|
||||
if len(bindings) != 1 || bindings[0].UserID <= 0 {
|
||||
return ResolvedIdentity{}, errors.New("invalid identifier")
|
||||
if len(bindings) == 1 && bindings[0].UserID > 0 {
|
||||
var user models.User
|
||||
has, err := db.Instance.ID(bindings[0].UserID).Get(&user)
|
||||
if err != nil {
|
||||
return ResolvedIdentity{}, fmt.Errorf("load login user: %w", err)
|
||||
}
|
||||
if has && user.ID > 0 && user.Account != "" && user.Disabled == 0 {
|
||||
return ResolvedIdentity{
|
||||
UserID: user.ID,
|
||||
Account: user.Account,
|
||||
LoginAddress: normalized,
|
||||
Kind: IdentifierEmail,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
var user models.User
|
||||
has, err := db.Instance.ID(bindings[0].UserID).Get(&user)
|
||||
if err != nil {
|
||||
return ResolvedIdentity{}, fmt.Errorf("load login user: %w", err)
|
||||
// 回退机制:若未绑定独立外部邮箱,但属于系统配置的域名,则按账号匹配有效系统用户
|
||||
parts := strings.SplitN(normalized, "@", 2)
|
||||
if len(parts) == 2 && isConfiguredLoginDomain(parts[1]) {
|
||||
account, err := validation.NormalizeAccount(parts[0])
|
||||
if err == nil {
|
||||
var user models.User
|
||||
has, err := db.Instance.Where("account = ? AND disabled = 0", account).Get(&user)
|
||||
if err != nil {
|
||||
return ResolvedIdentity{}, fmt.Errorf("load domain user: %w", err)
|
||||
}
|
||||
if has && user.ID > 0 && user.Account != "" {
|
||||
return ResolvedIdentity{
|
||||
UserID: user.ID,
|
||||
Account: user.Account,
|
||||
LoginAddress: normalized,
|
||||
Kind: IdentifierEmail,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if !has || user.ID <= 0 || user.Account == "" {
|
||||
return ResolvedIdentity{}, errors.New("invalid identifier")
|
||||
}
|
||||
return ResolvedIdentity{
|
||||
UserID: user.ID,
|
||||
Account: user.Account,
|
||||
LoginAddress: normalized,
|
||||
Kind: IdentifierEmail,
|
||||
}, nil
|
||||
|
||||
return ResolvedIdentity{}, errors.New("invalid identifier")
|
||||
}
|
||||
|
||||
func parseLoginIdentifier(identifier string) (string, IdentifierKind, error) {
|
||||
|
||||
@ -92,3 +92,53 @@ func TestNormalizeIdentifierKeepsLegacyAccountCompatibility(t *testing.T) {
|
||||
t.Fatalf("normalized email key = %q, err = %v", got, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func TestResolveIdentifierFallbackToConfiguredDomainUser(t *testing.T) {
|
||||
oldConfig := config.Instance
|
||||
oldDB := db.Instance
|
||||
config.Instance = &config.Config{
|
||||
DbType: config.DBTypeSQLite,
|
||||
DbDSN: filepath.Join(t.TempDir(), "domain_fallback.db"),
|
||||
Domain: "solit.cn",
|
||||
Domains: []string{"solit.cn"},
|
||||
}
|
||||
if err := db.Init(""); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
if db.Instance != nil && db.Instance != oldDB {
|
||||
_ = db.Instance.Close()
|
||||
}
|
||||
db.Instance = oldDB
|
||||
config.Instance = oldConfig
|
||||
})
|
||||
|
||||
user := models.User{Account: "bob", Name: "Bob", Disabled: 0}
|
||||
if err := SetPassword(&user, "CorrectP12"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := db.Instance.Insert(&user); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
identity, err := ResolveIdentifier(" Bob@Solit.cn ")
|
||||
if err != nil {
|
||||
t.Fatalf("resolve configured domain user failed: %v", err)
|
||||
}
|
||||
if identity.Kind != IdentifierEmail || identity.UserID != user.ID || identity.Account != "bob" || identity.LoginAddress != "bob@solit.cn" {
|
||||
t.Fatalf("unexpected resolved identity: %+v", identity)
|
||||
}
|
||||
|
||||
disabledUser := models.User{Account: "charlie", Name: "Charlie", Disabled: 1}
|
||||
if _, err := db.Instance.Insert(&disabledUser); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := ResolveIdentifier("charlie@solit.cn"); err == nil {
|
||||
t.Fatal("disabled domain user must not be resolved")
|
||||
}
|
||||
|
||||
if _, err := ResolveIdentifier("bob@other.com"); err == nil {
|
||||
t.Fatal("unconfigured domain must not be resolved")
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user