forked from baron/baron-sso
테넌트 등록 방식을 결정
This commit is contained in:
@@ -4,6 +4,8 @@ import (
|
||||
"baron-sso-backend/internal/domain"
|
||||
"baron-sso-backend/internal/service"
|
||||
"baron-sso-backend/internal/utils"
|
||||
"context"
|
||||
"log/slog"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -11,29 +13,32 @@ import (
|
||||
)
|
||||
|
||||
type UserHandler struct {
|
||||
KratosAdmin *service.KratosAdminService
|
||||
OryProvider *service.OryProvider
|
||||
KratosAdmin *service.KratosAdminService
|
||||
OryProvider *service.OryProvider
|
||||
TenantService service.TenantService
|
||||
}
|
||||
|
||||
func NewUserHandler(kratosAdmin *service.KratosAdminService, oryProvider *service.OryProvider) *UserHandler {
|
||||
func NewUserHandler(kratosAdmin *service.KratosAdminService, oryProvider *service.OryProvider, tenantService service.TenantService) *UserHandler {
|
||||
return &UserHandler{
|
||||
KratosAdmin: kratosAdmin,
|
||||
OryProvider: oryProvider,
|
||||
KratosAdmin: kratosAdmin,
|
||||
OryProvider: oryProvider,
|
||||
TenantService: tenantService,
|
||||
}
|
||||
}
|
||||
|
||||
type userSummary struct {
|
||||
ID string `json:"id"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
Phone string `json:"phone"`
|
||||
Role string `json:"role"`
|
||||
Status string `json:"status"`
|
||||
CompanyCode string `json:"companyCode"`
|
||||
Department string `json:"department"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
InitialPassword string `json:"initialPassword,omitempty"`
|
||||
ID string `json:"id"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
Phone string `json:"phone"`
|
||||
Role string `json:"role"`
|
||||
Status string `json:"status"`
|
||||
CompanyCode string `json:"companyCode"`
|
||||
Tenant *domain.Tenant `json:"tenant,omitempty"`
|
||||
Department string `json:"department"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
InitialPassword string `json:"initialPassword,omitempty"`
|
||||
}
|
||||
|
||||
type userListResponse struct {
|
||||
@@ -89,7 +94,8 @@ func (h *UserHandler) ListUsers(c *fiber.Ctx) error {
|
||||
|
||||
items := make([]userSummary, 0, end-offset)
|
||||
for _, identity := range filtered[offset:end] {
|
||||
items = append(items, mapIdentitySummary(identity))
|
||||
summary := h.mapIdentitySummary(c.Context(), identity)
|
||||
items = append(items, summary)
|
||||
}
|
||||
|
||||
return c.JSON(userListResponse{Items: items, Limit: limit, Offset: offset, Total: total})
|
||||
@@ -113,7 +119,7 @@ func (h *UserHandler) GetUser(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "user not found"})
|
||||
}
|
||||
|
||||
return c.JSON(mapIdentitySummary(*identity))
|
||||
return c.JSON(h.mapIdentitySummary(c.Context(), *identity))
|
||||
}
|
||||
|
||||
func (h *UserHandler) CreateUser(c *fiber.Ctx) error {
|
||||
@@ -138,6 +144,9 @@ func (h *UserHandler) CreateUser(c *fiber.Ctx) error {
|
||||
if email == "" {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "email is required"})
|
||||
}
|
||||
if !strings.Contains(email, "@") || !strings.Contains(email, ".") {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid email format"})
|
||||
}
|
||||
name := strings.TrimSpace(req.Name)
|
||||
if name == "" {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "name is required"})
|
||||
@@ -205,7 +214,7 @@ func (h *UserHandler) CreateUser(c *fiber.Ctx) error {
|
||||
return c.Status(fiber.StatusCreated).JSON(fiber.Map{"id": identityID, "initialPassword": generatedPassword})
|
||||
}
|
||||
|
||||
response := mapIdentitySummary(*identity)
|
||||
response := h.mapIdentitySummary(c.Context(), *identity)
|
||||
if generatedPassword != "" {
|
||||
response.InitialPassword = generatedPassword
|
||||
}
|
||||
@@ -279,7 +288,7 @@ func (h *UserHandler) UpdateUser(c *fiber.Ctx) error {
|
||||
}
|
||||
}
|
||||
|
||||
return c.JSON(mapIdentitySummary(*updated))
|
||||
return c.JSON(h.mapIdentitySummary(c.Context(), *updated))
|
||||
}
|
||||
|
||||
func (h *UserHandler) DeleteUser(c *fiber.Ctx) error {
|
||||
@@ -299,24 +308,35 @@ func (h *UserHandler) DeleteUser(c *fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusNoContent)
|
||||
}
|
||||
|
||||
func mapIdentitySummary(identity service.KratosIdentity) userSummary {
|
||||
func (h *UserHandler) mapIdentitySummary(ctx context.Context, identity service.KratosIdentity) userSummary {
|
||||
traits := identity.Traits
|
||||
role := extractTraitString(traits, "grade")
|
||||
if role == "" {
|
||||
role = "user"
|
||||
}
|
||||
return userSummary{
|
||||
|
||||
compCode := extractTraitString(traits, "companyCode")
|
||||
slog.Debug("Mapping identity", "email", extractTraitString(traits, "email"), "compCode", compCode)
|
||||
summary := userSummary{
|
||||
ID: identity.ID,
|
||||
Email: extractTraitString(traits, "email"),
|
||||
Name: extractTraitString(traits, "name"),
|
||||
Phone: extractTraitString(traits, "phone_number"),
|
||||
Role: role,
|
||||
Status: normalizeStatus(identity.State),
|
||||
CompanyCode: extractTraitString(traits, "companyCode"),
|
||||
CompanyCode: compCode,
|
||||
Department: extractTraitString(traits, "department"),
|
||||
CreatedAt: formatTime(identity.CreatedAt),
|
||||
UpdatedAt: formatTime(identity.UpdatedAt),
|
||||
}
|
||||
|
||||
if compCode != "" && h.TenantService != nil {
|
||||
if tenant, err := h.TenantService.GetTenantBySlug(ctx, compCode); err == nil && tenant != nil {
|
||||
summary.Tenant = tenant
|
||||
}
|
||||
}
|
||||
|
||||
return summary
|
||||
}
|
||||
|
||||
func extractTraitString(traits map[string]interface{}, key string) string {
|
||||
|
||||
Reference in New Issue
Block a user