feat: initial auth service support

This commit is contained in:
nihonium 2025-11-15 02:53:25 +03:00
parent d0c3547ef6
commit 2929a6e4bc
Signed by: nihonium
GPG key ID: 0251623741027CFC
10 changed files with 937 additions and 0 deletions

329
auth/auth.gen.go Normal file
View file

@ -0,0 +1,329 @@
// Package auth provides primitives to interact with the openapi HTTP API.
//
// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.5.0 DO NOT EDIT.
package auth
import (
"context"
"encoding/json"
"fmt"
"net/http"
"github.com/gin-gonic/gin"
strictgin "github.com/oapi-codegen/runtime/strictmiddleware/gin"
)
// PostAuthSignInJSONBody defines parameters for PostAuthSignIn.
type PostAuthSignInJSONBody struct {
Nickname string `json:"nickname"`
Pass string `json:"pass"`
}
// PostAuthSignUpJSONBody defines parameters for PostAuthSignUp.
type PostAuthSignUpJSONBody struct {
Nickname string `json:"nickname"`
Pass string `json:"pass"`
}
// PostAuthVerifyTokenJSONBody defines parameters for PostAuthVerifyToken.
type PostAuthVerifyTokenJSONBody struct {
// Token JWT token to validate
Token string `json:"token"`
}
// PostAuthSignInJSONRequestBody defines body for PostAuthSignIn for application/json ContentType.
type PostAuthSignInJSONRequestBody PostAuthSignInJSONBody
// PostAuthSignUpJSONRequestBody defines body for PostAuthSignUp for application/json ContentType.
type PostAuthSignUpJSONRequestBody PostAuthSignUpJSONBody
// PostAuthVerifyTokenJSONRequestBody defines body for PostAuthVerifyToken for application/json ContentType.
type PostAuthVerifyTokenJSONRequestBody PostAuthVerifyTokenJSONBody
// ServerInterface represents all server handlers.
type ServerInterface interface {
// Sign in a user and return JWT
// (POST /auth/sign-in)
PostAuthSignIn(c *gin.Context)
// Sign up a new user
// (POST /auth/sign-up)
PostAuthSignUp(c *gin.Context)
// Verify JWT validity
// (POST /auth/verify-token)
PostAuthVerifyToken(c *gin.Context)
}
// ServerInterfaceWrapper converts contexts to parameters.
type ServerInterfaceWrapper struct {
Handler ServerInterface
HandlerMiddlewares []MiddlewareFunc
ErrorHandler func(*gin.Context, error, int)
}
type MiddlewareFunc func(c *gin.Context)
// PostAuthSignIn operation middleware
func (siw *ServerInterfaceWrapper) PostAuthSignIn(c *gin.Context) {
for _, middleware := range siw.HandlerMiddlewares {
middleware(c)
if c.IsAborted() {
return
}
}
siw.Handler.PostAuthSignIn(c)
}
// PostAuthSignUp operation middleware
func (siw *ServerInterfaceWrapper) PostAuthSignUp(c *gin.Context) {
for _, middleware := range siw.HandlerMiddlewares {
middleware(c)
if c.IsAborted() {
return
}
}
siw.Handler.PostAuthSignUp(c)
}
// PostAuthVerifyToken operation middleware
func (siw *ServerInterfaceWrapper) PostAuthVerifyToken(c *gin.Context) {
for _, middleware := range siw.HandlerMiddlewares {
middleware(c)
if c.IsAborted() {
return
}
}
siw.Handler.PostAuthVerifyToken(c)
}
// GinServerOptions provides options for the Gin server.
type GinServerOptions struct {
BaseURL string
Middlewares []MiddlewareFunc
ErrorHandler func(*gin.Context, error, int)
}
// RegisterHandlers creates http.Handler with routing matching OpenAPI spec.
func RegisterHandlers(router gin.IRouter, si ServerInterface) {
RegisterHandlersWithOptions(router, si, GinServerOptions{})
}
// RegisterHandlersWithOptions creates http.Handler with additional options
func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options GinServerOptions) {
errorHandler := options.ErrorHandler
if errorHandler == nil {
errorHandler = func(c *gin.Context, err error, statusCode int) {
c.JSON(statusCode, gin.H{"msg": err.Error()})
}
}
wrapper := ServerInterfaceWrapper{
Handler: si,
HandlerMiddlewares: options.Middlewares,
ErrorHandler: errorHandler,
}
router.POST(options.BaseURL+"/auth/sign-in", wrapper.PostAuthSignIn)
router.POST(options.BaseURL+"/auth/sign-up", wrapper.PostAuthSignUp)
router.POST(options.BaseURL+"/auth/verify-token", wrapper.PostAuthVerifyToken)
}
type PostAuthSignInRequestObject struct {
Body *PostAuthSignInJSONRequestBody
}
type PostAuthSignInResponseObject interface {
VisitPostAuthSignInResponse(w http.ResponseWriter) error
}
type PostAuthSignIn200JSONResponse struct {
Error *string `json:"error"`
Success *bool `json:"success,omitempty"`
// Token JWT token to access protected endpoints
Token *string `json:"token"`
UserId *string `json:"user_id"`
}
func (response PostAuthSignIn200JSONResponse) VisitPostAuthSignInResponse(w http.ResponseWriter) error {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(200)
return json.NewEncoder(w).Encode(response)
}
type PostAuthSignUpRequestObject struct {
Body *PostAuthSignUpJSONRequestBody
}
type PostAuthSignUpResponseObject interface {
VisitPostAuthSignUpResponse(w http.ResponseWriter) error
}
type PostAuthSignUp200JSONResponse struct {
Error *string `json:"error"`
Success *bool `json:"success,omitempty"`
UserId *string `json:"user_id"`
}
func (response PostAuthSignUp200JSONResponse) VisitPostAuthSignUpResponse(w http.ResponseWriter) error {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(200)
return json.NewEncoder(w).Encode(response)
}
type PostAuthVerifyTokenRequestObject struct {
Body *PostAuthVerifyTokenJSONRequestBody
}
type PostAuthVerifyTokenResponseObject interface {
VisitPostAuthVerifyTokenResponse(w http.ResponseWriter) error
}
type PostAuthVerifyToken200JSONResponse struct {
// Error Error message if token is invalid
Error *string `json:"error"`
// UserId User ID extracted from token if valid
UserId *string `json:"user_id"`
// Valid True if token is valid
Valid *bool `json:"valid,omitempty"`
}
func (response PostAuthVerifyToken200JSONResponse) VisitPostAuthVerifyTokenResponse(w http.ResponseWriter) error {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(200)
return json.NewEncoder(w).Encode(response)
}
// StrictServerInterface represents all server handlers.
type StrictServerInterface interface {
// Sign in a user and return JWT
// (POST /auth/sign-in)
PostAuthSignIn(ctx context.Context, request PostAuthSignInRequestObject) (PostAuthSignInResponseObject, error)
// Sign up a new user
// (POST /auth/sign-up)
PostAuthSignUp(ctx context.Context, request PostAuthSignUpRequestObject) (PostAuthSignUpResponseObject, error)
// Verify JWT validity
// (POST /auth/verify-token)
PostAuthVerifyToken(ctx context.Context, request PostAuthVerifyTokenRequestObject) (PostAuthVerifyTokenResponseObject, error)
}
type StrictHandlerFunc = strictgin.StrictGinHandlerFunc
type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc
func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface {
return &strictHandler{ssi: ssi, middlewares: middlewares}
}
type strictHandler struct {
ssi StrictServerInterface
middlewares []StrictMiddlewareFunc
}
// PostAuthSignIn operation middleware
func (sh *strictHandler) PostAuthSignIn(ctx *gin.Context) {
var request PostAuthSignInRequestObject
var body PostAuthSignInJSONRequestBody
if err := ctx.ShouldBindJSON(&body); err != nil {
ctx.Status(http.StatusBadRequest)
ctx.Error(err)
return
}
request.Body = &body
handler := func(ctx *gin.Context, request interface{}) (interface{}, error) {
return sh.ssi.PostAuthSignIn(ctx, request.(PostAuthSignInRequestObject))
}
for _, middleware := range sh.middlewares {
handler = middleware(handler, "PostAuthSignIn")
}
response, err := handler(ctx, request)
if err != nil {
ctx.Error(err)
ctx.Status(http.StatusInternalServerError)
} else if validResponse, ok := response.(PostAuthSignInResponseObject); ok {
if err := validResponse.VisitPostAuthSignInResponse(ctx.Writer); err != nil {
ctx.Error(err)
}
} else if response != nil {
ctx.Error(fmt.Errorf("unexpected response type: %T", response))
}
}
// PostAuthSignUp operation middleware
func (sh *strictHandler) PostAuthSignUp(ctx *gin.Context) {
var request PostAuthSignUpRequestObject
var body PostAuthSignUpJSONRequestBody
if err := ctx.ShouldBindJSON(&body); err != nil {
ctx.Status(http.StatusBadRequest)
ctx.Error(err)
return
}
request.Body = &body
handler := func(ctx *gin.Context, request interface{}) (interface{}, error) {
return sh.ssi.PostAuthSignUp(ctx, request.(PostAuthSignUpRequestObject))
}
for _, middleware := range sh.middlewares {
handler = middleware(handler, "PostAuthSignUp")
}
response, err := handler(ctx, request)
if err != nil {
ctx.Error(err)
ctx.Status(http.StatusInternalServerError)
} else if validResponse, ok := response.(PostAuthSignUpResponseObject); ok {
if err := validResponse.VisitPostAuthSignUpResponse(ctx.Writer); err != nil {
ctx.Error(err)
}
} else if response != nil {
ctx.Error(fmt.Errorf("unexpected response type: %T", response))
}
}
// PostAuthVerifyToken operation middleware
func (sh *strictHandler) PostAuthVerifyToken(ctx *gin.Context) {
var request PostAuthVerifyTokenRequestObject
var body PostAuthVerifyTokenJSONRequestBody
if err := ctx.ShouldBindJSON(&body); err != nil {
ctx.Status(http.StatusBadRequest)
ctx.Error(err)
return
}
request.Body = &body
handler := func(ctx *gin.Context, request interface{}) (interface{}, error) {
return sh.ssi.PostAuthVerifyToken(ctx, request.(PostAuthVerifyTokenRequestObject))
}
for _, middleware := range sh.middlewares {
handler = middleware(handler, "PostAuthVerifyToken")
}
response, err := handler(ctx, request)
if err != nil {
ctx.Error(err)
ctx.Status(http.StatusInternalServerError)
} else if validResponse, ok := response.(PostAuthVerifyTokenResponseObject); ok {
if err := validResponse.VisitPostAuthVerifyTokenResponse(ctx.Writer); err != nil {
ctx.Error(err)
}
} else if response != nil {
ctx.Error(fmt.Errorf("unexpected response type: %T", response))
}
}

