141 lines
3.2 KiB
Go
141 lines
3.2 KiB
Go
package handlers
|
|
|
|
import (
|
|
"database/sql"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"admintemplate/internal/auth"
|
|
"admintemplate/internal/database"
|
|
"admintemplate/internal/models"
|
|
"admintemplate/pkg/config"
|
|
)
|
|
|
|
type AuthHandler struct {
|
|
db *database.DB
|
|
config *config.Config
|
|
}
|
|
|
|
func NewAuthHandler(db *database.DB, cfg *config.Config) *AuthHandler {
|
|
return &AuthHandler{
|
|
db: db,
|
|
config: cfg,
|
|
}
|
|
}
|
|
|
|
func (h *AuthHandler) Login(c *gin.Context) {
|
|
var req models.LoginRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
|
|
return
|
|
}
|
|
|
|
// Get user from database
|
|
var user models.User
|
|
query := "SELECT id, username, password, email, role, active, created_at, updated_at FROM users WHERE username = ?"
|
|
err := h.db.QueryRow(query, req.Username).Scan(
|
|
&user.ID, &user.Username, &user.Password, &user.Email,
|
|
&user.Role, &user.Active, &user.CreatedAt, &user.UpdatedAt,
|
|
)
|
|
|
|
if err == sql.ErrNoRows {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid credentials"})
|
|
return
|
|
}
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error"})
|
|
return
|
|
}
|
|
|
|
// Check if user is active
|
|
if !user.Active {
|
|
c.JSON(http.StatusForbidden, gin.H{"error": "User account is disabled"})
|
|
return
|
|
}
|
|
|
|
// Verify password
|
|
if !auth.CheckPassword(req.Password, user.Password) {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid credentials"})
|
|
return
|
|
}
|
|
|
|
// Generate JWT token
|
|
token, err := auth.GenerateToken(
|
|
user.ID,
|
|
user.Username,
|
|
user.Role,
|
|
h.config.Auth.JWTSecret,
|
|
h.config.Auth.TokenDuration,
|
|
)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, models.LoginResponse{
|
|
Token: token,
|
|
User: user,
|
|
})
|
|
}
|
|
|
|
func (h *AuthHandler) GetCurrentUser(c *gin.Context) {
|
|
userID, _ := c.Get("user_id")
|
|
|
|
var user models.User
|
|
query := "SELECT id, username, email, role, active, created_at, updated_at FROM users WHERE id = ?"
|
|
err := h.db.QueryRow(query, userID).Scan(
|
|
&user.ID, &user.Username, &user.Email,
|
|
&user.Role, &user.Active, &user.CreatedAt, &user.UpdatedAt,
|
|
)
|
|
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch user"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, user)
|
|
}
|
|
|
|
func (h *AuthHandler) InitDefaultUsers() error {
|
|
// Check if users already exist
|
|
var count int
|
|
err := h.db.QueryRow("SELECT COUNT(*) FROM users").Scan(&count)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if count > 0 {
|
|
return nil // Users already exist
|
|
}
|
|
|
|
// Create default users: admin and mf
|
|
defaultUsers := []struct {
|
|
username string
|
|
password string
|
|
email string
|
|
role string
|
|
}{
|
|
{"admin", "admin123", "admin@admintemplate.local", "admin"},
|
|
{"mf", "mf123", "mf@admintemplate.local", "user"},
|
|
}
|
|
|
|
for _, u := range defaultUsers {
|
|
hashedPassword, err := auth.HashPassword(u.password)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
query := `INSERT INTO users (username, password, email, role, active, created_at, updated_at)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?)`
|
|
now := time.Now()
|
|
_, err = h.db.Exec(query, u.username, hashedPassword, u.email, u.role, true, now, now)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|