feat: validate personal and enterprise auth tenants

This commit is contained in:
richjohnrambo
2026-09-21 21:24:25 +08:00
parent fc393cd685
commit 186cfa21c8
9 changed files with 689 additions and 53 deletions
+124
View File
@@ -43,6 +43,12 @@ func replyCreateUser(s *Session, msg *ClientComMessage, rec *auth.Rec) {
return
}
if err := validateAccountRegistrationTenant(s, msg); err != nil {
logs.Warn.Println("create user: invalid registration tenant fields", err, "sid=", s.sid)
s.queueOut(decodeStoreError(types.ErrPolicy, msg.Id, msg.Timestamp, registrationTenantErrorParams(err)))
return
}
account, phone, secretAccount, phoneRegistration, err := resolveRegistrationAccount(msg.Acc.Username, msg.Acc.Phone)
if err != nil || !registrationSecretMatches(msg.Acc.Secret, secretAccount) {
logs.Warn.Println("create user: invalid registration account fields, sid=", s.sid)
@@ -382,6 +388,124 @@ func resolveRegistrationAccount(username, phone string) (account, canonicalPhone
return username, "", username, false, nil
}
var (
errRegistrationTypeRequired = errors.New("registration_type required")
errRegistrationTypeInvalid = errors.New("registration_type invalid")
errRegistrationTenantForbidden = errors.New("registration tenant forbidden")
errRegistrationTenantRequired = errors.New("registration tenant required")
errRegistrationTenantMismatch = errors.New("registration tenant mismatch")
errLoginTypeRequired = errors.New("login_type required")
errLoginTypeInvalid = errors.New("login_type invalid")
)
func validateAccountRegistrationTenant(s *Session, msg *ClientComMessage) error {
if msg == nil || msg.Acc == nil || msg.Acc.RegistrationType == nil {
return errRegistrationTypeRequired
}
tenantCode := strings.TrimSpace(msg.Acc.TenantCode)
switch *msg.Acc.RegistrationType {
case registrationTypePersonal:
if tenantCode != "" {
return errRegistrationTenantForbidden
}
if !strings.EqualFold(s.tenantCode, imDefaultTenantCode) {
return errRegistrationTenantMismatch
}
case registrationTypeEnterprise:
if tenantCode == "" {
return errRegistrationTenantRequired
}
if strings.EqualFold(tenantCode, imDefaultTenantCode) {
return errRegistrationTenantForbidden
}
if !strings.EqualFold(s.tenantCode, tenantCode) {
return errRegistrationTenantMismatch
}
default:
return errRegistrationTypeInvalid
}
return nil
}
func registrationTenantErrorParams(err error) map[string]any {
params := map[string]any{"what": "registration_type", "reason": "REGISTRATION_TYPE_INVALID"}
switch {
case errors.Is(err, errRegistrationTypeRequired):
params["reason"] = "REGISTRATION_TYPE_REQUIRED"
case errors.Is(err, errRegistrationTypeInvalid):
params["reason"] = "REGISTRATION_TYPE_INVALID"
case errors.Is(err, errRegistrationTenantRequired):
params["what"] = "tenant_code"
params["reason"] = "TENANT_CODE_REQUIRED"
case errors.Is(err, errRegistrationTenantForbidden):
params["what"] = "tenant_code"
params["reason"] = "TENANT_CODE_FORBIDDEN"
case errors.Is(err, errRegistrationTenantMismatch):
params["what"] = "tenant_code"
params["reason"] = "TENANT_CODE_MISMATCH"
}
return params
}
func validateLoginTenant(s *Session, msg *ClientComMessage) error {
if msg == nil || msg.Login == nil {
return nil
}
if msg.Login.Scheme != "basic" && msg.Login.LoginType == nil {
return nil
}
if msg.Login.LoginType == nil {
return errLoginTypeRequired
}
tenantCode := strings.TrimSpace(msg.Login.TenantCode)
switch *msg.Login.LoginType {
case registrationTypePersonal:
if tenantCode != "" && !strings.EqualFold(tenantCode, imDefaultTenantCode) {
return errRegistrationTenantForbidden
}
if !strings.EqualFold(s.tenantCode, imDefaultTenantCode) {
return errRegistrationTenantMismatch
}
case registrationTypeEnterprise:
if tenantCode == "" {
tenantCode = s.tenantCode
}
if tenantCode == "" {
return errRegistrationTenantRequired
}
if strings.EqualFold(tenantCode, imDefaultTenantCode) {
return errRegistrationTenantForbidden
}
if !strings.EqualFold(s.tenantCode, tenantCode) {
return errRegistrationTenantMismatch
}
default:
return errLoginTypeInvalid
}
return nil
}
func loginTenantErrorParams(err error) map[string]any {
params := map[string]any{"what": "login_type", "reason": "LOGIN_TYPE_INVALID"}
switch {
case errors.Is(err, errLoginTypeRequired):
params["reason"] = "LOGIN_TYPE_REQUIRED"
case errors.Is(err, errLoginTypeInvalid):
params["reason"] = "LOGIN_TYPE_INVALID"
case errors.Is(err, errRegistrationTenantRequired):
params["what"] = "tenant_code"
params["reason"] = "TENANT_CODE_REQUIRED"
case errors.Is(err, errRegistrationTenantForbidden):
params["what"] = "tenant_code"
params["reason"] = "TENANT_CODE_FORBIDDEN"
case errors.Is(err, errRegistrationTenantMismatch):
params["what"] = "tenant_code"
params["reason"] = "TENANT_CODE_MISMATCH"
}
return params
}
func validateRegistrationUsername(username string) error {
if username == "" || len(username) > 10 {
return types.ErrPolicy