v0
This commit is contained in:
172
internal/handlers/token.go
Normal file
172
internal/handlers/token.go
Normal file
@ -0,0 +1,172 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/kms/api-key-service/internal/domain"
|
||||
"github.com/kms/api-key-service/internal/services"
|
||||
)
|
||||
|
||||
// TokenHandler handles token-related HTTP requests
|
||||
type TokenHandler struct {
|
||||
tokenService services.TokenService
|
||||
authService services.AuthenticationService
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// NewTokenHandler creates a new token handler
|
||||
func NewTokenHandler(
|
||||
tokenService services.TokenService,
|
||||
authService services.AuthenticationService,
|
||||
logger *zap.Logger,
|
||||
) *TokenHandler {
|
||||
return &TokenHandler{
|
||||
tokenService: tokenService,
|
||||
authService: authService,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// Create handles POST /applications/:id/tokens
|
||||
func (h *TokenHandler) Create(c *gin.Context) {
|
||||
appID := c.Param("id")
|
||||
if appID == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": "Bad Request",
|
||||
"message": "Application ID is required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var req domain.CreateStaticTokenRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
h.logger.Warn("Invalid request body", zap.Error(err))
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": "Bad Request",
|
||||
"message": "Invalid request body: " + err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Set app ID from URL parameter
|
||||
req.AppID = appID
|
||||
|
||||
// Get user ID from context
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
h.logger.Error("User ID not found in context")
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "Internal Server Error",
|
||||
"message": "Authentication context not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
token, err := h.tokenService.CreateStaticToken(c.Request.Context(), &req, userID.(string))
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to create token", zap.Error(err))
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "Internal Server Error",
|
||||
"message": "Failed to create token",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
h.logger.Info("Token created", zap.String("token_id", token.ID.String()))
|
||||
c.JSON(http.StatusCreated, token)
|
||||
}
|
||||
|
||||
// ListByApp handles GET /applications/:id/tokens
|
||||
func (h *TokenHandler) ListByApp(c *gin.Context) {
|
||||
appID := c.Param("id")
|
||||
if appID == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": "Bad Request",
|
||||
"message": "Application ID is required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Parse pagination parameters
|
||||
limit := 50
|
||||
offset := 0
|
||||
|
||||
if l := c.Query("limit"); l != "" {
|
||||
if parsed, err := strconv.Atoi(l); err == nil && parsed > 0 {
|
||||
limit = parsed
|
||||
}
|
||||
}
|
||||
|
||||
if o := c.Query("offset"); o != "" {
|
||||
if parsed, err := strconv.Atoi(o); err == nil && parsed >= 0 {
|
||||
offset = parsed
|
||||
}
|
||||
}
|
||||
|
||||
tokens, err := h.tokenService.ListByApp(c.Request.Context(), appID, limit, offset)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to list tokens", zap.Error(err), zap.String("app_id", appID))
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "Internal Server Error",
|
||||
"message": "Failed to list tokens",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"data": tokens,
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
"count": len(tokens),
|
||||
})
|
||||
}
|
||||
|
||||
// Delete handles DELETE /tokens/:id
|
||||
func (h *TokenHandler) Delete(c *gin.Context) {
|
||||
tokenIDStr := c.Param("id")
|
||||
if tokenIDStr == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": "Bad Request",
|
||||
"message": "Token ID is required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
tokenID, err := uuid.Parse(tokenIDStr)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": "Bad Request",
|
||||
"message": "Invalid token ID format",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Get user ID from context
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
h.logger.Error("User ID not found in context")
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "Internal Server Error",
|
||||
"message": "Authentication context not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
err = h.tokenService.Delete(c.Request.Context(), tokenID, userID.(string))
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to delete token", zap.Error(err), zap.String("token_id", tokenID.String()))
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "Internal Server Error",
|
||||
"message": "Failed to delete token",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
h.logger.Info("Token deleted", zap.String("token_id", tokenID.String()))
|
||||
c.JSON(http.StatusNoContent, nil)
|
||||
}
|
||||
Reference in New Issue
Block a user