From 4a49c702b34a512c75f32b13e90e06bf4d425e2f Mon Sep 17 00:00:00 2001 From: chan Date: Tue, 27 Jan 2026 13:42:36 +0900 Subject: [PATCH] admin page del --- backend/cmd/server/main.go | 5 - backend/internal/handler/admin_handler.go | 235 +--------------------- 2 files changed, 1 insertion(+), 239 deletions(-) diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go index bc132340..d4ec8499 100644 --- a/backend/cmd/server/main.go +++ b/backend/cmd/server/main.go @@ -251,12 +251,7 @@ func main() { // Admin Routes admin := api.Group("/admin") - admin.Post("/users", adminHandler.CreateUser) admin.Get("/check", adminHandler.CheckAuth) - admin.Get("/users", adminHandler.ListUsers) - admin.Patch("/users/:loginId", adminHandler.UpdateUser) - admin.Delete("/users/:loginId", adminHandler.DeleteUser) - admin.Patch("/users/:loginId/status", adminHandler.UpdateUserStatus) // Webhook for Descope Generic SMS Gateway auth.Post("/webhooks/descope-sms", authHandler.HandleDescopeSmsRelay) diff --git a/backend/internal/handler/admin_handler.go b/backend/internal/handler/admin_handler.go index a324dfd4..a6f8354c 100644 --- a/backend/internal/handler/admin_handler.go +++ b/backend/internal/handler/admin_handler.go @@ -1,13 +1,9 @@ package handler import ( - "context" "log/slog" - "net/url" "os" - "strings" - "github.com/descope/go-sdk/descope" "github.com/descope/go-sdk/descope/client" "github.com/gofiber/fiber/v2" ) @@ -40,10 +36,6 @@ func NewAdminHandler() *AdminHandler { } } -func boolPtr(b bool) *bool { - return &b -} - // checkAuth Helper func (h *AdminHandler) checkAuth(c *fiber.Ctx) error { adminPass := os.Getenv("ADMIN_PASSWORD") @@ -58,234 +50,9 @@ func (h *AdminHandler) checkAuth(c *fiber.Ctx) error { return nil } -type CreateUserRequest struct { - LoginID string `json:"loginId"` - Email string `json:"email"` - Phone string `json:"phone"` - DisplayName string `json:"displayName"` - Roles []string `json:"roles"` - Tenants map[string][]string `json:"tenants"` // tenantId -> roles -} - func (h *AdminHandler) CheckAuth(c *fiber.Ctx) error { if err := h.checkAuth(c); err != nil { return err } return c.Status(fiber.StatusOK).JSON(fiber.Map{"status": "ok"}) -} - -// ListUsers - GET /api/v1/admin/users -func (h *AdminHandler) ListUsers(c *fiber.Ctx) error { - if err := h.checkAuth(c); err != nil { - return err - } - - text := c.Query("text") - // Limit is not directly supported in SearchAll options as a simple int in all SDK versions, - // but let's check the options struct. - // Based on previous inspection: SearchAll takes UserSearchOptions. - - var users []*descope.UserResponse - var err error - - if text != "" { - options := &descope.UserSearchOptions{Text: text, Limit: 50} - users, _, err = h.DescopeClient.Management.User().SearchAll(context.Background(), options) - } else { - // Nil options means default search (usually returns all or default page) - users, _, err = h.DescopeClient.Management.User().SearchAll(context.Background(), nil) - } - - if err != nil { - slog.Error("[Admin] ListUsers failed", "error", err) - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) - } - - return c.JSON(fiber.Map{"users": users}) -} - -// DeleteUser - DELETE /api/v1/admin/users/:loginId -func (h *AdminHandler) DeleteUser(c *fiber.Ctx) error { - if err := h.checkAuth(c); err != nil { - return err - } - - loginID := c.Params("loginId") - // Decode if necessary (Fiber usually decodes params, but let's be safe if it's double encoded) - if decoded, err := url.QueryUnescape(loginID); err == nil { - loginID = decoded - } - - slog.Info("[Admin] Deleting user", "loginID", loginID) - if err := h.DescopeClient.Management.User().Delete(context.Background(), loginID); err != nil { - slog.Error("[Admin] DeleteUser failed", "error", err) - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) - } - - return c.JSON(fiber.Map{"message": "User deleted successfully"}) -} - -// UpdateUserStatus - PATCH /api/v1/admin/users/:loginId/status -func (h *AdminHandler) UpdateUserStatus(c *fiber.Ctx) error { - if err := h.checkAuth(c); err != nil { - return err - } - - loginID := c.Params("loginId") - if decoded, err := url.QueryUnescape(loginID); err == nil { - loginID = decoded - } - - var req struct { - Status string `json:"status"` // "enabled" or "disabled" - } - if err := c.BodyParser(&req); err != nil { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid body"}) - } - - var user *descope.UserResponse - var err error - - slog.Info("[Admin] Updating status", "loginID", loginID, "status", req.Status) - - if req.Status == "enabled" || req.Status == "active" { - user, err = h.DescopeClient.Management.User().Activate(context.Background(), loginID) - } else { - user, err = h.DescopeClient.Management.User().Deactivate(context.Background(), loginID) - } - - if err != nil { - slog.Error("[Admin] Status update failed", "error", err) - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) - } - - return c.JSON(fiber.Map{ - "message": "Status updated", - "user": user, - }) -} - -// UpdateUser - PATCH /api/v1/admin/users/:loginId -func (h *AdminHandler) UpdateUser(c *fiber.Ctx) error { - if err := h.checkAuth(c); err != nil { - return err - } - - loginID := c.Params("loginId") - if decoded, err := url.QueryUnescape(loginID); err == nil { - loginID = decoded - } - - var req struct { - Email *string `json:"email"` - Phone *string `json:"phone"` - DisplayName *string `json:"displayName"` - } - if err := c.BodyParser(&req); err != nil { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid body"}) - } - - ctx := context.Background() - var err error - - // Update Display Name - if req.DisplayName != nil { - _, err = h.DescopeClient.Management.User().UpdateDisplayName(ctx, loginID, *req.DisplayName) - if err != nil { - return c.Status(500).JSON(fiber.Map{"error": "Failed to update name: " + err.Error()}) - } - } - - // Update Email - if req.Email != nil { - _, err = h.DescopeClient.Management.User().UpdateEmail(ctx, loginID, *req.Email, true, false) // verified=true, addToLoginIDs=false - if err != nil { - return c.Status(500).JSON(fiber.Map{"error": "Failed to update email: " + err.Error()}) - } - } - - // Update Phone - if req.Phone != nil { - phone := *req.Phone - // Normalize - if strings.HasPrefix(phone, "010") { - phone = "+82" + phone[1:] - } - _, err = h.DescopeClient.Management.User().UpdatePhone(ctx, loginID, phone, true, false) // verified=true, addToLoginIDs=false - if err != nil { - return c.Status(500).JSON(fiber.Map{"error": "Failed to update phone: " + err.Error()}) - } - } - - return c.JSON(fiber.Map{"message": "User updated successfully"}) -} - -func (h *AdminHandler) CreateUser(c *fiber.Ctx) error { - if err := h.checkAuth(c); err != nil { - return err - } - - if h.DescopeClient == nil { - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Descope Client not configured"}) - } - - var req CreateUserRequest - if err := c.BodyParser(&req); err != nil { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request body"}) - } - - if req.LoginID == "" { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "LoginID is required"}) - } - - // Normalize Phone - normalizedPhone := req.Phone - if normalizedPhone != "" { - if strings.HasPrefix(normalizedPhone, "010") { - normalizedPhone = "+82" + normalizedPhone[1:] - } else if strings.HasPrefix(normalizedPhone, "82") { - normalizedPhone = "+" + normalizedPhone - } - } - - userObj := &descope.UserRequest{ - User: descope.User{ - Email: req.Email, - Phone: normalizedPhone, - Name: req.DisplayName, - }, - VerifiedEmail: boolPtr(req.Email != ""), - VerifiedPhone: boolPtr(normalizedPhone != ""), - } - - // Add Roles if provided - if len(req.Roles) > 0 { - userObj.Roles = req.Roles - } - - // Add Tenants if provided - if len(req.Tenants) > 0 { - // Convert map[string][]string to []*descope.AssociatedTenant - userTenants := []*descope.AssociatedTenant{} - for tenantID, roles := range req.Tenants { - userTenants = append(userTenants, &descope.AssociatedTenant{ - TenantID: tenantID, - Roles: roles, - }) - } - userObj.Tenants = userTenants - } - - slog.Info("[Admin] Creating user", "loginID", req.LoginID, "email", req.Email, "phone", normalizedPhone) - - res, err := h.DescopeClient.Management.User().Create(context.Background(), req.LoginID, userObj) - if err != nil { - slog.Error("[Admin] Failed to create user", "error", err) - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) - } - - return c.JSON(fiber.Map{ - "message": "User created successfully", - "user": res, - }) -} +} \ No newline at end of file