Compare commits

...

4 Commits

21 changed files with 839 additions and 528 deletions

2
.env Normal file
View File

@ -0,0 +1,2 @@
REDIS_PASSWORD=ELdhsgqJt5QZUSWKU5vY3D9CXa1a0teIceeHqvCtoPkrDJ0Lge7XIe8187gFjd0qZLv9zwhGr62MqY
HYDRA_PASSWORD=CHANGE-ME-INSECURE-PASSWORD

View File

@ -0,0 +1,30 @@
# ---------- Build Stage ----------
FROM golang:1.24 AS builder
# Set working directory
WORKDIR /app
# Copy Go module files and download dependencies
COPY go.mod go.sum ./
RUN go mod download
# Copy source code
COPY . .
# Build the Go binary
RUN CGO_ENABLED=0 GOOS=linux go build -o main ./cmd/api/main.go
# ---------- Final Image ----------
FROM alpine:latest
# Set working directory in final image
WORKDIR /app
# Copy only the binary from builder
COPY --from=builder /app/main .
# Expose the port your app listens on
EXPOSE 8080
# Set default command
CMD ["./main"]

169
api/auth/api.yaml Normal file
View File

@ -0,0 +1,169 @@
openapi: 3.0.0
info:
title: Authentication API
version: 1.0.0
servers:
- url: https://id.logidex.ru/api/auth
paths:
/auth/otp/request:
post:
tags:
- auth
summary: Request OTP
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RequestOTPRequest'
responses:
'200':
description: OTP requested successfully
content:
application/json:
schema:
$ref: '#/components/schemas/RequestOTPResponse'
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/RequestOTPResponse'
/auth/otp/verify:
post:
tags:
- auth
summary: Verify OTP
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/VerifyOTPRequest'
responses:
'200':
description: OTP verified successfully
content:
application/json:
schema:
$ref: '#/components/schemas/VerifyOTPResponse'
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/VerifyOTPResponse'
/auth/consent/accept:
post:
tags:
- auth
summary: Accept consent
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/AcceptConsentRequest'
responses:
'200':
description: Consent accepted successfully
content:
application/json:
schema:
$ref: '#/components/schemas/AcceptConsentResponse'
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/AcceptConsentResponse'
components:
schemas:
RequestOTPRequest:
type: object
properties:
phone_number:
type: string
description: Phone number to send OTP to
example: "+79999999999"
maxLength: 15
required:
- phone_number
RequestOTPResponse:
type: object
properties:
message:
type: string
description: Confirmation message
example: "OTP sent successfully"
ok:
type: boolean
description: Status of the request
example: true
required:
- message
- ok
VerifyOTPRequest:
type: object
properties:
phone_number:
type: string
description: Phone number to verify OTP for
example: "+79999999999"
maxLength: 15
otp:
type: string
description: One-time password to verify
example: "123456"
maxLength: 6
login_challenge:
type: string
description: Login challenge for verification
example: "challenge123"
required:
- phone_number
- otp
- login_challenge
VerifyOTPResponse:
type: object
properties:
redirect_url:
type: string
description: URL to redirect to after successful verification
example: "https://example.com/redirect"
ok:
type: boolean
description: Status of the verification
example: true
required:
- redirect_url
- ok
AcceptConsentRequest:
type: object
properties:
consent_challenge:
type: string
description: The consent challenge to accept
example: "challenge123"
required:
- consent_challenge
AcceptConsentResponse:
type: object
properties:
redirect_url:
type: string
description: URL to redirect to after accepting consent
example: "https://example.com/consent-accepted"
ok:
type: boolean
description: Status of the consent acceptance
example: true
message:
type: string
example: "Consent accepted"
required:
- message
- ok
- redirect_url

6
api/auth/cfg.yaml Normal file
View File

@ -0,0 +1,6 @@
package: handler
generate:
fiber-server: true
strict-server: true
models: true
output: gen.go

View File

