forked from baron/baron-sso
feat: implement dynamic tenant provisioning and remove hardcoded company mappings
This commit is contained in:
@@ -521,6 +521,14 @@ func (h *AuthHandler) Signup(c *fiber.Ctx) error {
|
||||
slog.Warn("[Signup] Attempted to join non-active tenant by domain", "email", req.Email, "tenant", tenant.Slug, "status", tenant.Status)
|
||||
return errorJSON(c, fiber.StatusForbidden, "Your organization's tenant is currently not active.")
|
||||
}
|
||||
} else {
|
||||
// [New Policy] Try dynamic provisioning via Group Policies if tenant doesn't exist
|
||||
tenant, err := h.TenantService.ProvisionTenantByDomain(c.Context(), domainName)
|
||||
if err == nil && tenant != nil {
|
||||
slog.Info("[Signup] Auto-provisioned tenant via group policy", "email", req.Email, "tenant", tenant.Slug)
|
||||
companyCode = tenant.Slug
|
||||
tenantID = &tenant.ID
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -529,8 +537,6 @@ func (h *AuthHandler) Signup(c *fiber.Ctx) error {
|
||||
tenant, err := h.TenantService.GetTenantBySlug(c.Context(), req.CompanyCode)
|
||||
if err == nil && tenant != nil {
|
||||
if tenant.Status == domain.TenantStatusActive {
|
||||
// Policy: Should we allow manual joining by Slug?
|
||||
// For now, let's allow it but log it as manual.
|
||||
slog.Info("[Signup] Assigning tenant by manual slug", "email", req.Email, "tenant", tenant.Slug)
|
||||
companyCode = tenant.Slug
|
||||
tenantID = &tenant.ID
|
||||
@@ -538,54 +544,18 @@ func (h *AuthHandler) Signup(c *fiber.Ctx) error {
|
||||
return errorJSON(c, fiber.StatusForbidden, "The specified organization is not active.")
|
||||
}
|
||||
} else {
|
||||
// If companyCode provided but not found, we automatically create one
|
||||
// [New Policy] 자동 생성 로직 추가
|
||||
slog.Info("[Signup] CompanyCode not found, creating new tenant automatically", "slug", req.CompanyCode)
|
||||
|
||||
// Determine name from CompanyCode
|
||||
tenantName := req.CompanyCode
|
||||
// Map slug to localized name if possible
|
||||
slugToName := map[string]string{
|
||||
"HANMAC": "한맥",
|
||||
"SAMAN": "삼안",
|
||||
"JANGHEON": "장헌",
|
||||
"HALLA": "한라",
|
||||
"PTC": "PTC",
|
||||
"BARON": "바론",
|
||||
}
|
||||
if name, ok := slugToName[strings.ToUpper(req.CompanyCode)]; ok {
|
||||
tenantName = name
|
||||
}
|
||||
|
||||
// Create the tenant
|
||||
// Note: creatorID is unknown at this point, will be set via Read-Model sync later
|
||||
newTenant, err := h.TenantService.RegisterTenant(c.Context(),
|
||||
tenantName,
|
||||
req.CompanyCode,
|
||||
domain.TenantTypeCompany,
|
||||
"Automatically created during signup",
|
||||
nil, // domains
|
||||
nil, // parentID
|
||||
"", // creatorID (will sync later)
|
||||
)
|
||||
if err != nil {
|
||||
// Handle race condition: if tenant was created by another request just now
|
||||
if strings.Contains(err.Error(), "already exists") {
|
||||
newTenant, err = h.TenantService.GetTenantBySlug(c.Context(), req.CompanyCode)
|
||||
}
|
||||
|
||||
if err != nil || newTenant == nil {
|
||||
slog.Error("[Signup] Failed to create tenant automatically", "slug", req.CompanyCode, "error", err)
|
||||
return errorJSON(c, fiber.StatusInternalServerError, "Failed to initialize organization.")
|
||||
}
|
||||
}
|
||||
|
||||
slog.Info("[Signup] Successfully created missing tenant", "slug", req.CompanyCode, "id", newTenant.ID)
|
||||
tenantID = &newTenant.ID
|
||||
companyCode = newTenant.Slug
|
||||
// [New Policy] Do NOT create tenants automatically with hardcoded names.
|
||||
// Only allow joining existing tenants.
|
||||
slog.Warn("[Signup] Attempted to join non-existent organization", "slug", req.CompanyCode, "email", req.Email)
|
||||
return errorJSON(c, fiber.StatusNotFound, "The specified organization code was not found. Please contact your administrator.")
|
||||
}
|
||||
}
|
||||
|
||||
if tenantID == nil {
|
||||
slog.Warn("[Signup] No tenant assigned to user", "email", req.Email)
|
||||
return errorJSON(c, fiber.StatusBadRequest, "We couldn't identify your organization. Please provide a company code or use your corporate email.")
|
||||
}
|
||||
|
||||
// Normalize Phone (E.164 형태로 보관)
|
||||
normalizedPhone := strings.ReplaceAll(req.Phone, "-", "")
|
||||
normalizedPhone = strings.ReplaceAll(normalizedPhone, " ", "")
|
||||
|
||||
Reference in New Issue
Block a user