142 lines
3.8 KiB
Go
142 lines
3.8 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/kms/api-key-service/internal/domain"
|
|
"github.com/kms/api-key-service/internal/services"
|
|
)
|
|
|
|
// AuthHandler handles authentication-related HTTP requests
|
|
type AuthHandler struct {
|
|
authService services.AuthenticationService
|
|
tokenService services.TokenService
|
|
logger *zap.Logger
|
|
}
|
|
|
|
// NewAuthHandler creates a new auth handler
|
|
func NewAuthHandler(
|
|
authService services.AuthenticationService,
|
|
tokenService services.TokenService,
|
|
logger *zap.Logger,
|
|
) *AuthHandler {
|
|
return &AuthHandler{
|
|
authService: authService,
|
|
tokenService: tokenService,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
// Login handles POST /login
|
|
func (h *AuthHandler) Login(c *gin.Context) {
|
|
var req domain.LoginRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
h.logger.Warn("Invalid login request", zap.Error(err))
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"error": "Bad Request",
|
|
"message": "Invalid request body: " + err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
// For now, we'll extract user ID from headers since we're using HeaderAuthenticationProvider
|
|
userID := c.GetHeader("X-User-Email")
|
|
if userID == "" {
|
|
h.logger.Warn("User email not found in headers")
|
|
c.JSON(http.StatusUnauthorized, gin.H{
|
|
"error": "Unauthorized",
|
|
"message": "User authentication required",
|
|
})
|
|
return
|
|
}
|
|
|
|
h.logger.Info("Processing login request", zap.String("user_id", userID), zap.String("app_id", req.AppID))
|
|
|
|
// Generate user token
|
|
token, err := h.tokenService.GenerateUserToken(c.Request.Context(), req.AppID, userID, req.Permissions)
|
|
if err != nil {
|
|
h.logger.Error("Failed to generate user token", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"error": "Internal Server Error",
|
|
"message": "Failed to generate token",
|
|
})
|
|
return
|
|
}
|
|
|
|
// For now, we'll just return the token directly
|
|
// In a real implementation, this would redirect to the callback URL
|
|
response := domain.LoginResponse{
|
|
RedirectURL: req.RedirectURI + "?token=" + token,
|
|
}
|
|
|
|
if req.RedirectURI == "" {
|
|
// If no redirect URI, return token directly
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"token": token,
|
|
"user_id": userID,
|
|
"app_id": req.AppID,
|
|
"expires_in": 604800, // 7 days in seconds
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, response)
|
|
}
|
|
|
|
// Verify handles POST /verify
|
|
func (h *AuthHandler) Verify(c *gin.Context) {
|
|
var req domain.VerifyRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
h.logger.Warn("Invalid verify request", zap.Error(err))
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"error": "Bad Request",
|
|
"message": "Invalid request body: " + err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
h.logger.Debug("Verifying token", zap.String("app_id", req.AppID), zap.String("type", string(req.Type)))
|
|
|
|
response, err := h.tokenService.VerifyToken(c.Request.Context(), &req)
|
|
if err != nil {
|
|
h.logger.Error("Failed to verify token", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"error": "Internal Server Error",
|
|
"message": "Failed to verify token",
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, response)
|
|
}
|
|
|
|
// Renew handles POST /renew
|
|
func (h *AuthHandler) Renew(c *gin.Context) {
|
|
var req domain.RenewRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
h.logger.Warn("Invalid renew request", zap.Error(err))
|
|
c.JSON(http.StatusBadRequest, gin.H{
|
|
"error": "Bad Request",
|
|
"message": "Invalid request body: " + err.Error(),
|
|
})
|
|
return
|
|
}
|
|
|
|
h.logger.Info("Renewing token", zap.String("app_id", req.AppID), zap.String("user_id", req.UserID))
|
|
|
|
response, err := h.tokenService.RenewUserToken(c.Request.Context(), &req)
|
|
if err != nil {
|
|
h.logger.Error("Failed to renew token", zap.Error(err))
|
|
c.JSON(http.StatusInternalServerError, gin.H{
|
|
"error": "Internal Server Error",
|
|
"message": "Failed to renew token",
|
|
})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, response)
|
|
}
|