@ -1,47 +1,28 @@
package main
import (
"context"
"fmt"
todo_api "git.logidex.ru/fakz9/logidex-id/internal/api/todo/handler"
user_api "git.logidex.ru/fakz9/logidex-id/internal/api/user/handler"
authApi "git.logidex.ru/fakz9/logidex-id/internal/api/auth/handler"
"git.logidex.ru/fakz9/logidex-id/internal/config"
"git.logidex.ru/fakz9/logidex-id/internal/hydra_client"
"git.logidex.ru/fakz9/logidex-id/internal/redis"
"github.com/gofiber/fiber/v2"
"github.com/ory/hydra-client-go"
"strconv"
)
func main() {
loginChallange := "-MLI2zCD8VLsZ6CIGHBKGtV0YCnVw1ipQnciX6UUsMvlWoDRu4S6V8d-in9hbUb_Nvc8vg8L7YnVBRhort90-eB0La4q1xhatcJUdlAsCW1le21WsOp63urZwRGdbk0yY6O5kD0AXO_U-asXWCNVkyVGUXmOkjf40hFeztO7XBfU8GRQkBb9ZTbBjjoFUWUgFYtYuYvp2Jbb754ZEC5zmbxq3s4oXLDgJJrUGsEza4tQ9Tj3JrVyf86x1ATZ3KnSfpWfyttQiz7P_yyQDjF4Cc3QseFYFScjhTopjteg0rmleXcnqYGIKQWXzCQwb8uJdAnIIe_Yo3yhHb_dRjFNEuLVUW7FFzQMwsVK3UscW-PDoxme0gYUqIIhDx-mpscBBiBzFKFHtbq9WvN5SrzGegUWWEIxrpJCtMh-bRSMuckU2BuxTY70BTvAxDsBlvFmSy7mhe-WgY2f5GJjy1GpbGwk0A8rXO8kaxnqjZvNnDwPqjUvlkkZwqr2Y3Pz2UsIalulM33lzem5CMUr8bZhblRrKiRpPFlHfiCbQr6huwFco18upmcPRzByt2fyXqhFjRbPqgd-x_HFBgiCwVcqxPFB1Kawcl45HiRWPvoy6uqZ16C8kHWGdOhTd2mL8tJCVx2EO_dXCh0GLhzNN_f29oTig-mM-Vn_ONozJcM7tHQvnXaNa1U5zccGXF5essmmOp-c8Eeu7N6HwH8rhufrbfro87L3qD5JFNFcTnhq8oTAKqGk7nl17lqKVfN-6Fh8pIvfl1mBYNmwXySGisCF1RyPJa2MHSi-NS6GbiwRSMltqumjrgnZFG81G_typRa7EAyX2Hla6VSCzw_gQY-McICJSXg8kdf6nDXIvYHZVRT4Kc096KRLDwKbssvN7MEZVEfuil0TpmSfSS_tbmowmojCq727E08BYH65kHXTLN9vJUJfvqflAXND2slYrob4njkuu4aJhjV-MjqAydGOEPhf20kzGnyDsMebIppYVh5KZ7pxM2LQvVb4Ey5J6b_gp-wzWgQhc6w4EFtFMeu23wKjj4-PxtLqWWRN5K4KZeQXP8UNCEkDCNd7JPd2ecrBBt0rsQDGsgE9XfQ6_eod-Bq6_FwKM9Xguql45-gsi-tWfApvuCCHmbWBT64rQOdxTuGMMHUW"
cfg := client.NewConfiguration()
cfg.AddDefaultHeader("X-Secret", "CHANGE-ME-INSECURE-PASSWORD")
cfg.Servers = []client.ServerConfiguration{
{
URL: "http://oauth2.logidex.ru/admin",
},
}
cl := client.NewAPIClient(cfg)
ctx := context.Background()
//cl.PublicApi.Oauth2Token(ctx).Code()
req := client.AcceptConsentRequest{}
req.SetGrantScope([]string{"openid"})
//req := client.AcceptLoginRequest{}
//req.SetSubject("someuser")
//req.SetRemember(true)
//req.SetRememberFor(3600)
//rsp, _, err := cl.AdminApi.AcceptLoginRequest(ctx).LoginChallenge(loginChallange).AcceptLoginRequest(req).Execute()
rsp, _, err := cl.AdminApi.AcceptConsentRequest(ctx).ConsentChallenge(loginChallange).AcceptConsentRequest(req).Execute()
config.Init()
err := redis.Init()
if err != nil {
fmt.Println(err)
return
panic(err)
}
fmt.Println(rsp.RedirectTo)
return
hydra_client.InitClient()
app := fiber.New()
api := app.Group("/api")
authApi.RegisterApp(api)
todo_api.RegisterApp(app)
user_api.RegisterApp(app)
app.Listen(":8080")
fmt.Println("test")
err = app.Listen(":" + strconv.Itoa(config.Cfg.App.Port))
if err != nil {
panic(err)
}
}

10
config.yaml Normal file
View File

@ -0,0 +1,10 @@
app:
port: 8080
redis:
host: localhost
port: 6379
db: 0
hydra:
host: https://oauth2.logidex.ru/admin

View File

@ -1,3 +0,0 @@
package LogDex_ID
//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen -config cfg.yaml api.yaml

10
go.mod
View File

