otpm/docs/swagger.go
“xHuPo” bcd986e3f7 beta
2025-05-23 18:57:11 +08:00

663 lines
18 KiB
Go

// Package docs provides API documentation using Swagger/OpenAPI
package docs
import (
"encoding/json"
"net/http"
)
// SwaggerInfo holds the API information
var SwaggerInfo = struct {
Title string
Description string
Version string
Host string
BasePath string
Schemes []string
}{
Title: "OTPM API",
Description: "API for One-Time Password Manager",
Version: "1.0.0",
Host: "localhost:8080",
BasePath: "/",
Schemes: []string{"http", "https"},
}
// SwaggerJSON returns the Swagger JSON
func SwaggerJSON() []byte {
swagger := map[string]interface{}{
"swagger": "2.0",
"info": map[string]interface{}{
"title": SwaggerInfo.Title,
"description": SwaggerInfo.Description,
"version": SwaggerInfo.Version,
},
"host": SwaggerInfo.Host,
"basePath": SwaggerInfo.BasePath,
"schemes": SwaggerInfo.Schemes,
"paths": getPaths(),
"definitions": map[string]interface{}{
"LoginRequest": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"code": map[string]interface{}{
"type": "string",
"description": "WeChat authorization code",
},
},
"required": []string{"code"},
},
"LoginResponse": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"token": map[string]interface{}{
"type": "string",
"description": "JWT token",
},
"openid": map[string]interface{}{
"type": "string",
"description": "WeChat OpenID",
},
},
},
"CreateOTPRequest": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"name": map[string]interface{}{
"type": "string",
"description": "OTP name",
},
"issuer": map[string]interface{}{
"type": "string",
"description": "OTP issuer",
},
"secret": map[string]interface{}{
"type": "string",
"description": "OTP secret",
},
"algorithm": map[string]interface{}{
"type": "string",
"description": "OTP algorithm",
"enum": []string{"SHA1", "SHA256", "SHA512"},
},
"digits": map[string]interface{}{
"type": "integer",
"description": "OTP digits",
"enum": []int{6, 8},
},
"period": map[string]interface{}{
"type": "integer",
"description": "OTP period in seconds",
"enum": []int{30, 60},
},
},
"required": []string{"name", "issuer", "secret", "algorithm", "digits", "period"},
},
"OTP": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"id": map[string]interface{}{
"type": "string",
"description": "OTP ID",
},
"user_id": map[string]interface{}{
"type": "string",
"description": "User ID",
},
"name": map[string]interface{}{
"type": "string",
"description": "OTP name",
},
"issuer": map[string]interface{}{
"type": "string",
"description": "OTP issuer",
},
"algorithm": map[string]interface{}{
"type": "string",
"description": "OTP algorithm",
},
"digits": map[string]interface{}{
"type": "integer",
"description": "OTP digits",
},
"period": map[string]interface{}{
"type": "integer",
"description": "OTP period in seconds",
},
"created_at": map[string]interface{}{
"type": "string",
"format": "date-time",
"description": "Creation time",
},
"updated_at": map[string]interface{}{
"type": "string",
"format": "date-time",
"description": "Last update time",
},
},
},
"OTPCodeResponse": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"code": map[string]interface{}{
"type": "string",
"description": "OTP code",
},
"expires_in": map[string]interface{}{
"type": "integer",
"description": "Seconds until expiration",
},
},
},
"VerifyOTPRequest": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"code": map[string]interface{}{
"type": "string",
"description": "OTP code to verify",
},
},
"required": []string{"code"},
},
"VerifyOTPResponse": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"valid": map[string]interface{}{
"type": "boolean",
"description": "Whether the code is valid",
},
},
},
"UpdateOTPRequest": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"name": map[string]interface{}{
"type": "string",
"description": "OTP name",
},
"issuer": map[string]interface{}{
"type": "string",
"description": "OTP issuer",
},
"algorithm": map[string]interface{}{
"type": "string",
"description": "OTP algorithm",
"enum": []string{"SHA1", "SHA256", "SHA512"},
},
"digits": map[string]interface{}{
"type": "integer",
"description": "OTP digits",
"enum": []int{6, 8},
},
"period": map[string]interface{}{
"type": "integer",
"description": "OTP period in seconds",
"enum": []int{30, 60},
},
},
},
"ErrorResponse": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"code": map[string]interface{}{
"type": "integer",
"description": "Error code",
},
"message": map[string]interface{}{
"type": "string",
"description": "Error message",
},
},
},
},
"securityDefinitions": map[string]interface{}{
"Bearer": map[string]interface{}{
"type": "apiKey",
"name": "Authorization",
"in": "header",
"description": "JWT token with Bearer prefix",
},
},
}
data, _ := json.MarshalIndent(swagger, "", " ")
return data
}
// getPaths returns the API paths
func getPaths() map[string]interface{} {
return map[string]interface{}{
"/login": map[string]interface{}{
"post": map[string]interface{}{
"summary": "Login with WeChat",
"description": "Login with WeChat authorization code",
"tags": []string{"auth"},
"parameters": []map[string]interface{}{
{
"name": "body",
"in": "body",
"description": "Login request",
"required": true,
"schema": map[string]interface{}{
"$ref": "#/definitions/LoginRequest",
},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Successful login",
"schema": map[string]interface{}{
"$ref": "#/definitions/LoginResponse",
},
},
"400": map[string]interface{}{
"description": "Invalid request",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
"500": map[string]interface{}{
"description": "Internal server error",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
},
},
},
"/verify-token": map[string]interface{}{
"post": map[string]interface{}{
"summary": "Verify token",
"description": "Verify JWT token",
"tags": []string{"auth"},
"security": []map[string]interface{}{
{
"Bearer": []string{},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Token is valid",
"schema": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"valid": map[string]interface{}{
"type": "boolean",
"description": "Whether the token is valid",
},
},
},
},
"401": map[string]interface{}{
"description": "Unauthorized",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
},
},
},
"/otp": map[string]interface{}{
"get": map[string]interface{}{
"summary": "List OTPs",
"description": "List all OTPs for the authenticated user",
"tags": []string{"otp"},
"security": []map[string]interface{}{
{
"Bearer": []string{},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "List of OTPs",
"schema": map[string]interface{}{
"type": "array",
"items": map[string]interface{}{
"$ref": "#/definitions/OTP",
},
},
},
"401": map[string]interface{}{
"description": "Unauthorized",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
"500": map[string]interface{}{
"description": "Internal server error",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
},
},
"post": map[string]interface{}{
"summary": "Create OTP",
"description": "Create a new OTP",
"tags": []string{"otp"},
"security": []map[string]interface{}{
{
"Bearer": []string{},
},
},
"parameters": []map[string]interface{}{
{
"name": "body",
"in": "body",
"description": "OTP creation request",
"required": true,
"schema": map[string]interface{}{
"$ref": "#/definitions/CreateOTPRequest",
},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "OTP created",
"schema": map[string]interface{}{
"$ref": "#/definitions/OTP",
},
},
"400": map[string]interface{}{
"description": "Invalid request",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
"401": map[string]interface{}{
"description": "Unauthorized",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
"500": map[string]interface{}{
"description": "Internal server error",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
},
},
},
"/otp/{id}": map[string]interface{}{
"put": map[string]interface{}{
"summary": "Update OTP",
"description": "Update an existing OTP",
"tags": []string{"otp"},
"security": []map[string]interface{}{
{
"Bearer": []string{},
},
},
"parameters": []map[string]interface{}{
{
"name": "id",
"in": "path",
"description": "OTP ID",
"required": true,
"type": "string",
},
{
"name": "body",
"in": "body",
"description": "OTP update request",
"required": true,
"schema": map[string]interface{}{
"$ref": "#/definitions/UpdateOTPRequest",
},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "OTP updated",
"schema": map[string]interface{}{
"$ref": "#/definitions/OTP",
},
},
"400": map[string]interface{}{
"description": "Invalid request",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
"401": map[string]interface{}{
"description": "Unauthorized",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
"404": map[string]interface{}{
"description": "OTP not found",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
"500": map[string]interface{}{
"description": "Internal server error",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
},
},
"delete": map[string]interface{}{
"summary": "Delete OTP",
"description": "Delete an existing OTP",
"tags": []string{"otp"},
"security": []map[string]interface{}{
{
"Bearer": []string{},
},
},
"parameters": []map[string]interface{}{
{
"name": "id",
"in": "path",
"description": "OTP ID",
"required": true,
"type": "string",
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "OTP deleted",
"schema": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"message": map[string]interface{}{
"type": "string",
"description": "Success message",
},
},
},
},
"401": map[string]interface{}{
"description": "Unauthorized",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
"404": map[string]interface{}{
"description": "OTP not found",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
"500": map[string]interface{}{
"description": "Internal server error",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
},
},
},
"/otp/{id}/code": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Get OTP code",
"description": "Get the current OTP code",
"tags": []string{"otp"},
"security": []map[string]interface{}{
{
"Bearer": []string{},
},
},
"parameters": []map[string]interface{}{
{
"name": "id",
"in": "path",
"description": "OTP ID",
"required": true,
"type": "string",
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "OTP code",
"schema": map[string]interface{}{
"$ref": "#/definitions/OTPCodeResponse",
},
},
"401": map[string]interface{}{
"description": "Unauthorized",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
"404": map[string]interface{}{
"description": "OTP not found",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
"500": map[string]interface{}{
"description": "Internal server error",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
},
},
},
"/otp/{id}/verify": map[string]interface{}{
"post": map[string]interface{}{
"summary": "Verify OTP code",
"description": "Verify an OTP code",
"tags": []string{"otp"},
"security": []map[string]interface{}{
{
"Bearer": []string{},
},
},
"parameters": []map[string]interface{}{
{
"name": "id",
"in": "path",
"description": "OTP ID",
"required": true,
"type": "string",
},
{
"name": "body",
"in": "body",
"description": "OTP verification request",
"required": true,
"schema": map[string]interface{}{
"$ref": "#/definitions/VerifyOTPRequest",
},
},
},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "OTP verification result",
"schema": map[string]interface{}{
"$ref": "#/definitions/VerifyOTPResponse",
},
},
"400": map[string]interface{}{
"description": "Invalid request",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
"401": map[string]interface{}{
"description": "Unauthorized",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
"404": map[string]interface{}{
"description": "OTP not found",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
"500": map[string]interface{}{
"description": "Internal server error",
"schema": map[string]interface{}{
"$ref": "#/definitions/ErrorResponse",
},
},
},
},
},
"/health": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Health check",
"description": "Check if the API is healthy",
"tags": []string{"system"},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "API is healthy",
"schema": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"status": map[string]interface{}{
"type": "string",
"description": "Health status",
},
"time": map[string]interface{}{
"type": "string",
"format": "date-time",
"description": "Current time",
},
},
},
},
},
},
},
"/metrics": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Metrics",
"description": "Get application metrics",
"tags": []string{"system"},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Application metrics",
},
},
},
},
"/swagger.json": map[string]interface{}{
"get": map[string]interface{}{
"summary": "Swagger JSON",
"description": "Get Swagger JSON",
"tags": []string{"system"},
"responses": map[string]interface{}{
"200": map[string]interface{}{
"description": "Swagger JSON",
},
},
},
},
}
}
// Handler returns an HTTP handler for Swagger JSON
func Handler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write(SwaggerJSON())
}
}