From 0ca54237768ddbe7e60e58d897cdd6db9ecc861c Mon Sep 17 00:00:00 2001 From: Josepablo Cruz Date: Tue, 31 Mar 2026 21:01:07 -0600 Subject: [PATCH] fix: end of line char --- .gitignore | 128 ++++----- app/Makefile | 6 +- app/README.md | 53 ++-- app/libs/database/db.go | 84 +++--- app/libs/database/schemas/rbac/rbac.go | 248 ++++++++--------- app/libs/services/auth/services.go | 104 +++---- app/main.go | 82 +++--- app/openapi/cfg.yaml | 12 +- app/openapi/openapi.yaml | 364 ++++++++++++------------- db/.gitignore | 2 +- db/Dockerfile | 46 ++-- 11 files changed, 567 insertions(+), 562 deletions(-) diff --git a/.gitignore b/.gitignore index b81c8a0..1ad87f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,65 +1,65 @@ -# Binaries for programs and plugins -*.exe -*.exec -*.exe~ -*.dll -*.so -*.dylib -*.test - -# Build output (common names) -/bin/ -/dist/ -/build/ -*.out -coverage.out - -# Go tooling -go.work -# Uncomment if you don't commit vendored deps -# vendor/ - -# Dependency manager files (optional) -Gopkg.lock -glide.lock - -# Generated code -gen/ -generated/ - -# Environment / secrets -.env -.env.* -*.key -*.pem - -# Logs -*.log - -# Editor directories and files -.idea/ -# .vscode/ -*.iml -*.sublime-project -*.sublime-workspace - -# Swap/backup files -*~ -*.swp -*.swo -.#* - -# macOS / Windows -.DS_Store -Thumbs.db - -# Container / OS artifacts -docker-compose.override.yml - -# CI artifacts -coverage/ -reports/ - -# Misc -node_modules/ +# Binaries for programs and plugins +*.exe +*.exec +*.exe~ +*.dll +*.so +*.dylib +*.test + +# Build output (common names) +/bin/ +/dist/ +/build/ +*.out +coverage.out + +# Go tooling +go.work +# Uncomment if you don't commit vendored deps +# vendor/ + +# Dependency manager files (optional) +Gopkg.lock +glide.lock + +# Generated code +gen/ +generated/ + +# Environment / secrets +.env +.env.* +*.key +*.pem + +# Logs +*.log + +# Editor directories and files +.idea/ +# .vscode/ +*.iml +*.sublime-project +*.sublime-workspace + +# Swap/backup files +*~ +*.swp +*.swo +.#* + +# macOS / Windows +.DS_Store +Thumbs.db + +# Container / OS artifacts +docker-compose.override.yml + +# CI artifacts +coverage/ +reports/ + +# Misc +node_modules/ deprecated/ \ No newline at end of file diff --git a/app/Makefile b/app/Makefile index d2b22a6..3a78f8a 100644 --- a/app/Makefile +++ b/app/Makefile @@ -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 diff --git a/app/README.md b/app/README.md index d437df9..0d111f6 100644 --- a/app/README.md +++ b/app/README.md @@ -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 \ No newline at end of file diff --git a/app/libs/database/db.go b/app/libs/database/db.go index 08c8fda..db45901 100644 --- a/app/libs/database/db.go +++ b/app/libs/database/db.go @@ -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 +} diff --git a/app/libs/database/schemas/rbac/rbac.go b/app/libs/database/schemas/rbac/rbac.go index b0c5192..0e85119 100644 --- a/app/libs/database/schemas/rbac/rbac.go +++ b/app/libs/database/schemas/rbac/rbac.go @@ -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" } diff --git a/app/libs/services/auth/services.go b/app/libs/services/auth/services.go index fe22218..2ff341d 100644 --- a/app/libs/services/auth/services.go +++ b/app/libs/services/auth/services.go @@ -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, + }) +} diff --git a/app/main.go b/app/main.go index a5fd33c..5547aab 100644 --- a/app/main.go +++ b/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") +} diff --git a/app/openapi/cfg.yaml b/app/openapi/cfg.yaml index 1aa6dc3..07e831f 100644 --- a/app/openapi/cfg.yaml +++ b/app/openapi/cfg.yaml @@ -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 diff --git a/app/openapi/openapi.yaml b/app/openapi/openapi.yaml index d784ba2..27d223c 100644 --- a/app/openapi/openapi.yaml +++ b/app/openapi/openapi.yaml @@ -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' diff --git a/db/.gitignore b/db/.gitignore index 751553b..4473662 100644 --- a/db/.gitignore +++ b/db/.gitignore @@ -1 +1 @@ -*.bak +*.bak diff --git a/db/Dockerfile b/db/Dockerfile index 4a03601..cb642be 100644 --- a/db/Dockerfile +++ b/db/Dockerfile @@ -1,23 +1,23 @@ -# Original author : https://github.com/yobasystems/alpine-mariadb.git -FROM alpine:latest - -ARG BUILD_DATE -ARG VCS_REF - -RUN apk add --no-cache mariadb mysql-client mariadb-server-utils pwgen && \ - rm -f /var/cache/apk/* - -RUN mkdir /schemas -COPY schemas /schemas - -ADD scripts/run.sh /scripts/run.sh -RUN mkdir /docker-entrypoint-initdb.d && \ - mkdir /scripts/pre-exec.d && \ - mkdir /scripts/pre-init.d && \ - chmod -R 755 /scripts - -EXPOSE 3306 - -VOLUME ["/var/lib/mysql"] - -ENTRYPOINT ["/scripts/run.sh"] +# Original author : https://github.com/yobasystems/alpine-mariadb.git +FROM alpine:latest + +ARG BUILD_DATE +ARG VCS_REF + +RUN apk add --no-cache mariadb mysql-client mariadb-server-utils pwgen && \ + rm -f /var/cache/apk/* + +RUN mkdir /schemas +COPY schemas /schemas + +ADD scripts/run.sh /scripts/run.sh +RUN mkdir /docker-entrypoint-initdb.d && \ + mkdir /scripts/pre-exec.d && \ + mkdir /scripts/pre-init.d && \ + chmod -R 755 /scripts + +EXPOSE 3306 + +VOLUME ["/var/lib/mysql"] + +ENTRYPOINT ["/scripts/run.sh"]