@ -13,10 +13,12 @@ require (
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fatih/structtag v1.2.0 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/getkin/kin-openapi v0.132.0 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-sql-driver/mysql v1.9.2 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/gofiber/fiber/v2 v2.52.9 // indirect
github.com/google/cel-go v0.24.1 // indirect
github.com/google/uuid v1.6.0 // indirect
@ -40,22 +42,30 @@ require (
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect
github.com/ory/hydra-client-go v1.11.8 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/perimeterx/marshmallow v1.1.5 // indirect
github.com/pganalyze/pg_query_go/v6 v6.1.0 // indirect
github.com/pingcap/errors v0.11.5-0.20240311024730-e056997136bb // indirect
github.com/pingcap/failpoint v0.0.0-20240528011301-b51a646c7c86 // indirect
github.com/pingcap/log v1.1.0 // indirect
github.com/pingcap/tidb/pkg/parser v0.0.0-20250324122243-d51e00e5bbf0 // indirect
github.com/redis/rueidis v1.0.63 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/riza-io/grpc-go v0.2.0 // indirect
github.com/sagikazarmark/locafero v0.7.0 // indirect
github.com/samber/lo v1.51.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/speakeasy-api/jsonpath v0.6.0 // indirect
github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect
github.com/spf13/afero v1.12.0 // indirect
github.com/spf13/cast v1.7.1 // indirect
github.com/spf13/cobra v1.9.1 // indirect
github.com/spf13/pflag v1.0.6 // indirect
github.com/spf13/viper v1.20.1 // indirect
github.com/sqlc-dev/sqlc v1.29.0 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/tetratelabs/wazero v1.9.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.51.0 // indirect

20
go.sum
View File

@ -71,6 +71,8 @@ github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/getkin/kin-openapi v0.132.0 h1:3ISeLMsQzcb5v26yeJrBcdTCEQTag36ZjaGk7MIRUwk=
github.com/getkin/kin-openapi v0.132.0/go.mod h1:3OlG51PCYNsPByuiMB0t4fjnNlIDnaEDsjiKUV8nL58=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@ -83,6 +85,8 @@ github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ
github.com/go-sql-driver/mysql v1.9.2 h1:4cNKDYQ1I84SXslGddlsrMhc8k4LeDVj6Ad6WRjiHuU=
github.com/go-sql-driver/mysql v1.9.2/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/gofiber/fiber/v2 v2.52.9 h1:YjKl5DOiyP3j0mO61u3NTmK7or8GzzWzCFzkboyP5cw=
github.com/gofiber/fiber/v2 v2.52.9/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@ -203,6 +207,8 @@ github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAl
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
github.com/ory/hydra-client-go v1.11.8 h1:GwJjvH/DBcfYzoST4vUpi4pIRzDGH5oODKpIVuhwVyc=
github.com/ory/hydra-client-go v1.11.8/go.mod h1:4YuBuwUEC4yiyDrnKjGYc1tB3gUXan4ZiUYMjXJbfxA=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=
github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
github.com/pganalyze/pg_query_go/v6 v6.1.0 h1:jG5ZLhcVgL1FAw4C/0VNQaVmX1SUJx71wBGdtTtBvls=
@ -219,6 +225,8 @@ github.com/pingcap/tidb/pkg/parser v0.0.0-20250324122243-d51e00e5bbf0/go.mod h1:
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/redis/rueidis v1.0.63 h1:zSt5focn0YgrgBAE5NcnAibyKf3ZKyv+eCQHk62jEFk=
github.com/redis/rueidis v1.0.63/go.mod h1:Lkhr2QTgcoYBhxARU7kJRO8SyVlgUuEkcJO1Y8MCluA=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
@ -227,17 +235,27 @@ github.com/riza-io/grpc-go v0.2.0 h1:2HxQKFVE7VuYstcJ8zqpN84VnAoJ4dCL6YFhJewNcHQ
github.com/riza-io/grpc-go v0.2.0/go.mod h1:2bDvR9KkKC3KhtlSHfR3dAXjUMT86kg4UfWFyVGWqi8=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo=
github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k=
github.com/samber/lo v1.51.0 h1:kysRYLbHy/MB7kQZf5DSN50JHmMsNEdeY24VzJFu7wI=
github.com/samber/lo v1.51.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8=
github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw=
github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU=
github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg=
github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=
github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
github.com/sqlc-dev/sqlc v1.29.0 h1:HQctoD7y/i29Bao53qXO7CZ/BV9NcvpGpsJWvz9nKWs=
github.com/sqlc-dev/sqlc v1.29.0/go.mod h1:BavmYw11px5AdPOjAVHmb9fctP5A8GTziC38wBF9tp0=
@ -248,6 +266,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=

View File

@ -0,0 +1,337 @@
// Package handler provides primitives to interact with the openapi HTTP API.
//
// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.5.0 DO NOT EDIT.
package handler
import (
"context"
"fmt"
"github.com/gofiber/fiber/v2"
)
// AcceptConsentRequest defines model for AcceptConsentRequest.
type AcceptConsentRequest struct {
// ConsentChallenge The consent challenge to accept
ConsentChallenge string `json:"consent_challenge"`
}
// AcceptConsentResponse defines model for AcceptConsentResponse.
type AcceptConsentResponse struct {
Message string `json:"message"`
// Ok Status of the consent acceptance
Ok bool `json:"ok"`
// RedirectUrl URL to redirect to after accepting consent
RedirectUrl string `json:"redirect_url"`
}
// RequestOTPRequest defines model for RequestOTPRequest.
type RequestOTPRequest struct {
// PhoneNumber Phone number to send OTP to
PhoneNumber string `json:"phone_number"`
}
// RequestOTPResponse defines model for RequestOTPResponse.
type RequestOTPResponse struct {
// Message Confirmation message
Message string `json:"message"`
// Ok Status of the request
Ok bool `json:"ok"`
}
// VerifyOTPRequest defines model for VerifyOTPRequest.
type VerifyOTPRequest struct {
// LoginChallenge Login challenge for verification
LoginChallenge string `json:"login_challenge"`
// Otp One-time password to verify
Otp string `json:"otp"`
// PhoneNumber Phone number to verify OTP for
PhoneNumber string `json:"phone_number"`
}
// VerifyOTPResponse defines model for VerifyOTPResponse.
type VerifyOTPResponse struct {
// Ok Status of the verification
Ok bool `json:"ok"`
// RedirectUrl URL to redirect to after successful verification
RedirectUrl string `json:"redirect_url"`
}
// PostAuthConsentAcceptJSONRequestBody defines body for PostAuthConsentAccept for application/json ContentType.
type PostAuthConsentAcceptJSONRequestBody = AcceptConsentRequest
// PostAuthOtpRequestJSONRequestBody defines body for PostAuthOtpRequest for application/json ContentType.
type PostAuthOtpRequestJSONRequestBody = RequestOTPRequest
// PostAuthOtpVerifyJSONRequestBody defines body for PostAuthOtpVerify for application/json ContentType.
type PostAuthOtpVerifyJSONRequestBody = VerifyOTPRequest
// ServerInterface represents all server handlers.
type ServerInterface interface {
// Accept consent
// (POST /auth/consent/accept)
PostAuthConsentAccept(c *fiber.Ctx) error
// Request OTP
// (POST /auth/otp/request)
PostAuthOtpRequest(c *fiber.Ctx) error
// Verify OTP
// (POST /auth/otp/verify)
PostAuthOtpVerify(c *fiber.Ctx) error
}
// ServerInterfaceWrapper converts contexts to parameters.
type ServerInterfaceWrapper struct {
Handler ServerInterface
}
type MiddlewareFunc fiber.Handler
// PostAuthConsentAccept operation middleware
func (siw *ServerInterfaceWrapper) PostAuthConsentAccept(c *fiber.Ctx) error {
return siw.Handler.PostAuthConsentAccept(c)
}
// PostAuthOtpRequest operation middleware
func (siw *ServerInterfaceWrapper) PostAuthOtpRequest(c *fiber.Ctx) error {
return siw.Handler.PostAuthOtpRequest(c)
}
// PostAuthOtpVerify operation middleware
func (siw *ServerInterfaceWrapper) PostAuthOtpVerify(c *fiber.Ctx) error {
return siw.Handler.PostAuthOtpVerify(c)
}
// FiberServerOptions provides options for the Fiber server.
type FiberServerOptions struct {
BaseURL string
Middlewares []MiddlewareFunc
}
// RegisterHandlers creates http.Handler with routing matching OpenAPI spec.
func RegisterHandlers(router fiber.Router, si ServerInterface) {
RegisterHandlersWithOptions(router, si, FiberServerOptions{})
}
// RegisterHandlersWithOptions creates http.Handler with additional options
func RegisterHandlersWithOptions(router fiber.Router, si ServerInterface, options FiberServerOptions) {
wrapper := ServerInterfaceWrapper{
Handler: si,
}
for _, m := range options.Middlewares {
router.Use(fiber.Handler(m))
}
router.Post(options.BaseURL+"/auth/consent/accept", wrapper.PostAuthConsentAccept)
router.Post(options.BaseURL+"/auth/otp/request", wrapper.PostAuthOtpRequest)
router.Post(options.BaseURL+"/auth/otp/verify", wrapper.PostAuthOtpVerify)
}
type PostAuthConsentAcceptRequestObject struct {
Body *PostAuthConsentAcceptJSONRequestBody
}
type PostAuthConsentAcceptResponseObject interface {
VisitPostAuthConsentAcceptResponse(ctx *fiber.Ctx) error
}
type PostAuthConsentAccept200JSONResponse AcceptConsentResponse
func (response PostAuthConsentAccept200JSONResponse) VisitPostAuthConsentAcceptResponse(ctx *fiber.Ctx) error {
ctx.Response().Header.Set("Content-Type", "application/json")
ctx.Status(200)
return ctx.JSON(&response)
}
type PostAuthConsentAccept400JSONResponse AcceptConsentResponse
func (response PostAuthConsentAccept400JSONResponse) VisitPostAuthConsentAcceptResponse(ctx *fiber.Ctx) error {
ctx.Response().Header.Set("Content-Type", "application/json")
ctx.Status(400)
return ctx.JSON(&response)
}
type PostAuthOtpRequestRequestObject struct {
Body *PostAuthOtpRequestJSONRequestBody
}
type PostAuthOtpRequestResponseObject interface {
VisitPostAuthOtpRequestResponse(ctx *fiber.Ctx) error
}
type PostAuthOtpRequest200JSONResponse RequestOTPResponse
func (response PostAuthOtpRequest200JSONResponse) VisitPostAuthOtpRequestResponse(ctx *fiber.Ctx) error {
ctx.Response().Header.Set("Content-Type", "application/json")
ctx.Status(200)
return ctx.JSON(&response)
}
type PostAuthOtpRequest400JSONResponse RequestOTPResponse
func (response PostAuthOtpRequest400JSONResponse) VisitPostAuthOtpRequestResponse(ctx *fiber.Ctx) error {
ctx.Response().Header.Set("Content-Type", "application/json")
ctx.Status(400)
return ctx.JSON(&response)
}
type PostAuthOtpVerifyRequestObject struct {
Body *PostAuthOtpVerifyJSONRequestBody
}
type PostAuthOtpVerifyResponseObject interface {
VisitPostAuthOtpVerifyResponse(ctx *fiber.Ctx) error
}
type PostAuthOtpVerify200JSONResponse VerifyOTPResponse
func (response PostAuthOtpVerify200JSONResponse) VisitPostAuthOtpVerifyResponse(ctx *fiber.Ctx) error {
ctx.Response().Header.Set("Content-Type", "application/json")
ctx.Status(200)
return ctx.JSON(&response)
}
type PostAuthOtpVerify400JSONResponse VerifyOTPResponse
func (response PostAuthOtpVerify400JSONResponse) VisitPostAuthOtpVerifyResponse(ctx *fiber.Ctx) error {
ctx.Response().Header.Set("Content-Type", "application/json")
ctx.Status(400)
return ctx.JSON(&response)
}
// StrictServerInterface represents all server handlers.
type StrictServerInterface interface {
// Accept consent
// (POST /auth/consent/accept)
PostAuthConsentAccept(ctx context.Context, request PostAuthConsentAcceptRequestObject) (PostAuthConsentAcceptResponseObject, error)
// Request OTP
// (POST /auth/otp/request)
PostAuthOtpRequest(ctx context.Context, request PostAuthOtpRequestRequestObject) (PostAuthOtpRequestResponseObject, error)
// Verify OTP
// (POST /auth/otp/verify)
PostAuthOtpVerify(ctx context.Context, request PostAuthOtpVerifyRequestObject) (PostAuthOtpVerifyResponseObject, error)
}
type StrictHandlerFunc func(ctx *fiber.Ctx, args interface{}) (interface{}, error)
type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc
func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface {
return &strictHandler{ssi: ssi, middlewares: middlewares}
}
type strictHandler struct {
ssi StrictServerInterface
middlewares []StrictMiddlewareFunc
}
// PostAuthConsentAccept operation middleware
func (sh *strictHandler) PostAuthConsentAccept(ctx *fiber.Ctx) error {
var request PostAuthConsentAcceptRequestObject
var body PostAuthConsentAcceptJSONRequestBody
if err := ctx.BodyParser(&body); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
request.Body = &body
handler := func(ctx *fiber.Ctx, request interface{}) (interface{}, error) {
return sh.ssi.PostAuthConsentAccept(ctx.UserContext(), request.(PostAuthConsentAcceptRequestObject))
}
for _, middleware := range sh.middlewares {
handler = middleware(handler, "PostAuthConsentAccept")
}
response, err := handler(ctx, request)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
} else if validResponse, ok := response.(PostAuthConsentAcceptResponseObject); ok {
if err := validResponse.VisitPostAuthConsentAcceptResponse(ctx); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
} else if response != nil {
return fmt.Errorf("unexpected response type: %T", response)
}
return nil
}
// PostAuthOtpRequest operation middleware
func (sh *strictHandler) PostAuthOtpRequest(ctx *fiber.Ctx) error {
var request PostAuthOtpRequestRequestObject
var body PostAuthOtpRequestJSONRequestBody
if err := ctx.BodyParser(&body); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
request.Body = &body
handler := func(ctx *fiber.Ctx, request interface{}) (interface{}, error) {
return sh.ssi.PostAuthOtpRequest(ctx.UserContext(), request.(PostAuthOtpRequestRequestObject))
}
for _, middleware := range sh.middlewares {
handler = middleware(handler, "PostAuthOtpRequest")
}
response, err := handler(ctx, request)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
} else if validResponse, ok := response.(PostAuthOtpRequestResponseObject); ok {
if err := validResponse.VisitPostAuthOtpRequestResponse(ctx); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
} else if response != nil {
return fmt.Errorf("unexpected response type: %T", response)
}
return nil
}
// PostAuthOtpVerify operation middleware
func (sh *strictHandler) PostAuthOtpVerify(ctx *fiber.Ctx) error {
var request PostAuthOtpVerifyRequestObject
var body PostAuthOtpVerifyJSONRequestBody
if err := ctx.BodyParser(&body); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
request.Body = &body
handler := func(ctx *fiber.Ctx, request interface{}) (interface{}, error) {
return sh.ssi.PostAuthOtpVerify(ctx.UserContext(), request.(PostAuthOtpVerifyRequestObject))
}
for _, middleware := range sh.middlewares {
handler = middleware(handler, "PostAuthOtpVerify")
}
response, err := handler(ctx, request)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
} else if validResponse, ok := response.(PostAuthOtpVerifyResponseObject); ok {
if err := validResponse.VisitPostAuthOtpVerifyResponse(ctx); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
} else if response != nil {
return fmt.Errorf("unexpected response type: %T", response)
}
return nil
}

