forked from baron/baron-sso
156 lines
3.9 KiB
Go
156 lines
3.9 KiB
Go
package handler
|
|
|
|
import (
|
|
"baron-sso-backend/internal/domain"
|
|
"baron-sso-backend/internal/service"
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
func representativeTenantIDFromTraits(traits map[string]any) string {
|
|
if value := tenantClaimString(traits, "tenant_id"); value != "" {
|
|
return value
|
|
}
|
|
if value := tenantClaimString(traits, "primaryTenantId"); value != "" {
|
|
return value
|
|
}
|
|
if metadata, ok := traits["metadata"].(map[string]any); ok {
|
|
if value := tenantClaimString(metadata, "primaryTenantId"); value != "" {
|
|
return value
|
|
}
|
|
}
|
|
|
|
appointments := tenantAssignmentAppointmentsFromTraits(traits)
|
|
for _, appointment := range appointments {
|
|
if tenantAssignmentBool(appointment, "isPrimary", "primary", "representative", "isRepresentative") {
|
|
if value := tenantAssignmentTenantID(appointment); value != "" {
|
|
return value
|
|
}
|
|
}
|
|
}
|
|
for _, appointment := range appointments {
|
|
if value := tenantAssignmentTenantID(appointment); value != "" {
|
|
return value
|
|
}
|
|
}
|
|
|
|
for _, tenantID := range tenantNamespaceIDsFromTraits(traits) {
|
|
return tenantID
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func joinedTenantIDsFromTraits(traits map[string]any, representativeTenantID string) []string {
|
|
values := make([]string, 0)
|
|
if representativeTenantID != "" {
|
|
values = append(values, representativeTenantID)
|
|
}
|
|
if value := tenantClaimString(traits, "tenant_id"); value != "" {
|
|
values = append(values, value)
|
|
}
|
|
for _, appointment := range tenantAssignmentAppointmentsFromTraits(traits) {
|
|
if value := tenantAssignmentTenantID(appointment); value != "" {
|
|
values = append(values, value)
|
|
}
|
|
}
|
|
values = append(values, tenantNamespaceIDsFromTraits(traits)...)
|
|
return uniqueSortedStrings(values)
|
|
}
|
|
|
|
func tenantAssignmentAppointmentsFromTraits(traits map[string]any) []map[string]any {
|
|
raw := rawAdditionalAppointments(traits)
|
|
switch values := raw.(type) {
|
|
case []any:
|
|
appointments := make([]map[string]any, 0, len(values))
|
|
for _, item := range values {
|
|
if appointment, ok := item.(map[string]any); ok {
|
|
appointments = append(appointments, appointment)
|
|
}
|
|
}
|
|
return appointments
|
|
case []map[string]any:
|
|
return values
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func tenantAssignmentTenantID(appointment map[string]any) string {
|
|
for _, key := range []string{"tenantId", "tenant_id"} {
|
|
if value := tenantClaimString(appointment, key); value != "" {
|
|
return value
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func tenantAssignmentBool(values map[string]any, keys ...string) bool {
|
|
for _, key := range keys {
|
|
raw, ok := values[key]
|
|
if !ok || raw == nil {
|
|
continue
|
|
}
|
|
switch value := raw.(type) {
|
|
case bool:
|
|
if value {
|
|
return true
|
|
}
|
|
case string:
|
|
normalized := strings.ToLower(strings.TrimSpace(value))
|
|
if normalized == "true" || normalized == "1" || normalized == "yes" {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func tenantNamespaceIDsFromTraits(traits map[string]any) []string {
|
|
if traits == nil {
|
|
return nil
|
|
}
|
|
ids := make([]string, 0)
|
|
for key, value := range traits {
|
|
if key == "" || key == "metadata" {
|
|
continue
|
|
}
|
|
switch value.(type) {
|
|
case map[string]any:
|
|
ids = append(ids, key)
|
|
}
|
|
}
|
|
return uniqueSortedStrings(ids)
|
|
}
|
|
|
|
func createPersonalTenantForUser(ctx context.Context, tenantService service.TenantService, email string) (*domain.Tenant, error) {
|
|
if tenantService == nil {
|
|
return nil, errors.New("tenant service unavailable")
|
|
}
|
|
normalizedEmail := strings.ToLower(strings.TrimSpace(email))
|
|
if normalizedEmail == "" {
|
|
normalizedEmail = "user"
|
|
}
|
|
slug := "personal-" + strings.ReplaceAll(uuid.NewString(), "-", "")
|
|
tenant, err := tenantService.RegisterTenant(
|
|
ctx,
|
|
fmt.Sprintf("Personal - %s", normalizedEmail),
|
|
slug,
|
|
domain.TenantTypePersonal,
|
|
"Automatically provisioned personal tenant",
|
|
nil,
|
|
nil,
|
|
"",
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if tenant == nil {
|
|
return nil, errors.New("personal tenant not created")
|
|
}
|
|
return tenant, nil
|
|
}
|