1
0
forked from baron/baron-sso

사용자 테넌트 소속 데이터 정리

This commit is contained in:
2026-05-13 18:23:39 +09:00
parent 8a6e41d74c
commit e36a973053
26 changed files with 348 additions and 387 deletions

View File

@@ -704,8 +704,12 @@ func (h *AuthHandler) Signup(c *fiber.Ctx) error {
return errorJSON(c, fiber.StatusInternalServerError, "Identity provider unavailable")
}
if strings.TrimSpace(req.CompanyCode) != "" {
return errorJSON(c, fiber.StatusBadRequest, "companyCode is deprecated; use tenantSlug")
}
// 소속이 비어 있는 일반 가입자는 PERSONAL tenant를 자동 생성해 대표소속을 보장합니다.
companyCode := ""
tenantSlug := strings.TrimSpace(req.TenantSlug)
var tenantID *string
parts := strings.Split(req.Email, "@")
@@ -726,33 +730,28 @@ func (h *AuthHandler) Signup(c *fiber.Ctx) error {
slog.Info("[Signup] Forcing AffiliationType to GENERAL", "email", req.Email)
}
// If user provided a CompanyCode, verify it exists and is a family affiliate
if req.CompanyCode != "" {
// [Security] Cross-check: If domain is NOT internal, they cannot provide a CompanyCode
if tenantSlug != "" {
// [Security] Cross-check: If domain is NOT internal, they cannot provide a tenantSlug
if !isInternal {
slog.Warn("[Signup] Security violation: non-internal email providing CompanyCode", "email", req.Email)
slog.Warn("[Signup] Security violation: non-internal email providing tenantSlug", "email", req.Email)
return errorJSON(c, fiber.StatusForbidden, "Only affiliate members can join an organization.")
}
// Verify the selected company code exists and is indeed a family company
if !affiliateSlugs[strings.ToLower(req.CompanyCode)] {
if !affiliateSlugs[strings.ToLower(tenantSlug)] {
return errorJSON(c, fiber.StatusForbidden, "The selected organization is not a valid family affiliate.")
}
tenant, err := h.TenantService.GetTenantBySlug(c.Context(), req.CompanyCode)
tenant, err := h.TenantService.GetTenantBySlug(c.Context(), tenantSlug)
if err == nil && tenant != nil {
if tenant.Status == domain.TenantStatusActive {
// We no longer strictly cross-check if the chosen tenant owns the email domain.
// Being an 'isInternal' (family) email is enough to join ANY family affiliate.
slog.Info("[Signup] Assigning tenant by manual slug", "email", req.Email, "tenant", tenant.Slug)
companyCode = tenant.Slug
tenantSlug = tenant.Slug
tenantID = &tenant.ID
} else {
return errorJSON(c, fiber.StatusForbidden, "The specified organization is not active.")
}
} else {
slog.Warn("[Signup] Attempted to join non-existent organization", "slug", req.CompanyCode, "email", req.Email)
slog.Warn("[Signup] Attempted to join non-existent organization", "slug", tenantSlug, "email", req.Email)
return errorJSON(c, fiber.StatusNotFound, "The specified organization code was not found.")
}
} else {
@@ -770,7 +769,7 @@ func (h *AuthHandler) Signup(c *fiber.Ctx) error {
if err != nil {
return errorJSON(c, fiber.StatusServiceUnavailable, "failed to create personal tenant")
}
companyCode = tenant.Slug
tenantSlug = tenant.Slug
tenantID = &tenant.ID
}
@@ -789,7 +788,6 @@ func (h *AuthHandler) Signup(c *fiber.Ctx) error {
attributes := map[string]interface{}{
"department": req.Department,
"affiliationType": req.AffiliationType,
"companyCode": companyCode,
"grade": "",
"role": domain.RoleUser,
}
@@ -844,7 +842,6 @@ func (h *AuthHandler) Signup(c *fiber.Ctx) error {
Phone: normalizedPhone,
Role: "user",
AffiliationType: req.AffiliationType,
CompanyCode: companyCode,
Department: req.Department,
Status: "active",
CreatedAt: time.Now(),
@@ -7508,7 +7505,6 @@ func (h *AuthHandler) mapKratosIdentityToProfile(identityID string, traits map[s
phone, _ := traits["phone_number"].(string)
dept, _ := traits["department"].(string)
affType, _ := traits["affiliationType"].(string)
compCode, _ := traits["companyCode"].(string)
role, _ := traits["role"].(string)
tenantID, _ := traits["tenant_id"].(string)
relyingPartyID, _ := traits["relying_party_id"].(string)
@@ -7520,7 +7516,6 @@ func (h *AuthHandler) mapKratosIdentityToProfile(identityID string, traits map[s
Phone: h.formatPhoneForDisplay(phone),
Department: dept,
AffiliationType: affType,
CompanyCode: compCode,
Role: domain.NormalizeRole(role),
Metadata: make(map[string]any),
}
@@ -7591,16 +7586,6 @@ func (h *AuthHandler) mapKratosTraitsToLocalUser(identityID string, traits map[s
localUser.AffiliationType = affType
}
companyCode := extractTraitString(traits, "companyCode")
if companyCode == "" {
companyCode = extractTraitString(traits, "company_code")
}
if companyCode != "" {
localUser.CompanyCode = companyCode
}
if companyCodes := extractTraitStringArray(traits, "companyCodes"); len(companyCodes) > 0 {
localUser.CompanyCodes = pq.StringArray(companyCodes)
}
if tenantID := extractTraitString(traits, "tenant_id"); tenantID != "" {
localUser.TenantID = &tenantID
}