View File

@ -0,0 +1,3 @@
package handler
//go:generate go tool oapi-codegen -config ../../../../api/auth/cfg.yaml ../../../../api/auth/api.yaml

View File

@ -0,0 +1,114 @@
package handler
import (
"context"
"fmt"
"git.logidex.ru/fakz9/logidex-id/internal/hydra_client"
"git.logidex.ru/fakz9/logidex-id/internal/redis"
"github.com/gofiber/fiber/v2"
hydraApi "github.com/ory/hydra-client-go"
)
type AuthHandler struct{}
func (a AuthHandler) PostAuthConsentAccept(ctx context.Context, request PostAuthConsentAcceptRequestObject) (PostAuthConsentAcceptResponseObject, error) {
hydraClient := hydra_client.GetClient()
hydraRequest := hydraApi.AcceptConsentRequest{}
hydraRequest.SetGrantScope([]string{"openid"})
hydraRequest.SetRemember(true)
hydraRequest.SetRememberFor(3600) // 1 hour
hydraResponse, r, err := hydraClient.AdminApi.
AcceptConsentRequest(ctx).
ConsentChallenge(request.Body.ConsentChallenge).
AcceptConsentRequest(hydraRequest).
Execute()
if err != nil {
return PostAuthConsentAccept400JSONResponse{
RedirectUrl: "",
Ok: false,
Message: "Failed to accept consent request",
}, nil
}
fmt.Println(r)
return PostAuthConsentAccept200JSONResponse{
RedirectUrl: hydraResponse.RedirectTo,
Ok: true,
Message: "Успешно",
}, nil
}
func (a AuthHandler) PostAuthOtpRequest(ctx context.Context, request PostAuthOtpRequestRequestObject) (PostAuthOtpRequestResponseObject, error) {
redisClient := redis.GetClient()
// TODO implement OTP request logic
err := redisClient.Do(ctx, redisClient.B().Set().Key("otp:"+request.Body.PhoneNumber).Value("123456").Build()).Error()
if err != nil {
return PostAuthOtpRequest400JSONResponse{
Message: "Failed to set OTP in Redis",
Ok: false,
}, nil
}
return PostAuthOtpRequest200JSONResponse{
Message: "Код успешно отправлен",
Ok: true,
}, nil
}
func (a AuthHandler) PostAuthOtpVerify(ctx context.Context, request PostAuthOtpVerifyRequestObject) (PostAuthOtpVerifyResponseObject, error) {
redisClient := redis.GetClient()
hydraClient := hydra_client.GetClient()
sentOtp, err := redisClient.Do(ctx, redisClient.B().Get().Key("otp:"+request.Body.PhoneNumber).Build()).ToString()
if err != nil {
return PostAuthOtpVerify400JSONResponse{
RedirectUrl: "",
Ok: false,
}, nil
}
if sentOtp != request.Body.Otp {
return PostAuthOtpVerify400JSONResponse{
RedirectUrl: "",
Ok: false,
}, nil
}
hydraRequest := hydraApi.AcceptLoginRequest{}
// TODO read user from database by phone number
hydraRequest.SetSubject("some-user-id") // Replace with actual user ID
hydraRequest.SetRemember(true)
hydraRequest.SetRememberFor(3600) // 1 hour
hydraResponse, r, err := hydraClient.AdminApi.
AcceptLoginRequest(ctx).
LoginChallenge(request.Body.LoginChallenge).
AcceptLoginRequest(hydraRequest).
Execute()
fmt.Println(r)
if err != nil {
return PostAuthOtpVerify400JSONResponse{
RedirectUrl: "",
Ok: false,
}, nil
}
return PostAuthOtpVerify200JSONResponse{
RedirectUrl: hydraResponse.RedirectTo,
Ok: true,
}, nil
}
var _ StrictServerInterface = (*AuthHandler)(nil)
func NewAuthHandler() *AuthHandler {
return &AuthHandler{}
}
func RegisterApp(router fiber.Router) {
//authGroup := router.Group("/auth")
server := NewStrictHandler(NewAuthHandler(), nil)
RegisterHandlers(router, server)
}

