140 lines
4.5 KiB
Go
140 lines
4.5 KiB
Go
package controller
|
|
|
|
import (
|
|
"net/http"
|
|
"time"
|
|
"users_management/m/model/entity"
|
|
"users_management/m/usecase"
|
|
"users_management/m/utils"
|
|
"users_management/m/utils/common"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type BypassController struct {
|
|
userUC usecase.UsersUsecase
|
|
rg *gin.RouterGroup
|
|
}
|
|
|
|
func NewBypassController(userUC usecase.UsersUsecase, rg *gin.RouterGroup) *BypassController {
|
|
return &BypassController{
|
|
userUC: userUC,
|
|
rg: rg,
|
|
}
|
|
}
|
|
|
|
func (c *BypassController) Route() {
|
|
bypass := c.rg.Group("/bypass")
|
|
{
|
|
// Dangerous endpoint - should be secured or removed in production
|
|
bypass.POST("/create-super-admin", c.createSuperAdmin)
|
|
bypass.GET("/roles", c.getRoles) // Helper to get role IDs
|
|
}
|
|
}
|
|
|
|
type CreateSuperAdminRequest struct {
|
|
Name string `json:"name" binding:"required"`
|
|
Username string `json:"username" binding:"required"`
|
|
Password string `json:"password" binding:"required,min=6"`
|
|
NomorInduk string `json:"nomor_induk" binding:"required"`
|
|
SecretKey string `json:"secret_key" binding:"required"` // Extra security
|
|
}
|
|
|
|
func (c *BypassController) createSuperAdmin(ctx *gin.Context) {
|
|
var req CreateSuperAdminRequest
|
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
|
common.ErrorResponses(ctx, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
// Simple secret key check (change this in production)
|
|
if req.SecretKey != "create-super-admin-secret-2024" {
|
|
common.ErrorResponses(ctx, http.StatusForbidden, "Invalid secret key")
|
|
return
|
|
}
|
|
|
|
// Check if username already exists
|
|
existingUser, err := c.userUC.GetUserByUsernameWithStatus(req.Username)
|
|
if err == nil && existingUser.ID != uuid.Nil {
|
|
common.ErrorResponses(ctx, http.StatusBadRequest, "Username already exists")
|
|
return
|
|
}
|
|
|
|
// Check if nomor_induk already exists
|
|
if req.NomorInduk != "" {
|
|
existingUser, err := c.userUC.GetUserByNomorInduk(req.NomorInduk)
|
|
if err == nil && existingUser.ID != uuid.Nil {
|
|
common.ErrorResponses(ctx, http.StatusBadRequest, "Nomor induk already exists")
|
|
return
|
|
}
|
|
}
|
|
|
|
// Get or create Super Admin role
|
|
superAdminRoleID, err := c.userUC.GetRoleByDepartment("Super Admin")
|
|
if err != nil {
|
|
// If Super Admin role doesn't exist, try Admin
|
|
superAdminRoleID, err = c.userUC.GetRoleByDepartment("Admin")
|
|
if err != nil {
|
|
common.ErrorResponses(ctx, http.StatusInternalServerError, "No admin role found in system")
|
|
return
|
|
}
|
|
}
|
|
|
|
// Hash password
|
|
hashedPassword, err := utils.HashPassword(req.Password)
|
|
if err != nil {
|
|
common.ErrorResponses(ctx, http.StatusInternalServerError, "Failed to hash password")
|
|
return
|
|
}
|
|
|
|
// Create super admin user directly (bypass normal registration flow)
|
|
user := entity.User{
|
|
ID: uuid.New(),
|
|
Name: req.Name,
|
|
Username: req.Username,
|
|
Password: hashedPassword,
|
|
NomorInduk: &req.NomorInduk,
|
|
RoleID: superAdminRoleID,
|
|
Status: entity.UserStatusApproved, // Directly approved
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
err = c.userUC.CreateSuperAdminBypass(user)
|
|
if err != nil {
|
|
common.ErrorResponses(ctx, http.StatusInternalServerError, "Failed to create super admin: "+err.Error())
|
|
return
|
|
}
|
|
|
|
response := gin.H{
|
|
"message": "Super admin created successfully",
|
|
"user": gin.H{
|
|
"id": user.ID,
|
|
"name": user.Name,
|
|
"username": user.Username,
|
|
"nomor_induk": user.NomorInduk,
|
|
"status": string(user.Status),
|
|
},
|
|
"warning": "This bypass endpoint should be disabled in production",
|
|
}
|
|
|
|
common.SingleResponses(ctx, "Super admin created", response)
|
|
}
|
|
|
|
func (c *BypassController) getRoles(ctx *gin.Context) {
|
|
// Helper endpoint to see available roles
|
|
roles := []gin.H{
|
|
{"name": "Super Admin", "description": "Full system access"},
|
|
{"name": "Admin", "description": "Administrative access"},
|
|
{"name": "Teknisi", "description": "Technical user access"},
|
|
{"name": "Manager", "description": "Management access"},
|
|
}
|
|
|
|
response := gin.H{
|
|
"roles": roles,
|
|
"note": "Use the role name to get role ID via GetRoleByDepartment",
|
|
}
|
|
|
|
common.SingleResponses(ctx, "Available roles", response)
|
|
} |