miniITCS/backend/internal/handlers/auth_handler.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
}