329
auth/auth/auth.gen.go Normal file
View file

@ -0,0 +1,329 @@
// Package oapi_auth provides primitives to interact with the openapi HTTP API.
//
// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.5.0 DO NOT EDIT.
package oapi_auth
import (
"context"
"encoding/json"
"fmt"
"net/http"
"github.com/gin-gonic/gin"
strictgin "github.com/oapi-codegen/runtime/strictmiddleware/gin"
)
// PostAuthSignInJSONBody defines parameters for PostAuthSignIn.
type PostAuthSignInJSONBody struct {
Nickname string `json:"nickname"`
Pass string `json:"pass"`
}
// PostAuthSignUpJSONBody defines parameters for PostAuthSignUp.
type PostAuthSignUpJSONBody struct {
Nickname string `json:"nickname"`
Pass string `json:"pass"`
}
// PostAuthVerifyTokenJSONBody defines parameters for PostAuthVerifyToken.
type PostAuthVerifyTokenJSONBody struct {
// Token JWT token to validate
Token string `json:"token"`
}
// PostAuthSignInJSONRequestBody defines body for PostAuthSignIn for application/json ContentType.
type PostAuthSignInJSONRequestBody PostAuthSignInJSONBody
// PostAuthSignUpJSONRequestBody defines body for PostAuthSignUp for application/json ContentType.
type PostAuthSignUpJSONRequestBody PostAuthSignUpJSONBody
// PostAuthVerifyTokenJSONRequestBody defines body for PostAuthVerifyToken for application/json ContentType.
type PostAuthVerifyTokenJSONRequestBody PostAuthVerifyTokenJSONBody
// ServerInterface represents all server handlers.
type ServerInterface interface {
// Sign in a user and return JWT
// (POST /auth/sign-in)
PostAuthSignIn(c *gin.Context)
// Sign up a new user
// (POST /auth/sign-up)
PostAuthSignUp(c *gin.Context)
// Verify JWT validity
// (POST /auth/verify-token)
PostAuthVerifyToken(c *gin.Context)
}
// ServerInterfaceWrapper converts contexts to parameters.
type ServerInterfaceWrapper struct {
Handler ServerInterface
HandlerMiddlewares []MiddlewareFunc
ErrorHandler func(*gin.Context, error, int)
}
type MiddlewareFunc func(c *gin.Context)
// PostAuthSignIn operation middleware
func (siw *ServerInterfaceWrapper) PostAuthSignIn(c *gin.Context) {
for _, middleware := range siw.HandlerMiddlewares {
middleware(c)
if c.IsAborted() {
return
}
}
siw.Handler.PostAuthSignIn(c)
}
// PostAuthSignUp operation middleware
func (siw *ServerInterfaceWrapper) PostAuthSignUp(c *gin.Context) {
for _, middleware := range siw.HandlerMiddlewares {
middleware(c)
if c.IsAborted() {
return
}
}
siw.Handler.PostAuthSignUp(c)
}
// PostAuthVerifyToken operation middleware
func (siw *ServerInterfaceWrapper) PostAuthVerifyToken(c *gin.Context) {
for _, middleware := range siw.HandlerMiddlewares {
middleware(c)
if c.IsAborted() {
return
}
}
siw.Handler.PostAuthVerifyToken(c)
}
// GinServerOptions provides options for the Gin server.
type GinServerOptions struct {
BaseURL string
Middlewares []MiddlewareFunc
ErrorHandler func(*gin.Context, error, int)
}
// RegisterHandlers creates http.Handler with routing matching OpenAPI spec.
func RegisterHandlers(router gin.IRouter, si ServerInterface) {
RegisterHandlersWithOptions(router, si, GinServerOptions{})
}
// RegisterHandlersWithOptions creates http.Handler with additional options
func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options GinServerOptions) {
errorHandler := options.ErrorHandler
if errorHandler == nil {
errorHandler = func(c *gin.Context, err error, statusCode int) {
c.JSON(statusCode, gin.H{"msg": err.Error()})
}
}
wrapper := ServerInterfaceWrapper{
Handler: si,
HandlerMiddlewares: options.Middlewares,
ErrorHandler: errorHandler,
}
router.POST(options.BaseURL+"/auth/sign-in", wrapper.PostAuthSignIn)
router.POST(options.BaseURL+"/auth/sign-up", wrapper.PostAuthSignUp)
router.POST(options.BaseURL+"/auth/verify-token", wrapper.PostAuthVerifyToken)
}
type PostAuthSignInRequestObject struct {
Body *PostAuthSignInJSONRequestBody
}
type PostAuthSignInResponseObject interface {
VisitPostAuthSignInResponse(w http.ResponseWriter) error
}
type PostAuthSignIn200JSONResponse struct {
Error *string `json:"error"`
Success *bool `json:"success,omitempty"`
// Token JWT token to access protected endpoints
Token *string `json:"token"`
UserId *string `json:"user_id"`
}
func (response PostAuthSignIn200JSONResponse) VisitPostAuthSignInResponse(w http.ResponseWriter) error {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(200)
return json.NewEncoder(w).Encode(response)
}
type PostAuthSignUpRequestObject struct {
Body *PostAuthSignUpJSONRequestBody
}
type PostAuthSignUpResponseObject interface {
VisitPostAuthSignUpResponse(w http.ResponseWriter) error
}
type PostAuthSignUp200JSONResponse struct {
Error *string `json:"error"`
Success *bool `json:"success,omitempty"`
UserId *string `json:"user_id"`
}
func (response PostAuthSignUp200JSONResponse) VisitPostAuthSignUpResponse(w http.ResponseWriter) error {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(200)
return json.NewEncoder(w).Encode(response)
}
type PostAuthVerifyTokenRequestObject struct {
Body *PostAuthVerifyTokenJSONRequestBody
}
type PostAuthVerifyTokenResponseObject interface {
VisitPostAuthVerifyTokenResponse(w http.ResponseWriter) error
}
type PostAuthVerifyToken200JSONResponse struct {
// Error Error message if token is invalid
Error *string `json:"error"`
// UserId User ID extracted from token if valid
UserId *string `json:"user_id"`
// Valid True if token is valid
Valid *bool `json:"valid,omitempty"`
}
func (response PostAuthVerifyToken200JSONResponse) VisitPostAuthVerifyTokenResponse(w http.ResponseWriter) error {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(200)
return json.NewEncoder(w).Encode(response)
}
// StrictServerInterface represents all server handlers.
type StrictServerInterface interface {
// Sign in a user and return JWT
// (POST /auth/sign-in)
PostAuthSignIn(ctx context.Context, request PostAuthSignInRequestObject) (PostAuthSignInResponseObject, error)
// Sign up a new user
// (POST /auth/sign-up)
PostAuthSignUp(ctx context.Context, request PostAuthSignUpRequestObject) (PostAuthSignUpResponseObject, error)
// Verify JWT validity
// (POST /auth/verify-token)
PostAuthVerifyToken(ctx context.Context, request PostAuthVerifyTokenRequestObject) (PostAuthVerifyTokenResponseObject, error)
}
type StrictHandlerFunc = strictgin.StrictGinHandlerFunc
type StrictMiddlewareFunc = strictgin.StrictGinMiddlewareFunc
func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface {
return &strictHandler{ssi: ssi, middlewares: middlewares}
}
type strictHandler struct {
ssi StrictServerInterface
middlewares []StrictMiddlewareFunc
}
// PostAuthSignIn operation middleware
func (sh *strictHandler) PostAuthSignIn(ctx *gin.Context) {
var request PostAuthSignInRequestObject
var body PostAuthSignInJSONRequestBody
if err := ctx.ShouldBindJSON(&body); err != nil {
ctx.Status(http.StatusBadRequest)
ctx.Error(err)
return
}
request.Body = &body
handler := func(ctx *gin.Context, request interface{}) (interface{}, error) {
return sh.ssi.PostAuthSignIn(ctx, request.(PostAuthSignInRequestObject))
}
for _, middleware := range sh.middlewares {
handler = middleware(handler, "PostAuthSignIn")
}
response, err := handler(ctx, request)
if err != nil {
ctx.Error(err)
ctx.Status(http.StatusInternalServerError)
} else if validResponse, ok := response.(PostAuthSignInResponseObject); ok {
if err := validResponse.VisitPostAuthSignInResponse(ctx.Writer); err != nil {
ctx.Error(err)
}
} else if response != nil {
ctx.Error(fmt.Errorf("unexpected response type: %T", response))
}
}
// PostAuthSignUp operation middleware
func (sh *strictHandler) PostAuthSignUp(ctx *gin.Context) {
var request PostAuthSignUpRequestObject
var body PostAuthSignUpJSONRequestBody
if err := ctx.ShouldBindJSON(&body); err != nil {
ctx.Status(http.StatusBadRequest)
ctx.Error(err)
return
}
request.Body = &body
handler := func(ctx *gin.Context, request interface{}) (interface{}, error) {
return sh.ssi.PostAuthSignUp(ctx, request.(PostAuthSignUpRequestObject))
}
for _, middleware := range sh.middlewares {
handler = middleware(handler, "PostAuthSignUp")
}
response, err := handler(ctx, request)
if err != nil {
ctx.Error(err)
ctx.Status(http.StatusInternalServerError)
} else if validResponse, ok := response.(PostAuthSignUpResponseObject); ok {
if err := validResponse.VisitPostAuthSignUpResponse(ctx.Writer); err != nil {
ctx.Error(err)
}
} else if response != nil {
ctx.Error(fmt.Errorf("unexpected response type: %T", response))
}
}
// PostAuthVerifyToken operation middleware
func (sh *strictHandler) PostAuthVerifyToken(ctx *gin.Context) {
var request PostAuthVerifyTokenRequestObject
var body PostAuthVerifyTokenJSONRequestBody
if err := ctx.ShouldBindJSON(&body); err != nil {
ctx.Status(http.StatusBadRequest)
ctx.Error(err)
return
}
request.Body = &body
handler := func(ctx *gin.Context, request interface{}) (interface{}, error) {
return sh.ssi.PostAuthVerifyToken(ctx, request.(PostAuthVerifyTokenRequestObject))
}
for _, middleware := range sh.middlewares {
handler = middleware(handler, "PostAuthVerifyToken")
}
response, err := handler(ctx, request)
if err != nil {
ctx.Error(err)
ctx.Status(http.StatusInternalServerError)
} else if validResponse, ok := response.(PostAuthVerifyTokenResponseObject); ok {
if err := validResponse.VisitPostAuthVerifyTokenResponse(ctx.Writer); err != nil {
ctx.Error(err)
}
} else if response != nil {
ctx.Error(fmt.Errorf("unexpected response type: %T", response))
}
}