View File

@ -1,441 +0,0 @@
// Package handler provides primitives to interact with the openapi HTTP API.
//
// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.5.0 DO NOT EDIT.
package handler
import (
"context"
"fmt"
"github.com/gofiber/fiber/v2"
"github.com/oapi-codegen/runtime"
)
// Todo defines model for Todo.
type Todo struct {
Completed bool `json:"completed"`
Description *string `json:"description,omitempty"`
Id string `json:"id"`
Title string `json:"title"`
}
// TodoCreate defines model for TodoCreate.
type TodoCreate struct {
Description *string `json:"description,omitempty"`
Title string `json:"title"`
}
// TodoUpdate defines model for TodoUpdate.
type TodoUpdate struct {
Completed *bool `json:"completed,omitempty"`
Description *string `json:"description,omitempty"`
Title *string `json:"title,omitempty"`
}
// PostTodosJSONRequestBody defines body for PostTodos for application/json ContentType.
type PostTodosJSONRequestBody = TodoCreate
// PutTodosTodoIdJSONRequestBody defines body for PutTodosTodoId for application/json ContentType.
type PutTodosTodoIdJSONRequestBody = TodoUpdate
// ServerInterface represents all server handlers.
type ServerInterface interface {
// Get all todos
// (GET /todos)
GetTodos(c *fiber.Ctx) error
// Create a new todo
// (POST /todos)
PostTodos(c *fiber.Ctx) error
// Delete a todo by ID
// (DELETE /todos/{todoId})
DeleteTodosTodoId(c *fiber.Ctx, todoId string) error
// Get a todo by ID
// (GET /todos/{todoId})
GetTodosTodoId(c *fiber.Ctx, todoId string) error
// Update a todo by ID
// (PUT /todos/{todoId})
PutTodosTodoId(c *fiber.Ctx, todoId string) error
}
// ServerInterfaceWrapper converts contexts to parameters.
type ServerInterfaceWrapper struct {
Handler ServerInterface
}
type MiddlewareFunc fiber.Handler
// GetTodos operation middleware
func (siw *ServerInterfaceWrapper) GetTodos(c *fiber.Ctx) error {
return siw.Handler.GetTodos(c)
}
// PostTodos operation middleware
func (siw *ServerInterfaceWrapper) PostTodos(c *fiber.Ctx) error {
return siw.Handler.PostTodos(c)
}
// DeleteTodosTodoId operation middleware
func (siw *ServerInterfaceWrapper) DeleteTodosTodoId(c *fiber.Ctx) error {
var err error
// ------------- Path parameter "todoId" -------------
var todoId string
err = runtime.BindStyledParameterWithOptions("simple", "todoId", c.Params("todoId"), &todoId, runtime.BindStyledParameterOptions{Explode: false, Required: true})
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter todoId: %w", err).Error())
}
return siw.Handler.DeleteTodosTodoId(c, todoId)
}
// GetTodosTodoId operation middleware
func (siw *ServerInterfaceWrapper) GetTodosTodoId(c *fiber.Ctx) error {
var err error
// ------------- Path parameter "todoId" -------------
var todoId string
err = runtime.BindStyledParameterWithOptions("simple", "todoId", c.Params("todoId"), &todoId, runtime.BindStyledParameterOptions{Explode: false, Required: true})
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter todoId: %w", err).Error())
}
return siw.Handler.GetTodosTodoId(c, todoId)
}
// PutTodosTodoId operation middleware
func (siw *ServerInterfaceWrapper) PutTodosTodoId(c *fiber.Ctx) error {
var err error
// ------------- Path parameter "todoId" -------------
var todoId string
err = runtime.BindStyledParameterWithOptions("simple", "todoId", c.Params("todoId"), &todoId, runtime.BindStyledParameterOptions{Explode: false, Required: true})
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter todoId: %w", err).Error())
}
return siw.Handler.PutTodosTodoId(c, todoId)
}
// FiberServerOptions provides options for the Fiber server.
type FiberServerOptions struct {
BaseURL string
Middlewares []MiddlewareFunc
}
// RegisterHandlers creates http.Handler with routing matching OpenAPI spec.
func RegisterHandlers(router fiber.Router, si ServerInterface) {
RegisterHandlersWithOptions(router, si, FiberServerOptions{})
}
// RegisterHandlersWithOptions creates http.Handler with additional options
func RegisterHandlersWithOptions(router fiber.Router, si ServerInterface, options FiberServerOptions) {
wrapper := ServerInterfaceWrapper{
Handler: si,
}
for _, m := range options.Middlewares {
router.Use(fiber.Handler(m))
}
router.Get(options.BaseURL+"/todos", wrapper.GetTodos)
router.Post(options.BaseURL+"/todos", wrapper.PostTodos)
router.Delete(options.BaseURL+"/todos/:todoId", wrapper.DeleteTodosTodoId)
router.Get(options.BaseURL+"/todos/:todoId", wrapper.GetTodosTodoId)
router.Put(options.BaseURL+"/todos/:todoId", wrapper.PutTodosTodoId)
}
type GetTodosRequestObject struct {
}
type GetTodosResponseObject interface {
VisitGetTodosResponse(ctx *fiber.Ctx) error
}
type GetTodos200JSONResponse []Todo
func (response GetTodos200JSONResponse) VisitGetTodosResponse(ctx *fiber.Ctx) error {
ctx.Response().Header.Set("Content-Type", "application/json")
ctx.Status(200)
return ctx.JSON(&response)
}
type PostTodosRequestObject struct {
Body *PostTodosJSONRequestBody
}
type PostTodosResponseObject interface {
VisitPostTodosResponse(ctx *fiber.Ctx) error
}
type PostTodos201JSONResponse Todo
func (response PostTodos201JSONResponse) VisitPostTodosResponse(ctx *fiber.Ctx) error {
ctx.Response().Header.Set("Content-Type", "application/json")
ctx.Status(201)
return ctx.JSON(&response)
}
type DeleteTodosTodoIdRequestObject struct {
TodoId string `json:"todoId"`
}
type DeleteTodosTodoIdResponseObject interface {
VisitDeleteTodosTodoIdResponse(ctx *fiber.Ctx) error
}
type DeleteTodosTodoId204Response struct {
}
func (response DeleteTodosTodoId204Response) VisitDeleteTodosTodoIdResponse(ctx *fiber.Ctx) error {
ctx.Status(204)
return nil
}
type DeleteTodosTodoId404Response struct {
}
func (response DeleteTodosTodoId404Response) VisitDeleteTodosTodoIdResponse(ctx *fiber.Ctx) error {
ctx.Status(404)
return nil
}
type GetTodosTodoIdRequestObject struct {
TodoId string `json:"todoId"`
}
type GetTodosTodoIdResponseObject interface {
VisitGetTodosTodoIdResponse(ctx *fiber.Ctx) error
}
type GetTodosTodoId200JSONResponse Todo
func (response GetTodosTodoId200JSONResponse) VisitGetTodosTodoIdResponse(ctx *fiber.Ctx) error {
ctx.Response().Header.Set("Content-Type", "application/json")
ctx.Status(200)
return ctx.JSON(&response)
}
type GetTodosTodoId404Response struct {
}
func (response GetTodosTodoId404Response) VisitGetTodosTodoIdResponse(ctx *fiber.Ctx) error {
ctx.Status(404)
return nil
}
type PutTodosTodoIdRequestObject struct {
TodoId string `json:"todoId"`
Body *PutTodosTodoIdJSONRequestBody
}
type PutTodosTodoIdResponseObject interface {
VisitPutTodosTodoIdResponse(ctx *fiber.Ctx) error
}
type PutTodosTodoId200JSONResponse Todo
func (response PutTodosTodoId200JSONResponse) VisitPutTodosTodoIdResponse(ctx *fiber.Ctx) error {
ctx.Response().Header.Set("Content-Type", "application/json")
ctx.Status(200)
return ctx.JSON(&response)
}
type PutTodosTodoId404Response struct {
}
func (response PutTodosTodoId404Response) VisitPutTodosTodoIdResponse(ctx *fiber.Ctx) error {
ctx.Status(404)
return nil
}
// StrictServerInterface represents all server handlers.
type StrictServerInterface interface {
// Get all todos
// (GET /todos)
GetTodos(ctx context.Context, request GetTodosRequestObject) (GetTodosResponseObject, error)
// Create a new todo
// (POST /todos)
PostTodos(ctx context.Context, request PostTodosRequestObject) (PostTodosResponseObject, error)
// Delete a todo by ID
// (DELETE /todos/{todoId})
DeleteTodosTodoId(ctx context.Context, request DeleteTodosTodoIdRequestObject) (DeleteTodosTodoIdResponseObject, error)
// Get a todo by ID
// (GET /todos/{todoId})
GetTodosTodoId(ctx context.Context, request GetTodosTodoIdRequestObject) (GetTodosTodoIdResponseObject, error)
// Update a todo by ID
// (PUT /todos/{todoId})
PutTodosTodoId(ctx context.Context, request PutTodosTodoIdRequestObject) (PutTodosTodoIdResponseObject, error)
}
type StrictHandlerFunc func(ctx *fiber.Ctx, args interface{}) (interface{}, error)
type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc
func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface {
return &strictHandler{ssi: ssi, middlewares: middlewares}
}
type strictHandler struct {
ssi StrictServerInterface
middlewares []StrictMiddlewareFunc
}
// GetTodos operation middleware
func (sh *strictHandler) GetTodos(ctx *fiber.Ctx) error {
var request GetTodosRequestObject
handler := func(ctx *fiber.Ctx, request interface{}) (interface{}, error) {
return sh.ssi.GetTodos(ctx.UserContext(), request.(GetTodosRequestObject))
}
for _, middleware := range sh.middlewares {
handler = middleware(handler, "GetTodos")
}
response, err := handler(ctx, request)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
} else if validResponse, ok := response.(GetTodosResponseObject); ok {
if err := validResponse.VisitGetTodosResponse(ctx); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
} else if response != nil {
return fmt.Errorf("unexpected response type: %T", response)
}
return nil
}
// PostTodos operation middleware
func (sh *strictHandler) PostTodos(ctx *fiber.Ctx) error {
var request PostTodosRequestObject
var body PostTodosJSONRequestBody
if err := ctx.BodyParser(&body); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
request.Body = &body
handler := func(ctx *fiber.Ctx, request interface{}) (interface{}, error) {
return sh.ssi.PostTodos(ctx.UserContext(), request.(PostTodosRequestObject))
}
for _, middleware := range sh.middlewares {
handler = middleware(handler, "PostTodos")
}
response, err := handler(ctx, request)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
} else if validResponse, ok := response.(PostTodosResponseObject); ok {
if err := validResponse.VisitPostTodosResponse(ctx); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
} else if response != nil {
return fmt.Errorf("unexpected response type: %T", response)
}
return nil
}
// DeleteTodosTodoId operation middleware
func (sh *strictHandler) DeleteTodosTodoId(ctx *fiber.Ctx, todoId string) error {
var request DeleteTodosTodoIdRequestObject
request.TodoId = todoId
handler := func(ctx *fiber.Ctx, request interface{}) (interface{}, error) {
return sh.ssi.DeleteTodosTodoId(ctx.UserContext(), request.(DeleteTodosTodoIdRequestObject))
}
for _, middleware := range sh.middlewares {
handler = middleware(handler, "DeleteTodosTodoId")
}
response, err := handler(ctx, request)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
} else if validResponse, ok := response.(DeleteTodosTodoIdResponseObject); ok {
if err := validResponse.VisitDeleteTodosTodoIdResponse(ctx); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
} else if response != nil {
return fmt.Errorf("unexpected response type: %T", response)
}
return nil
}
// GetTodosTodoId operation middleware
func (sh *strictHandler) GetTodosTodoId(ctx *fiber.Ctx, todoId string) error {
var request GetTodosTodoIdRequestObject
request.TodoId = todoId
handler := func(ctx *fiber.Ctx, request interface{}) (interface{}, error) {
return sh.ssi.GetTodosTodoId(ctx.UserContext(), request.(GetTodosTodoIdRequestObject))
}
for _, middleware := range sh.middlewares {
handler = middleware(handler, "GetTodosTodoId")
}
response, err := handler(ctx, request)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
} else if validResponse, ok := response.(GetTodosTodoIdResponseObject); ok {
if err := validResponse.VisitGetTodosTodoIdResponse(ctx); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
} else if response != nil {
return fmt.Errorf("unexpected response type: %T", response)
}
return nil
}
// PutTodosTodoId operation middleware
func (sh *strictHandler) PutTodosTodoId(ctx *fiber.Ctx, todoId string) error {
var request PutTodosTodoIdRequestObject
request.TodoId = todoId
var body PutTodosTodoIdJSONRequestBody
if err := ctx.BodyParser(&body); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
request.Body = &body
handler := func(ctx *fiber.Ctx, request interface{}) (interface{}, error) {
return sh.ssi.PutTodosTodoId(ctx.UserContext(), request.(PutTodosTodoIdRequestObject))
}
for _, middleware := range sh.middlewares {
handler = middleware(handler, "PutTodosTodoId")
}
response, err := handler(ctx, request)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
} else if validResponse, ok := response.(PutTodosTodoIdResponseObject); ok {
if err := validResponse.VisitPutTodosTodoIdResponse(ctx); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
} else if response != nil {
return fmt.Errorf("unexpected response type: %T", response)
}
return nil
}

View File

@ -1,3 +0,0 @@
package handler
//go:generate go tool oapi-codegen -config ../../../../api/todo/cfg.yaml ../../../../api/todo/todo.yaml

View File

@ -1,46 +0,0 @@
package handler
import (
"context"
"github.com/gofiber/fiber/v2"
)
type TodoHandler struct {
}
var _ StrictServerInterface = (*TodoHandler)(nil)
func (t TodoHandler) GetTodos(ctx context.Context, request GetTodosRequestObject) (GetTodosResponseObject, error) {
//TODO implement me
panic("implement me")
}
func (t TodoHandler) PostTodos(ctx context.Context, request PostTodosRequestObject) (PostTodosResponseObject, error) {
//TODO implement me
panic("implement me")
}
func (t TodoHandler) DeleteTodosTodoId(ctx context.Context, request DeleteTodosTodoIdRequestObject) (DeleteTodosTodoIdResponseObject, error) {
//TODO implement me
panic("implement me")
}
func (t TodoHandler) GetTodosTodoId(ctx context.Context, request GetTodosTodoIdRequestObject) (GetTodosTodoIdResponseObject, error) {
//TODO implement me
panic("implement me")
}
func (t TodoHandler) PutTodosTodoId(ctx context.Context, request PutTodosTodoIdRequestObject) (PutTodosTodoIdResponseObject, error) {
//TODO implement me
panic("implement me")
}
func NewTodoHandler() *TodoHandler {
return &TodoHandler{}
}
func RegisterApp(router fiber.Router) {
server := NewStrictHandler(NewTodoHandler(), nil)
RegisterHandlers(router, server)
}

