beta
This commit is contained in:
parent
a45ddf13d5
commit
bcd986e3f7
46 changed files with 6166 additions and 454 deletions
663
docs/swagger.go
Normal file
663
docs/swagger.go
Normal file
|
@ -0,0 +1,663 @@
|
|||
// 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())
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue