initial commit, adding SQL connection and a simple testing on main
This commit is contained in:
29
app/go.mod
Normal file
29
app/go.mod
Normal file
@@ -0,0 +1,29 @@
|
||||
module cloud.etaviaporte.com/api
|
||||
|
||||
go 1.23.2
|
||||
|
||||
require (
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/spf13/viper v1.21.0
|
||||
gorm.io/driver/mysql v1.6.0
|
||||
gorm.io/gorm v1.31.1
|
||||
)
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||
github.com/spf13/afero v1.15.0 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
)
|
||||
61
app/go.sum
Normal file
61
app/go.sum
Normal file
@@ -0,0 +1,61 @@
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
|
||||
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/mysql v1.6.0 h1:eNbLmNTpPpTOVZi8MMxCi2aaIm0ZpInbORNXDwyLGvg=
|
||||
gorm.io/driver/mysql v1.6.0/go.mod h1:D/oCC2GWK3M/dqoLxnOlaNKmXz8WNTfcS9y5ovaSqKo=
|
||||
gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg=
|
||||
gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
|
||||
42
app/libs/database/db.go
Normal file
42
app/libs/database/db.go
Normal file
@@ -0,0 +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
|
||||
}
|
||||
124
app/libs/database/schemas/rbac/rbac.go
Normal file
124
app/libs/database/schemas/rbac/rbac.go
Normal file
@@ -0,0 +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" }
|
||||
34
app/main.go
Normal file
34
app/main.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
database "cloud.etaviaporte.com/api/libs/database"
|
||||
rbac "cloud.etaviaporte.com/api/libs/database/schemas/rbac"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var connection = database.Init()
|
||||
|
||||
// Prepare a variable to hold the fetched user record.
|
||||
// Replace rbac.User with the actual struct name if different.
|
||||
var user rbac.User
|
||||
|
||||
// Fetch the user whose primary key is 1.
|
||||
// GORM's First method, when given a numeric id as the second argument, queries by primary key.
|
||||
result := connection.First(&user, 1)
|
||||
|
||||
// result.Error holds any error from the DB operation (including "record not found").
|
||||
// result.RowsAffected tells how many rows were returned.
|
||||
if result.Error != nil {
|
||||
// Handle the error (could be gorm.ErrRecordNotFound or a DB/connection error).
|
||||
// For learning purposes we print the error and exit main.
|
||||
fmt.Printf("failed to fetch user with id=1: %v\n", result.Error)
|
||||
return
|
||||
}
|
||||
|
||||
// If no error, user now contains the row from the database.
|
||||
// Print the struct with field names and values to inspect the loaded data.
|
||||
fmt.Printf("User fetched: %+v\n", user)
|
||||
|
||||
}
|
||||
182
app/openapi.yaml
Normal file
182
app/openapi.yaml
Normal file
@@ -0,0 +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'
|
||||
Reference in New Issue
Block a user