Update template go
This commit is contained in:
132
internal/handlers/auth.go
Normal file
132
internal/handlers/auth.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"api-service/internal/models"
|
||||
"api-service/internal/services"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// AuthHandler handles authentication endpoints
|
||||
type AuthHandler struct {
|
||||
authService *services.AuthService
|
||||
}
|
||||
|
||||
// NewAuthHandler creates a new authentication handler
|
||||
func NewAuthHandler(authService *services.AuthService) *AuthHandler {
|
||||
return &AuthHandler{
|
||||
authService: authService,
|
||||
}
|
||||
}
|
||||
|
||||
// Login godoc
|
||||
// @Summary Login user and get JWT token
|
||||
// @Description Authenticate user with username and password to receive JWT token
|
||||
// @Tags Authentication
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param login body models.LoginRequest true "Login credentials"
|
||||
// @Success 200 {object} models.TokenResponse
|
||||
// @Failure 400 {object} map[string]string "Bad request"
|
||||
// @Failure 401 {object} map[string]string "Unauthorized"
|
||||
// @Router /api/v1/auth/login [post]
|
||||
func (h *AuthHandler) Login(c *gin.Context) {
|
||||
var loginReq models.LoginRequest
|
||||
|
||||
// Bind JSON request
|
||||
if err := c.ShouldBindJSON(&loginReq); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Authenticate user
|
||||
tokenResponse, err := h.authService.Login(loginReq.Username, loginReq.Password)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, tokenResponse)
|
||||
}
|
||||
|
||||
// RefreshToken godoc
|
||||
// @Summary Refresh JWT token
|
||||
// @Description Refresh the JWT token using a valid refresh token
|
||||
// @Tags Authentication
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param refresh body map[string]string true "Refresh token"
|
||||
// @Success 200 {object} models.TokenResponse
|
||||
// @Failure 400 {object} map[string]string "Bad request"
|
||||
// @Failure 401 {object} map[string]string "Unauthorized"
|
||||
// @Router /api/v1/auth/refresh [post]
|
||||
func (h *AuthHandler) RefreshToken(c *gin.Context) {
|
||||
// For now, this is a placeholder for refresh token functionality
|
||||
// In a real implementation, you would handle refresh tokens here
|
||||
c.JSON(http.StatusNotImplemented, gin.H{"error": "refresh token not implemented"})
|
||||
}
|
||||
|
||||
// Register godoc
|
||||
// @Summary Register new user
|
||||
// @Description Register a new user account
|
||||
// @Tags Authentication
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param register body map[string]string true "Registration data"
|
||||
// @Success 201 {object} map[string]string
|
||||
// @Failure 400 {object} map[string]string "Bad request"
|
||||
// @Router /api/v1/auth/register [post]
|
||||
func (h *AuthHandler) Register(c *gin.Context) {
|
||||
var registerReq struct {
|
||||
Username string `json:"username" binding:"required"`
|
||||
Email string `json:"email" binding:"required,email"`
|
||||
Password string `json:"password" binding:"required,min=6"`
|
||||
Role string `json:"role" binding:"required"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(®isterReq); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
err := h.authService.RegisterUser(
|
||||
registerReq.Username,
|
||||
registerReq.Email,
|
||||
registerReq.Password,
|
||||
registerReq.Role,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, gin.H{"message": "user registered successfully"})
|
||||
}
|
||||
|
||||
// Me godoc
|
||||
// @Summary Get current user info
|
||||
// @Description Get information about the currently authenticated user
|
||||
// @Tags Authentication
|
||||
// @Produce json
|
||||
// @Security Bearer
|
||||
// @Success 200 {object} models.User
|
||||
// @Failure 401 {object} map[string]string "Unauthorized"
|
||||
// @Router /api/v1/auth/me [get]
|
||||
func (h *AuthHandler) Me(c *gin.Context) {
|
||||
// Get user info from context (set by middleware)
|
||||
userID, exists := c.Get("user_id")
|
||||
if !exists {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "user not authenticated"})
|
||||
return
|
||||
}
|
||||
|
||||
// In a real implementation, you would fetch user details from database
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"id": userID,
|
||||
"username": c.GetString("username"),
|
||||
"email": c.GetString("email"),
|
||||
"role": c.GetString("role"),
|
||||
})
|
||||
}
|
||||
124
internal/handlers/product.go
Normal file
124
internal/handlers/product.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"api-service/internal/models"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// ProductHandler handles product services
|
||||
type ProductHandler struct{}
|
||||
|
||||
// NewProductHandler creates a new ProductHandler
|
||||
func NewProductHandler() *ProductHandler {
|
||||
return &ProductHandler{}
|
||||
}
|
||||
|
||||
// GetProduct godoc
|
||||
// @Summary Get product
|
||||
// @Description Returns a list of products
|
||||
// @Tags product
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} models.ProductGetResponse "Product GET response"
|
||||
// @Router /api/v1/products [get]
|
||||
func (h *ProductHandler) GetProduct(c *gin.Context) {
|
||||
response := models.ProductGetResponse{
|
||||
Message: "List of products",
|
||||
Data: []string{"Product 1", "Product 2"},
|
||||
}
|
||||
c.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
// GetProductByID godoc
|
||||
// @Summary Get product by ID
|
||||
// @Description Returns a single product by ID
|
||||
// @Tags product
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Product ID"
|
||||
// @Success 200 {object} models.ProductGetByIDResponse "Product GET by ID response"
|
||||
// @Failure 404 {object} models.ErrorResponse "Product not found"
|
||||
// @Router /api/v1/products/{id} [get]
|
||||
func (h *ProductHandler) GetProductByID(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
response := models.ProductGetByIDResponse{
|
||||
ID: id,
|
||||
Message: "Product details",
|
||||
}
|
||||
c.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
// CreateProduct godoc
|
||||
// @Summary Create product
|
||||
// @Description Creates a new product
|
||||
// @Tags product
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body models.ProductCreateRequest true "Product creation request"
|
||||
// @Success 201 {object} models.ProductCreateResponse "Product created successfully"
|
||||
// @Failure 400 {object} models.ErrorResponse "Bad request"
|
||||
// @Router /api/v1/products [post]
|
||||
func (h *ProductHandler) CreateProduct(c *gin.Context) {
|
||||
var req models.ProductCreateRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
response := models.ProductCreateResponse{
|
||||
ID: uuid.NewString(),
|
||||
Message: "Product created successfully",
|
||||
Data: req,
|
||||
}
|
||||
c.JSON(http.StatusCreated, response)
|
||||
}
|
||||
|
||||
// UpdateProduct godoc
|
||||
// @Summary Update product
|
||||
// @Description Updates an existing product
|
||||
// @Tags product
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Product ID"
|
||||
// @Param request body models.ProductUpdateRequest true "Product update request"
|
||||
// @Success 200 {object} models.ProductUpdateResponse "Product updated successfully"
|
||||
// @Failure 400 {object} models.ErrorResponse "Bad request"
|
||||
// @Failure 404 {object} models.ErrorResponse "Product not found"
|
||||
// @Router /api/v1/products/{id} [put]
|
||||
func (h *ProductHandler) UpdateProduct(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
var req models.ProductUpdateRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
response := models.ProductUpdateResponse{
|
||||
ID: id,
|
||||
Message: "Product updated successfully",
|
||||
Data: req,
|
||||
}
|
||||
c.JSON(http.StatusOK, response)
|
||||
}
|
||||
|
||||
// DeleteProduct godoc
|
||||
// @Summary Delete product
|
||||
// @Description Deletes a product by ID
|
||||
// @Tags product
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "Product ID"
|
||||
// @Success 200 {object} models.ProductDeleteResponse "Product deleted successfully"
|
||||
// @Failure 404 {object} models.ErrorResponse "Product not found"
|
||||
// @Router /api/v1/products/{id} [delete]
|
||||
func (h *ProductHandler) DeleteProduct(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
response := models.ProductDeleteResponse{
|
||||
ID: id,
|
||||
Message: "Product deleted successfully",
|
||||
}
|
||||
c.JSON(http.StatusOK, response)
|
||||
}
|
||||
95
internal/handlers/token_handler.go
Normal file
95
internal/handlers/token_handler.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"api-service/internal/models"
|
||||
"api-service/internal/services"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// TokenHandler handles token generation endpoints
|
||||
type TokenHandler struct {
|
||||
authService *services.AuthService
|
||||
}
|
||||
|
||||
// NewTokenHandler creates a new token handler
|
||||
func NewTokenHandler(authService *services.AuthService) *TokenHandler {
|
||||
return &TokenHandler{
|
||||
authService: authService,
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateToken godoc
|
||||
// @Summary Generate JWT token
|
||||
// @Description Generate a JWT token for a user
|
||||
// @Tags Token
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param token body models.LoginRequest true "User credentials"
|
||||
// @Success 200 {object} models.TokenResponse
|
||||
// @Failure 400 {object} map[string]string "Bad request"
|
||||
// @Failure 401 {object} map[string]string "Unauthorized"
|
||||
// @Router /api/v1/token/generate [post]
|
||||
func (h *TokenHandler) GenerateToken(c *gin.Context) {
|
||||
var loginReq models.LoginRequest
|
||||
|
||||
// Bind JSON request
|
||||
if err := c.ShouldBindJSON(&loginReq); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Generate token
|
||||
tokenResponse, err := h.authService.Login(loginReq.Username, loginReq.Password)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, tokenResponse)
|
||||
}
|
||||
|
||||
// GenerateTokenDirect godoc
|
||||
// @Summary Generate token directly
|
||||
// @Description Generate a JWT token directly without password verification (for testing)
|
||||
// @Tags Token
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param user body map[string]string true "User info"
|
||||
// @Success 200 {object} models.TokenResponse
|
||||
// @Failure 400 {object} map[string]string "Bad request"
|
||||
// @Router /api/v1/token/generate-direct [post]
|
||||
func (h *TokenHandler) GenerateTokenDirect(c *gin.Context) {
|
||||
var req struct {
|
||||
Username string `json:"username" binding:"required"`
|
||||
Email string `json:"email" binding:"required"`
|
||||
Role string `json:"role" binding:"required"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Create a temporary user for token generation
|
||||
user := &models.User{
|
||||
ID: "temp-" + req.Username,
|
||||
Username: req.Username,
|
||||
Email: req.Email,
|
||||
Role: req.Role,
|
||||
}
|
||||
|
||||
// Generate token directly
|
||||
token, err := h.authService.GenerateTokenForUser(user)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, models.TokenResponse{
|
||||
AccessToken: token,
|
||||
TokenType: "Bearer",
|
||||
ExpiresIn: 3600,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user