View file

@ -0,0 +1,6 @@
package: auth
generate:
strict-server: true
gin-server: true
models: true
output: auth/auth.gen.go

112
auth/openapi-auth.yaml Normal file
View file

@ -0,0 +1,112 @@
openapi: 3.1.0
info:
title: Auth Service
version: 1.0.0
paths:
/auth/sign-up:
post:
summary: Sign up a new user
tags: [Auth]
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [nickname, pass]
properties:
nickname:
type: string
pass:
type: string
format: password
responses:
"200":
description: Sign-up result
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
error:
type: string
nullable: true
user_id:
type: string
nullable: true
/auth/sign-in:
post:
summary: Sign in a user and return JWT
tags: [Auth]
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [nickname, pass]
properties:
nickname:
type: string
pass:
type: string
format: password
responses:
"200":
description: Sign-in result with JWT
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
error:
type: string
nullable: true
user_id:
type: string
nullable: true
token:
type: string
description: JWT token to access protected endpoints
nullable: true
/auth/verify-token:
post:
summary: Verify JWT validity
tags: [Auth]
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [token]
properties:
token:
type: string
description: JWT token to validate
responses:
"200":
description: Token validation result
content:
application/json:
schema:
type: object
properties:
valid:
type: boolean
description: True if token is valid
user_id:
type: string
nullable: true
description: User ID extracted from token if valid
error:
type: string
nullable: true
description: Error message if token is invalid