52
internal/config/config.go Normal file
View File

@ -0,0 +1,52 @@
package config
import (
"github.com/joho/godotenv"
"github.com/spf13/viper"
"log"
)
type Config struct {
App struct {
Port int
}
Redis struct {
Host string
Port int
DB int
Password string
}
Hydra struct {
Host string
Password string
}
}
var Cfg *Config
func Init() {
err := godotenv.Load()
if err != nil {
log.Println("Error loading .env file")
}
viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
err = viper.ReadInConfig()
if err != nil {
log.Fatalf("Error reading config file, %s", err)
}
viper.AutomaticEnv()
var config Config
_ = viper.BindEnv("redis.password", "REDIS_PASSWORD")
_ = viper.BindEnv("hydra.password", "HYDRA_PASSWORD")
err = viper.Unmarshal(&config)
if err != nil {
log.Fatalf("Unable to decode config into struct, %v", err)
}
Cfg = &config
}

View File

@ -0,0 +1,28 @@
package hydra_client
import (
"git.logidex.ru/fakz9/logidex-id/internal/config"
hydraApi "github.com/ory/hydra-client-go"
"sync"
)
var (
client *hydraApi.APIClient
initClient sync.Once
)
func InitClient() {
cfg := hydraApi.NewConfiguration()
cfg.AddDefaultHeader("X-Secret", config.Cfg.Hydra.Password)
cfg.Servers = []hydraApi.ServerConfiguration{
{
URL: config.Cfg.Hydra.Host,
},
}
client = hydraApi.NewAPIClient(cfg)
}
func GetClient() *hydraApi.APIClient {
initClient.Do(InitClient)
return client
}

26
internal/redis/client.go Normal file
View File

@ -0,0 +1,26 @@
package redis
import (
"git.logidex.ru/fakz9/logidex-id/internal/config"
"github.com/redis/rueidis"
"strconv"
)
var client rueidis.Client
func Init() error {
var err error
client, err = rueidis.NewClient(rueidis.ClientOption{
// Set the address of your Redis server
InitAddress: []string{config.Cfg.Redis.Host + ":" + strconv.Itoa(config.Cfg.Redis.Port)},
Password: config.Cfg.Redis.Password,
})
if err != nil {
return err
}
return nil
}
func GetClient() rueidis.Client {
return client
}

16
openapi.yaml Normal file
View File

@ -0,0 +1,16 @@
openapi: 3.0.0
info:
title: Logidex ID API
version: 1.0.0
paths:
$ref: './api/auth/api.yaml#/paths'
components:
schemas:
$ref: './api/auth/api.yaml#/components/schemas'
tags:
- name: auth
description: Authentication operations