fix: end of line char
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
PHONY: gen_openapi_models
|
||||
gen_openapi_models: openapi/cfg.yaml openapi/openapi.yaml
|
||||
oapi-codegen.exe -config .\openapi\cfg.yaml .\openapi\openapi.yaml
|
||||
PHONY: gen_openapi_models
|
||||
gen_openapi_models: openapi/cfg.yaml openapi/openapi.yaml
|
||||
oapi-codegen.exe -config .\openapi\cfg.yaml .\openapi\openapi.yaml
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
# ETA API v2
|
||||
|
||||
This is the second generation of the ETA API developed on GoLang using OpenAPI to auto document and generate api endpoints.
|
||||
|
||||
# OpenApi Generator
|
||||
|
||||
With the following command the generator tool can be installed
|
||||
|
||||
```.{sh}
|
||||
go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@latest
|
||||
```
|
||||
|
||||
|
||||
|
||||
# Deployment
|
||||
|
||||
The details on how to deploy are described here
|
||||
|
||||
## DOTENV
|
||||
|
||||
```{.sh}
|
||||
SQL_DSN="{USER}:{PASS}@tcp({HOST}:{PORT})/{DB}?charset=utf8mb4&parseTime=true&loc=Local"
|
||||
```
|
||||
|
||||
# ETA API v2
|
||||
|
||||
This is the second generation of the ETA API developed on GoLang using OpenAPI to auto document and generate api endpoints.
|
||||
|
||||
# OpenApi Generator
|
||||
|
||||
With the following command the generator tool can be installed
|
||||
|
||||
```.{sh}
|
||||
go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@latest
|
||||
```
|
||||
|
||||
|
||||
|
||||
# Deployment
|
||||
|
||||
The details on how to deploy are described here
|
||||
|
||||
## DOTENV
|
||||
|
||||
```{.sh}
|
||||
SQL_DSN="{USER}:{PASS}@tcp({HOST}:{PORT})/{DB}?charset=utf8mb4&parseTime=true&loc=Local"
|
||||
```
|
||||
|
||||
|
||||
# GPU information
|
||||
|
||||
https://en.wikipedia.org/wiki/Graphics_processing_unit ->
|
||||
https://en.wikipedia.org/wiki/Shader -> https://en.wikipedia.org/wiki/RenderMan_Interface_Specification
|
||||
@@ -1,42 +1,42 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/spf13/viper"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var shared_db_connection *gorm.DB
|
||||
|
||||
func initDB() *gorm.DB {
|
||||
// load .env into environment (so viper can read them)
|
||||
if err := godotenv.Load(); err != nil {
|
||||
log.Println(".env not found or could not be loaded; proceeding with existing environment variables")
|
||||
}
|
||||
|
||||
viper.AutomaticEnv() // read from environment
|
||||
|
||||
sql_dsn := viper.GetString("SQL_DSN")
|
||||
|
||||
if sql_dsn == "" {
|
||||
log.Fatal("SQL_DSN must be set in .env or environment")
|
||||
}
|
||||
|
||||
db, err := gorm.Open(mysql.Open(sql_dsn), &gorm.Config{})
|
||||
if err != nil {
|
||||
log.Fatalf("failed to connect to MySQL Server: %v", err)
|
||||
}
|
||||
|
||||
log.Println("connected to MySQL Server")
|
||||
return db
|
||||
}
|
||||
|
||||
func Init() *gorm.DB {
|
||||
if shared_db_connection == nil {
|
||||
shared_db_connection = initDB()
|
||||
}
|
||||
return shared_db_connection
|
||||
}
|
||||
package database
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/spf13/viper"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var shared_db_connection *gorm.DB
|
||||
|
||||
func initDB() *gorm.DB {
|
||||
// load .env into environment (so viper can read them)
|
||||
if err := godotenv.Load(); err != nil {
|
||||
log.Println(".env not found or could not be loaded; proceeding with existing environment variables")
|
||||
}
|
||||
|
||||
viper.AutomaticEnv() // read from environment
|
||||
|
||||
sql_dsn := viper.GetString("SQL_DSN")
|
||||
|
||||
if sql_dsn == "" {
|
||||
log.Fatal("SQL_DSN must be set in .env or environment")
|
||||
}
|
||||
|
||||
db, err := gorm.Open(mysql.Open(sql_dsn), &gorm.Config{})
|
||||
if err != nil {
|
||||
log.Fatalf("failed to connect to MySQL Server: %v", err)
|
||||
}
|
||||
|
||||
log.Println("connected to MySQL Server")
|
||||
return db
|
||||
}
|
||||
|
||||
func Init() *gorm.DB {
|
||||
if shared_db_connection == nil {
|
||||
shared_db_connection = initDB()
|
||||
}
|
||||
return shared_db_connection
|
||||
}
|
||||
|
||||
@@ -1,124 +1,124 @@
|
||||
/**
|
||||
* @file schema.rbac.go
|
||||
* @brief RBAC schema models for GORM
|
||||
*
|
||||
* This file defines the base database models used by the RBAC
|
||||
* (Role-Based Access Control) system. Models map to the following
|
||||
* tables: user_types, users, auth_identities, auth_credentials,
|
||||
* roles, permissions, role_permissions and user_roles.
|
||||
*
|
||||
* The structs include GORM tags for column names and relationships:
|
||||
* - UserType: types of users.
|
||||
* - User: main user record; links to UserType, AuthIdentity and UserRole.
|
||||
* - AuthIdentity: external identity providers; links to AuthCredential.
|
||||
* - AuthCredential: stored credentials for an identity.
|
||||
* - Role: role definitions and their permissions and assigned users.
|
||||
* - Permission: permission definitions.
|
||||
* - RolePermission: join table between Role and Permission.
|
||||
* - UserRole: join table between User and Role with optional expiration.
|
||||
*
|
||||
* These models are intended for use with GORM to perform ORM operations
|
||||
* against the RBAC schema.
|
||||
*/
|
||||
|
||||
package rbac
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserType struct {
|
||||
ID uint `gorm:"primaryKey;column:id"`
|
||||
Name string `gorm:"type:text;column:name"`
|
||||
Description *string `gorm:"type:text;column:description"`
|
||||
}
|
||||
|
||||
func (UserType) TableName() string { return "user_types" }
|
||||
|
||||
type User struct {
|
||||
ID uint `gorm:"primaryKey;column:id"`
|
||||
UserTypeID uint `gorm:"column:user_type"`
|
||||
Name string `gorm:"type:text;column:name"`
|
||||
LastName string `gorm:"type:text;column:last_name"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime"`
|
||||
|
||||
UserType UserType `gorm:"foreignKey:UserTypeID;references:ID"`
|
||||
AuthIdentities []AuthIdentity `gorm:"foreignKey:UserID;references:ID"`
|
||||
UserRoles []UserRole `gorm:"foreignKey:UserID;references:ID"`
|
||||
}
|
||||
|
||||
func (User) TableName() string { return "users" }
|
||||
|
||||
type AuthIdentity struct {
|
||||
ID uint `gorm:"primaryKey;column:id"`
|
||||
UserID uint `gorm:"column:user_id"`
|
||||
Provider string `gorm:"type:text;column:provider"`
|
||||
Identifier string `gorm:"type:text;column:identifier"`
|
||||
IsPrimary bool `gorm:"column:is_primary"`
|
||||
IsVerified bool `gorm:"column:is_verified"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime"`
|
||||
|
||||
User User `gorm:"foreignKey:UserID;references:ID"`
|
||||
Credentials []AuthCredential `gorm:"foreignKey:IdentityID;references:ID"`
|
||||
}
|
||||
|
||||
func (AuthIdentity) TableName() string { return "auth_identities" }
|
||||
|
||||
type AuthCredential struct {
|
||||
ID uint `gorm:"primaryKey;column:id"`
|
||||
IdentityID uint `gorm:"column:identity_id"`
|
||||
Password string `gorm:"type:text;column:password"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime"`
|
||||
|
||||
Identity AuthIdentity `gorm:"foreignKey:IdentityID;references:ID"`
|
||||
}
|
||||
|
||||
func (AuthCredential) TableName() string { return "auth_credentials" }
|
||||
|
||||
type Role struct {
|
||||
ID uint `gorm:"primaryKey;column:id"`
|
||||
Name string `gorm:"type:text;column:name"`
|
||||
Description *string `gorm:"type:text;column:description"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime"`
|
||||
RolePermissions []RolePermission `gorm:"foreignKey:RoleID;references:ID"`
|
||||
UserRoles []UserRole `gorm:"foreignKey:RoleID;references:ID"`
|
||||
}
|
||||
|
||||
func (Role) TableName() string { return "roles" }
|
||||
|
||||
type Permission struct {
|
||||
ID uint `gorm:"primaryKey;column:id"`
|
||||
Name string `gorm:"type:text;column:name"`
|
||||
Description *string `gorm:"type:text;column:description"`
|
||||
RolePermissions []RolePermission `gorm:"foreignKey:PermissionID;references:ID"`
|
||||
}
|
||||
|
||||
func (Permission) TableName() string { return "permissions" }
|
||||
|
||||
type RolePermission struct {
|
||||
ID uint `gorm:"primaryKey;column:id"`
|
||||
RoleID uint `gorm:"column:role_id"`
|
||||
PermissionID uint `gorm:"column:permission_id"`
|
||||
|
||||
Role Role `gorm:"foreignKey:RoleID;references:ID"`
|
||||
Permission Permission `gorm:"foreignKey:PermissionID;references:ID"`
|
||||
}
|
||||
|
||||
func (RolePermission) TableName() string { return "role_permissions" }
|
||||
|
||||
type UserRole struct {
|
||||
ID uint `gorm:"primaryKey;column:id"`
|
||||
UserID uint `gorm:"column:user_id"`
|
||||
RoleID uint `gorm:"column:role_id"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime"`
|
||||
ExpiresAt *time.Time `gorm:"column:expires_at"`
|
||||
|
||||
User User `gorm:"foreignKey:UserID;references:ID"`
|
||||
Role Role `gorm:"foreignKey:RoleID;references:ID"`
|
||||
}
|
||||
|
||||
func (UserRole) TableName() string { return "user_roles" }
|
||||
/**
|
||||
* @file schema.rbac.go
|
||||
* @brief RBAC schema models for GORM
|
||||
*
|
||||
* This file defines the base database models used by the RBAC
|
||||
* (Role-Based Access Control) system. Models map to the following
|
||||
* tables: user_types, users, auth_identities, auth_credentials,
|
||||
* roles, permissions, role_permissions and user_roles.
|
||||
*
|
||||
* The structs include GORM tags for column names and relationships:
|
||||
* - UserType: types of users.
|
||||
* - User: main user record; links to UserType, AuthIdentity and UserRole.
|
||||
* - AuthIdentity: external identity providers; links to AuthCredential.
|
||||
* - AuthCredential: stored credentials for an identity.
|
||||
* - Role: role definitions and their permissions and assigned users.
|
||||
* - Permission: permission definitions.
|
||||
* - RolePermission: join table between Role and Permission.
|
||||
* - UserRole: join table between User and Role with optional expiration.
|
||||
*
|
||||
* These models are intended for use with GORM to perform ORM operations
|
||||
* against the RBAC schema.
|
||||
*/
|
||||
|
||||
package rbac
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type UserType struct {
|
||||
ID uint `gorm:"primaryKey;column:id"`
|
||||
Name string `gorm:"type:text;column:name"`
|
||||
Description *string `gorm:"type:text;column:description"`
|
||||
}
|
||||
|
||||
func (UserType) TableName() string { return "user_types" }
|
||||
|
||||
type User struct {
|
||||
ID uint `gorm:"primaryKey;column:id"`
|
||||
UserTypeID uint `gorm:"column:user_type"`
|
||||
Name string `gorm:"type:text;column:name"`
|
||||
LastName string `gorm:"type:text;column:last_name"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime"`
|
||||
|
||||
UserType UserType `gorm:"foreignKey:UserTypeID;references:ID"`
|
||||
AuthIdentities []AuthIdentity `gorm:"foreignKey:UserID;references:ID"`
|
||||
UserRoles []UserRole `gorm:"foreignKey:UserID;references:ID"`
|
||||
}
|
||||
|
||||
func (User) TableName() string { return "users" }
|
||||
|
||||
type AuthIdentity struct {
|
||||
ID uint `gorm:"primaryKey;column:id"`
|
||||
UserID uint `gorm:"column:user_id"`
|
||||
Provider string `gorm:"type:text;column:provider"`
|
||||
Identifier string `gorm:"type:text;column:identifier"`
|
||||
IsPrimary bool `gorm:"column:is_primary"`
|
||||
IsVerified bool `gorm:"column:is_verified"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime"`
|
||||
|
||||
User User `gorm:"foreignKey:UserID;references:ID"`
|
||||
Credentials []AuthCredential `gorm:"foreignKey:IdentityID;references:ID"`
|
||||
}
|
||||
|
||||
func (AuthIdentity) TableName() string { return "auth_identities" }
|
||||
|
||||
type AuthCredential struct {
|
||||
ID uint `gorm:"primaryKey;column:id"`
|
||||
IdentityID uint `gorm:"column:identity_id"`
|
||||
Password string `gorm:"type:text;column:password"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime"`
|
||||
|
||||
Identity AuthIdentity `gorm:"foreignKey:IdentityID;references:ID"`
|
||||
}
|
||||
|
||||
func (AuthCredential) TableName() string { return "auth_credentials" }
|
||||
|
||||
type Role struct {
|
||||
ID uint `gorm:"primaryKey;column:id"`
|
||||
Name string `gorm:"type:text;column:name"`
|
||||
Description *string `gorm:"type:text;column:description"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime"`
|
||||
RolePermissions []RolePermission `gorm:"foreignKey:RoleID;references:ID"`
|
||||
UserRoles []UserRole `gorm:"foreignKey:RoleID;references:ID"`
|
||||
}
|
||||
|
||||
func (Role) TableName() string { return "roles" }
|
||||
|
||||
type Permission struct {
|
||||
ID uint `gorm:"primaryKey;column:id"`
|
||||
Name string `gorm:"type:text;column:name"`
|
||||
Description *string `gorm:"type:text;column:description"`
|
||||
RolePermissions []RolePermission `gorm:"foreignKey:PermissionID;references:ID"`
|
||||
}
|
||||
|
||||
func (Permission) TableName() string { return "permissions" }
|
||||
|
||||
type RolePermission struct {
|
||||
ID uint `gorm:"primaryKey;column:id"`
|
||||
RoleID uint `gorm:"column:role_id"`
|
||||
PermissionID uint `gorm:"column:permission_id"`
|
||||
|
||||
Role Role `gorm:"foreignKey:RoleID;references:ID"`
|
||||
Permission Permission `gorm:"foreignKey:PermissionID;references:ID"`
|
||||
}
|
||||
|
||||
func (RolePermission) TableName() string { return "role_permissions" }
|
||||
|
||||
type UserRole struct {
|
||||
ID uint `gorm:"primaryKey;column:id"`
|
||||
UserID uint `gorm:"column:user_id"`
|
||||
RoleID uint `gorm:"column:role_id"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime"`
|
||||
ExpiresAt *time.Time `gorm:"column:expires_at"`
|
||||
|
||||
User User `gorm:"foreignKey:UserID;references:ID"`
|
||||
Role Role `gorm:"foreignKey:RoleID;references:ID"`
|
||||
}
|
||||
|
||||
func (UserRole) TableName() string { return "user_roles" }
|
||||
|
||||
@@ -1,52 +1,52 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"cloud.etaviaporte.com/api/libs/openapi"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type Handler struct{}
|
||||
|
||||
// GetAuthMe implements openapi.ServerInterface.
|
||||
func (handler Handler) GetAuthMe(c *fiber.Ctx) error {
|
||||
err_code := fiber.StatusInternalServerError
|
||||
code := "Something went wrong!"
|
||||
message := "This endpoint is not yet implemented"
|
||||
return c.Status(err_code).JSON(openapi.Error{
|
||||
Code: &code,
|
||||
Message: &message,
|
||||
})
|
||||
}
|
||||
|
||||
// PostAuthLogin implements openapi.ServerInterface.
|
||||
func (handler Handler) PostAuthLogin(c *fiber.Ctx) error {
|
||||
err_code := fiber.StatusInternalServerError
|
||||
code := "Something went wrong!"
|
||||
message := "This endpoint is not yet implemented"
|
||||
return c.Status(err_code).JSON(openapi.Error{
|
||||
Code: &code,
|
||||
Message: &message,
|
||||
})
|
||||
}
|
||||
|
||||
// PostAuthLogout implements openapi.ServerInterface.
|
||||
func (handler Handler) PostAuthLogout(c *fiber.Ctx) error {
|
||||
err_code := fiber.StatusInternalServerError
|
||||
code := "Something went wrong!"
|
||||
message := "This endpoint is not yet implemented"
|
||||
return c.Status(err_code).JSON(openapi.Error{
|
||||
Code: &code,
|
||||
Message: &message,
|
||||
})
|
||||
}
|
||||
|
||||
// PostAuthRefresh implements openapi.ServerInterface.
|
||||
func (handler Handler) PostAuthRefresh(c *fiber.Ctx) error {
|
||||
err_code := fiber.StatusInternalServerError
|
||||
code := "Something went wrong!"
|
||||
message := "This endpoint is not yet implemented"
|
||||
return c.Status(err_code).JSON(openapi.Error{
|
||||
Code: &code,
|
||||
Message: &message,
|
||||
})
|
||||
}
|
||||
package auth
|
||||
|
||||
import (
|
||||
"cloud.etaviaporte.com/api/libs/openapi"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type Handler struct{}
|
||||
|
||||
// GetAuthMe implements openapi.ServerInterface.
|
||||
func (handler Handler) GetAuthMe(c *fiber.Ctx) error {
|
||||
err_code := fiber.StatusInternalServerError
|
||||
code := "Something went wrong!"
|
||||
message := "This endpoint is not yet implemented"
|
||||
return c.Status(err_code).JSON(openapi.Error{
|
||||
Code: &code,
|
||||
Message: &message,
|
||||
})
|
||||
}
|
||||
|
||||
// PostAuthLogin implements openapi.ServerInterface.
|
||||
func (handler Handler) PostAuthLogin(c *fiber.Ctx) error {
|
||||
err_code := fiber.StatusInternalServerError
|
||||
code := "Something went wrong!"
|
||||
message := "This endpoint is not yet implemented"
|
||||
return c.Status(err_code).JSON(openapi.Error{
|
||||
Code: &code,
|
||||
Message: &message,
|
||||
})
|
||||
}
|
||||
|
||||
// PostAuthLogout implements openapi.ServerInterface.
|
||||
func (handler Handler) PostAuthLogout(c *fiber.Ctx) error {
|
||||
err_code := fiber.StatusInternalServerError
|
||||
code := "Something went wrong!"
|
||||
message := "This endpoint is not yet implemented"
|
||||
return c.Status(err_code).JSON(openapi.Error{
|
||||
Code: &code,
|
||||
Message: &message,
|
||||
})
|
||||
}
|
||||
|
||||
// PostAuthRefresh implements openapi.ServerInterface.
|
||||
func (handler Handler) PostAuthRefresh(c *fiber.Ctx) error {
|
||||
err_code := fiber.StatusInternalServerError
|
||||
code := "Something went wrong!"
|
||||
message := "This endpoint is not yet implemented"
|
||||
return c.Status(err_code).JSON(openapi.Error{
|
||||
Code: &code,
|
||||
Message: &message,
|
||||
})
|
||||
}
|
||||
|
||||
82
app/main.go
82
app/main.go
@@ -1,41 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/cors"
|
||||
"github.com/gofiber/fiber/v2/middleware/helmet"
|
||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||
|
||||
"cloud.etaviaporte.com/api/libs/services/auth"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(cors.New(cors.Config{
|
||||
AllowOrigins: "https://api.etaviaporte.com, http://127.0.0.1, http://localhost",
|
||||
AllowHeaders: "Origin, Content-Type, Accept, Authorization",
|
||||
AllowMethods: "GET, POST, HEAD, PUT, DELETE, PATCH",
|
||||
AllowCredentials: true,
|
||||
}))
|
||||
|
||||
app.Use(logger.New(logger.Config{
|
||||
Format: "[${ip}]:${port} ${status} - ${method} ${path}\n",
|
||||
}))
|
||||
|
||||
app.Use(helmet.New())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("Hello, World!")
|
||||
})
|
||||
|
||||
handler := auth.Handler{}
|
||||
// openapi.RegisterHandlers(app, auth.Handler{})
|
||||
|
||||
app.Post("/auth/login", handler.PostAuthLogin)
|
||||
app.Post("/auth/logout", handler.PostAuthLogout)
|
||||
app.Get("/auth/me", handler.GetAuthMe)
|
||||
app.Post("/auth/refresh", handler.PostAuthRefresh)
|
||||
|
||||
app.Listen(":3000")
|
||||
}
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/cors"
|
||||
"github.com/gofiber/fiber/v2/middleware/helmet"
|
||||
"github.com/gofiber/fiber/v2/middleware/logger"
|
||||
|
||||
"cloud.etaviaporte.com/api/libs/services/auth"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Use(cors.New(cors.Config{
|
||||
AllowOrigins: "https://api.etaviaporte.com, http://127.0.0.1, http://localhost",
|
||||
AllowHeaders: "Origin, Content-Type, Accept, Authorization",
|
||||
AllowMethods: "GET, POST, HEAD, PUT, DELETE, PATCH",
|
||||
AllowCredentials: true,
|
||||
}))
|
||||
|
||||
app.Use(logger.New(logger.Config{
|
||||
Format: "[${ip}]:${port} ${status} - ${method} ${path}\n",
|
||||
}))
|
||||
|
||||
app.Use(helmet.New())
|
||||
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("Hello, World!")
|
||||
})
|
||||
|
||||
handler := auth.Handler{}
|
||||
// openapi.RegisterHandlers(app, auth.Handler{})
|
||||
|
||||
app.Post("/auth/login", handler.PostAuthLogin)
|
||||
app.Post("/auth/logout", handler.PostAuthLogout)
|
||||
app.Get("/auth/me", handler.GetAuthMe)
|
||||
app.Post("/auth/refresh", handler.PostAuthRefresh)
|
||||
|
||||
app.Listen(":3000")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package: openapi
|
||||
output: libs/openapi/generated.go
|
||||
generate:
|
||||
models: true
|
||||
output-options:
|
||||
skip-prune: true
|
||||
package: openapi
|
||||
output: libs/openapi/generated.go
|
||||
generate:
|
||||
models: true
|
||||
output-options:
|
||||
skip-prune: true
|
||||
|
||||
@@ -1,182 +1,182 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Authorization API
|
||||
version: "1.0.0"
|
||||
description: Simple authorization endpoints for login, refresh, logout and getting current user info.
|
||||
servers:
|
||||
- url: http://localhost:8080
|
||||
description: Local development server
|
||||
|
||||
paths:
|
||||
/auth/login:
|
||||
post:
|
||||
summary: Obtain access and refresh tokens
|
||||
tags:
|
||||
- Auth
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/LoginRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Tokens issued
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TokenResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
/auth/refresh:
|
||||
post:
|
||||
summary: Refresh access token using a refresh token
|
||||
tags:
|
||||
- Auth
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RefreshRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: New tokens
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TokenResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
/auth/logout:
|
||||
post:
|
||||
summary: Revoke refresh token / logout
|
||||
tags:
|
||||
- Auth
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RevokeRequest'
|
||||
responses:
|
||||
'204':
|
||||
description: Successfully logged out (no content)
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
/auth/me:
|
||||
get:
|
||||
summary: Get current authenticated user
|
||||
tags:
|
||||
- Auth
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
description: Current user profile
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserProfile'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
|
||||
schemas:
|
||||
LoginRequest:
|
||||
type: object
|
||||
required:
|
||||
- username
|
||||
- password
|
||||
properties:
|
||||
username:
|
||||
type: string
|
||||
example: user@example.com
|
||||
password:
|
||||
type: string
|
||||
format: password
|
||||
example: secret123
|
||||
|
||||
TokenResponse:
|
||||
type: object
|
||||
properties:
|
||||
accessToken:
|
||||
type: string
|
||||
example: eyJhbGciOi...
|
||||
refreshToken:
|
||||
type: string
|
||||
example: dummyr3fr3sht0k3n
|
||||
expiresIn:
|
||||
type: integer
|
||||
description: Seconds until access token expiration
|
||||
example: 3600
|
||||
|
||||
RefreshRequest:
|
||||
type: object
|
||||
required:
|
||||
- refreshToken
|
||||
properties:
|
||||
refreshToken:
|
||||
type: string
|
||||
|
||||
RevokeRequest:
|
||||
type: object
|
||||
required:
|
||||
- refreshToken
|
||||
properties:
|
||||
refreshToken:
|
||||
type: string
|
||||
|
||||
UserProfile:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
example: "123e4567-e89b-12d3-a456-426614174000"
|
||||
username:
|
||||
type: string
|
||||
example: user@example.com
|
||||
email:
|
||||
type: string
|
||||
example: user@example.com
|
||||
|
||||
Error:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
example: invalid_request
|
||||
message:
|
||||
type: string
|
||||
example: "Detailed error message"
|
||||
|
||||
responses:
|
||||
BadRequest:
|
||||
description: Invalid request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
Unauthorized:
|
||||
description: Authentication failed or missing credentials
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Authorization API
|
||||
version: "1.0.0"
|
||||
description: Simple authorization endpoints for login, refresh, logout and getting current user info.
|
||||
servers:
|
||||
- url: http://localhost:8080
|
||||
description: Local development server
|
||||
|
||||
paths:
|
||||
/auth/login:
|
||||
post:
|
||||
summary: Obtain access and refresh tokens
|
||||
tags:
|
||||
- Auth
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/LoginRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Tokens issued
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TokenResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
/auth/refresh:
|
||||
post:
|
||||
summary: Refresh access token using a refresh token
|
||||
tags:
|
||||
- Auth
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RefreshRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: New tokens
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TokenResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
/auth/logout:
|
||||
post:
|
||||
summary: Revoke refresh token / logout
|
||||
tags:
|
||||
- Auth
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RevokeRequest'
|
||||
responses:
|
||||
'204':
|
||||
description: Successfully logged out (no content)
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
/auth/me:
|
||||
get:
|
||||
summary: Get current authenticated user
|
||||
tags:
|
||||
- Auth
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
description: Current user profile
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserProfile'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
|
||||
schemas:
|
||||
LoginRequest:
|
||||
type: object
|
||||
required:
|
||||
- username
|
||||
- password
|
||||
properties:
|
||||
username:
|
||||
type: string
|
||||
example: user@example.com
|
||||
password:
|
||||
type: string
|
||||
format: password
|
||||
example: secret123
|
||||
|
||||
TokenResponse:
|
||||
type: object
|
||||
properties:
|
||||
accessToken:
|
||||
type: string
|
||||
example: eyJhbGciOi...
|
||||
refreshToken:
|
||||
type: string
|
||||
example: dummyr3fr3sht0k3n
|
||||
expiresIn:
|
||||
type: integer
|
||||
description: Seconds until access token expiration
|
||||
example: 3600
|
||||
|
||||
RefreshRequest:
|
||||
type: object
|
||||
required:
|
||||
- refreshToken
|
||||
properties:
|
||||
refreshToken:
|
||||
type: string
|
||||
|
||||
RevokeRequest:
|
||||
type: object
|
||||
required:
|
||||
- refreshToken
|
||||
properties:
|
||||
refreshToken:
|
||||
type: string
|
||||
|
||||
UserProfile:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
example: "123e4567-e89b-12d3-a456-426614174000"
|
||||
username:
|
||||
type: string
|
||||
example: user@example.com
|
||||
email:
|
||||
type: string
|
||||
example: user@example.com
|
||||
|
||||
Error:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
example: invalid_request
|
||||
message:
|
||||
type: string
|
||||
example: "Detailed error message"
|
||||
|
||||
responses:
|
||||
BadRequest:
|
||||
description: Invalid request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
Unauthorized:
|
||||
description: Authentication failed or missing credentials
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
Reference in New Issue
Block a user