from __future__ import annotations from string import Template GO_VERSIONS = ["1.21", "1.22", "1.23", "1.24"] _AUTH_SERVICE_TEMPLATE = Template("""\ go$go_version implementations // services/implementations/auth_service.go // Pattern: JWT HS256 token generation + validation service // Observed in: Medical-App-Core/services/implementations/auth_service.go package implementations import ( \t"fmt" \t"os" \t"time" \t"github.com/golang-jwt/jwt/v4" \t"golang.org/x/crypto/bcrypt" ) // Claims holds the JWT payload. type Claims struct { \tUserID string `json:"user_id"` \tEmail string `json:"email"` \tRole string `json:"role"` \tjwt.RegisteredClaims } // AuthTokenServiceImpl handles JWT creation and validation. type AuthTokenServiceImpl struct { \tsecret []byte \tttl time.Duration } // NewAuthTokenService reads JWT_SECRET from the environment and constructs the service. func NewAuthTokenService() *AuthTokenServiceImpl { \tsecret := os.Getenv("JWT_SECRET") \tif secret == "" { \t\tpanic("JWT_SECRET environment variable must be set") \t} \treturn &AuthTokenServiceImpl{ \t\tsecret: []byte(secret), \t\tttl: 24 * time.Hour, \t} } // GenerateToken creates a signed HS256 JWT for the given user attributes. func (s *AuthTokenServiceImpl) GenerateToken(userID, email, role string) (string, error) { \tclaims := &Claims{ \t\tUserID: userID, \t\tEmail: email, \t\tRole: role, \t\tRegisteredClaims: jwt.RegisteredClaims{ \t\t\tExpiresAt: jwt.NewNumericDate(time.Now().Add(s.ttl)), \t\t\tIssuedAt: jwt.NewNumericDate(time.Now()), \t\t\tIssuer: "medical-sas-api", \t\t}, \t} \ttoken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) \tsigned, err := token.SignedString(s.secret) \tif err != nil { \t\treturn "", fmt.Errorf("sign token: %w", err) \t} \treturn signed, nil } // ValidateToken parses and validates a JWT string. Returns nil on success. func (s *AuthTokenServiceImpl) ValidateToken(tokenString string) error { \ttoken, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(t *jwt.Token) (any, error) { \t\tif _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok { \t\t\treturn nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"]) \t\t} \t\treturn s.secret, nil \t}) \tif err != nil { \t\treturn fmt.Errorf("invalid token: %w", err) \t} \tif !token.Valid { \t\treturn fmt.Errorf("token is not valid") \t} \treturn nil } // ParseClaims extracts the Claims from a valid JWT string. func (s *AuthTokenServiceImpl) ParseClaims(tokenString string) (*Claims, error) { \tclaims := &Claims{} \t_, err := jwt.ParseWithClaims(tokenString, claims, func(t *jwt.Token) (any, error) { \t\treturn s.secret, nil \t}) \tif err != nil { \t\treturn nil, fmt.Errorf("parse claims: %w", err) \t} \treturn claims, nil } // HashPassword returns a bcrypt hash of the plain-text password. func HashPassword(plain string) (string, error) { \thashed, err := bcrypt.GenerateFromPassword([]byte(plain), bcrypt.DefaultCost) \tif err != nil { \t\treturn "", fmt.Errorf("hash password: %w", err) \t} \treturn string(hashed), nil } // CheckPassword returns nil if plain matches the bcrypt hash. func CheckPassword(plain, hash string) error { \tif err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(plain)); err != nil { \t\treturn fmt.Errorf("invalid credentials") \t} \treturn nil } """) _AUTH_MIDDLEWARE_TEMPLATE = Template("""\ go$go_version middleware // middleware/auth.go // Pattern: Fiber JWT bearer middleware with claims propagation via Locals // Observed pattern from: Medical-App-Core/cmd/main.go AuthMiddleware package middleware import ( \t"strings" \t"$module/services/implementations" \t"github.com/gofiber/fiber/v2" ) // BearerAuth validates the Authorization: Bearer header and stores parsed // claims in fiber.Ctx.Locals("claims") for downstream handlers. func BearerAuth(authSvc *implementations.AuthTokenServiceImpl) fiber.Handler { \treturn func(c *fiber.Ctx) error { \t\theader := c.Get("Authorization") \t\tif !strings.HasPrefix(header, "Bearer ") { \t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ \t\t\t\t"error": "missing or malformed Authorization header", \t\t\t}) \t\t} \t\ttokenStr := strings.TrimPrefix(header, "Bearer ") \t\tclaims, err := authSvc.ParseClaims(tokenStr) \t\tif err != nil { \t\t\treturn c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ \t\t\t\t"error": "invalid or expired token", \t\t\t\t"reason": err.Error(), \t\t\t}) \t\t} \t\t// Make claims available to all downstream handlers \t\tc.Locals("claims", claims) \t\tc.Locals("user_id", claims.UserID) \t\tc.Locals("role", claims.Role) \t\treturn c.Next() \t} } // RoleRequired returns a middleware that allows only the specified roles. // Must be chained after BearerAuth. func RoleRequired(roles ...string) fiber.Handler { \tallowed := make(map[string]struct{}, len(roles)) \tfor _, r := range roles { \t\tallowed[r] = struct{}{} \t} \treturn func(c *fiber.Ctx) error { \t\trole, _ := c.Locals("role").(string) \t\tif _, ok := allowed[role]; !ok { \t\t\treturn c.Status(fiber.StatusForbidden).JSON(fiber.Map{ \t\t\t\t"error": "insufficient permissions", \t\t\t}) \t\t} \t\treturn c.Next() \t} } """) _AUTH_CONTROLLER_TEMPLATE = Template("""\ go$go_version controllers // controllers/auth_controller.go // Pattern: login + token generation handler // Observed in: Medical-App-Core/controllers/auth_controller.go package controllers import ( \t"net/http" \t"$module/services/implementations" \t"github.com/gofiber/fiber/v2" ) // AuthController handles token generation and validation endpoints. type AuthController struct { \tauthSvc *implementations.AuthTokenServiceImpl } func NewAuthController(svc *implementations.AuthTokenServiceImpl) *AuthController { \treturn &AuthController{authSvc: svc} } type generateTokenRequest struct { \tUserID string `json:"user_id" validate:"required,uuid4"` \tEmail string `json:"email" validate:"required,email"` \tRole string `json:"role" validate:"required"` } // GenerateToken godoc // @Summary Issue a JWT token // @Description Generates a signed JWT for the given user credentials // @Tags Auth // @Accept json // @Produce json // @Param body body generateTokenRequest true "Token request" // @Success 200 {object} fiber.Map{token=string} // @Failure 400 {object} fiber.Map // @Failure 500 {object} fiber.Map // @Router /auth/token [post] func (ac *AuthController) GenerateToken(c *fiber.Ctx) error { \tvar req generateTokenRequest \tif err := c.BodyParser(&req); err != nil { \t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "invalid request payload"}) \t} \tif req.UserID == "" || req.Email == "" || req.Role == "" { \t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "user_id, email, and role are required"}) \t} \ttoken, err := ac.authSvc.GenerateToken(req.UserID, req.Email, req.Role) \tif err != nil { \t\treturn c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "failed to generate token"}) \t} \treturn c.Status(http.StatusOK).JSON(fiber.Map{"token": token}) } // ValidateToken godoc // @Summary Validate a JWT token // @Description Returns 200 if the token is valid, 401 otherwise // @Tags Auth // @Accept json // @Produce json // @Param body body fiber.Map{token=string} true "Token to validate" // @Success 200 {object} fiber.Map{valid=bool} // @Failure 401 {object} fiber.Map // @Router /auth/validate [post] func (ac *AuthController) ValidateToken(c *fiber.Ctx) error { \tvar body struct { \t\tToken string `json:"token"` \t} \tif err := c.BodyParser(&body); err != nil || body.Token == "" { \t\treturn c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "token is required"}) \t} \tif err := ac.authSvc.ValidateToken(body.Token); err != nil { \t\treturn c.Status(http.StatusUnauthorized).JSON(fiber.Map{ \t\t\t"valid": false, \t\t\t"reason": err.Error(), \t\t}) \t} \treturn c.Status(http.StatusOK).JSON(fiber.Map{"valid": true}) } """) _VALIDATOR_TEMPLATE = Template("""\ go$go_version initializers // initializers/validators.go // Pattern: custom validator registration with go-playground/validator // Observed in: Medical-App-Core/initializers/validators.go package initializers import ( \t"strconv" \t"strings" \t"github.com/go-playground/validator/v10" ) // RegisterCustomValidators adds domain-specific validation rules. func RegisterCustomValidators(v *validator.Validate) { \t_ = v.RegisterValidation("cpf", validateCPF) \t_ = v.RegisterValidation("cnpj", validateCNPJ) \t_ = v.RegisterValidation("crm", validateCRM) } // validateCPF validates a Brazilian CPF number (11 digits, checksum). func validateCPF(fl validator.FieldLevel) bool { \tcpf := strings.ReplaceAll(fl.Field().String(), ".", "") \tcpf = strings.ReplaceAll(cpf, "-", "") \tif len(cpf) != 11 || allEqual(cpf) { \t\treturn false \t} \treturn cpfChecksum(cpf) } func cpfChecksum(cpf string) bool { \tdigits := make([]int, 11) \tfor i, ch := range cpf { \t\tdigits[i], _ = strconv.Atoi(string(ch)) \t} \tfor pass := 0; pass < 2; pass++ { \t\tweight := 10 + pass \t\tsum := 0 \t\tfor i := 0; i < 9+pass; i++ { \t\t\tsum += digits[i] * (weight - i) \t\t} \t\trem := (sum * 10) % 11 \t\tif rem == 10 || rem == 11 { \t\t\trem = 0 \t\t} \t\tif rem != digits[9+pass] { \t\t\treturn false \t\t} \t} \treturn true } // validateCNPJ validates a Brazilian CNPJ number (14 digits, checksum). func validateCNPJ(fl validator.FieldLevel) bool { \tcnpj := strings.Map(func(r rune) rune { \t\tif r >= '0' && r <= '9' { return r } \t\treturn -1 \t}, fl.Field().String()) \tif len(cnpj) != 14 || allEqual(cnpj) { \t\treturn false \t} \treturn cnpjChecksum(cnpj) } func cnpjChecksum(cnpj string) bool { \tweights1 := []int{5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2} \tweights2 := []int{6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2} \tfor pass, weights := range [][]int{weights1, weights2} { \t\tsum := 0 \t\tfor i, w := range weights { \t\t\td, _ := strconv.Atoi(string(cnpj[i])) \t\t\tsum += d * w \t\t} \t\trem := sum % 11 \t\texpected := byte('0') \t\tif rem >= 2 { \t\t\texpected = byte('0' + (11 - rem)) \t\t} \t\tif cnpj[12+pass] != expected { \t\t\treturn false \t\t} \t} \treturn true } // validateCRM validates a Brazilian CRM number (digits optionally followed by UF code). func validateCRM(fl validator.FieldLevel) bool { \tcrm := fl.Field().String() \treturn len(crm) >= 4 && len(crm) <= 10 } func allEqual(s string) bool { \tif s == "" { return false } \tfor _, c := range s[1:] { \t\tif byte(c) != s[0] { return false } \t} \treturn true } """) class AuthPatternGenerator: """Generate JWT auth and validation training examples.""" MODULE = "medical-sas-api" def all_examples(self) -> list[str]: examples: list[str] = [] for ver in GO_VERSIONS: examples.append(_AUTH_SERVICE_TEMPLATE.substitute(go_version=ver)) examples.append(_AUTH_MIDDLEWARE_TEMPLATE.substitute(go_version=ver, module=self.MODULE)) examples.append(_AUTH_CONTROLLER_TEMPLATE.substitute(go_version=ver, module=self.MODULE)) examples.append(_VALIDATOR_TEMPLATE.substitute(go_version=ver)) return examples