Skip to content

Commit e05a6ad

Browse files
committed
refactor(core): 🚧 rewrite from chi to gin
1 parent c2a82f9 commit e05a6ad

31 files changed

+2360
-1410
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"config",
44
"api",
55
"test",
6-
"deps"
6+
"deps",
7+
"core"
78
]
89
}

api/openapi.yaml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ paths:
4848
Authenticates a user by user_name and password, starts a new session,
4949
and returns a session cookie.
5050
operationId: signInUser
51+
security:
52+
- sessionAuth: []
5153
requestBody:
5254
required: true
5355
content:
@@ -97,6 +99,8 @@ paths:
9799
Authenticates a user by user_name and password, starts a new session,
98100
and returns a session cookie.
99101
operationId: signOutUser
102+
security:
103+
- sessionAuth: []
100104
responses:
101105
'200':
102106
description: User logout successfully. A session cookie is remove.
@@ -162,6 +166,8 @@ paths:
162166
- Users
163167
summary: Create a new user
164168
operationId: createUser
169+
security:
170+
- sessionAuth: []
165171
parameters: []
166172
requestBody:
167173
content:
@@ -211,6 +217,8 @@ paths:
211217
tags:
212218
- Users
213219
summary: Update a user
220+
security:
221+
- sessionAuth: []
214222
operationId: updateUser
215223
parameters:
216224
- name: userId
@@ -240,6 +248,8 @@ paths:
240248
- Users
241249
summary: Delete a user
242250
operationId: deleteUser
251+
security:
252+
- sessionAuth: []
243253
parameters:
244254
- name: userId
245255
in: path
@@ -309,6 +319,8 @@ paths:
309319
- Games
310320
summary: Create a new game
311321
operationId: createGame
322+
security:
323+
- sessionAuth: []
312324
parameters: []
313325
requestBody:
314326
content:
@@ -358,6 +370,8 @@ paths:
358370
tags:
359371
- Games
360372
summary: Update a game
373+
security:
374+
- sessionAuth: []
361375
operationId: updateGame
362376
parameters:
363377
- name: gameId
@@ -392,6 +406,8 @@ paths:
392406
tags:
393407
- Games
394408
summary: Delete a game
409+
security:
410+
- sessionAuth: []
395411
operationId: deleteGame
396412
parameters:
397413
- name: gameId
@@ -442,6 +458,8 @@ paths:
442458
- Teams
443459
summary: Create a new team
444460
operationId: createTeam
461+
security:
462+
- sessionAuth: []
445463
parameters: []
446464
requestBody:
447465
content:
@@ -494,6 +512,8 @@ paths:
494512
- Teams
495513
summary: Update a team
496514
operationId: updateTeam
515+
security:
516+
- sessionAuth: []
497517
parameters:
498518
- name: teamId
499519
in: path
@@ -518,6 +538,8 @@ paths:
518538
- Teams
519539
summary: Delete a team
520540
operationId: deleteTeam
541+
security:
542+
- sessionAuth: []
521543
parameters:
522544
- name: teamId
523545
in: path
@@ -561,6 +583,8 @@ paths:
561583
- Teams
562584
summary: Connect user with team
563585
operationId: connectUserTeam
586+
security:
587+
- sessionAuth: []
564588
parameters:
565589
- in: path
566590
name: teamId
@@ -591,6 +615,8 @@ paths:
591615
- Teams
592616
summary: Approve connected user with team lead
593617
operationId: approveUserTeam
618+
security:
619+
- sessionAuth: []
594620
parameters:
595621
- in: path
596622
name: teamId
@@ -621,6 +647,8 @@ paths:
621647
- Teams
622648
summary: Leave user from team
623649
operationId: leaveUserFromTeam
650+
security:
651+
- sessionAuth: []
624652
parameters:
625653
- in: path
626654
name: teamId
@@ -659,6 +687,8 @@ paths:
659687
format: uuid
660688
summary: Create a new game result
661689
operationId: createResult
690+
security:
691+
- sessionAuth: []
662692
requestBody:
663693
content:
664694
application/json:
@@ -709,6 +739,8 @@ paths:
709739
- Results
710740
summary: Update a result
711741
operationId: updateResult
742+
security:
743+
- sessionAuth: []
712744
parameters:
713745
- in: path
714746
name: gameId
@@ -780,6 +812,8 @@ paths:
780812
- Services
781813
summary: Create a new service
782814
operationId: createService
815+
security:
816+
- sessionAuth: []
783817
parameters: []
784818
requestBody:
785819
content:
@@ -822,6 +856,8 @@ paths:
822856
- Services
823857
summary: Update a service
824858
operationId: updateService
859+
security:
860+
- sessionAuth: []
825861
parameters:
826862
- name: serviceId
827863
in: path
@@ -846,6 +882,8 @@ paths:
846882
- Services
847883
summary: Delete a service
848884
operationId: deleteService
885+
security:
886+
- sessionAuth: []
849887
parameters:
850888
- name: serviceId
851889
in: path
@@ -864,6 +902,8 @@ paths:
864902
tags:
865903
- Services
866904
summary: Upload zip-archive
905+
security:
906+
- sessionAuth: []
867907
description: |
868908
Handler for upload zip-archive with checker
869909
operationId: uploadChecker
@@ -898,6 +938,8 @@ paths:
898938
tags:
899939
- Services
900940
operationId: uploadService
941+
security:
942+
- sessionAuth: []
901943
parameters:
902944
- in: path
903945
name: serviceId
@@ -1375,4 +1417,9 @@ components:
13751417
format: uuid
13761418
links: {}
13771419
callbacks: {}
1420+
securitySchemes:
1421+
sessionAuth:
1422+
type: apiKey
1423+
in: cookie
1424+
name: session
13781425
security: []

cmd/main.go

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
package main
22

33
import (
4+
"context"
5+
"log"
46
"log/slog"
5-
"net/http"
67
"os"
78

89
"ctf01d/internal/config"
910
"ctf01d/internal/handler"
1011
"ctf01d/internal/httpserver"
1112
migration "ctf01d/internal/migrations/psql"
12-
"github.com/go-chi/chi/v5"
13-
"github.com/go-chi/cors"
13+
"ctf01d/pkg/ginmiddleware"
14+
15+
"github.com/getkin/kin-openapi/openapi3"
16+
"github.com/getkin/kin-openapi/openapi3filter"
17+
"github.com/gin-contrib/cors"
18+
"github.com/gin-gonic/gin"
1419
_ "github.com/lib/pq"
1520
_ "go.uber.org/automaxprocs"
1621
)
@@ -33,36 +38,49 @@ func main() {
3338
slog.Info("Config path is - " + path)
3439
db, err := migration.InitDatabase(cfg)
3540
if err != nil {
36-
slog.Error("Error opening database connection: " + err.Error())
37-
return
41+
slog.Error("Database connection error: " + err.Error())
42+
os.Exit(1)
3843
}
39-
slog.Info("Database connection established successfully")
4044
defer db.Close()
41-
router := chi.NewRouter()
45+
slog.Info("Database connection established successfully")
46+
router := gin.New()
47+
router.Use(gin.Recovery(), gin.Logger())
4248

4349
// Добавление CORS middleware
44-
corsMiddleware := cors.New(cors.Options{
45-
AllowedOrigins: []string{"*"},
46-
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
47-
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},
48-
ExposedHeaders: []string{"Link"},
49-
AllowCredentials: true,
50-
MaxAge: 300,
50+
router.Use(cors.Default())
51+
52+
// Загрузка спецификации OpenAPI
53+
swagger, err := openapi3.NewLoader().LoadFromFile("api/openapi.yaml")
54+
if err != nil {
55+
log.Fatalf("Failed to load OpenAPI spec: %v", err)
56+
}
57+
58+
// OpenAPI middleware валидации запросов
59+
requestValidator := ginmiddleware.OapiRequestValidatorWithOptions(swagger, &ginmiddleware.Options{
60+
Options: openapi3filter.Options{
61+
AuthenticationFunc: func(_ context.Context, _ *openapi3filter.AuthenticationInput) error {
62+
return nil
63+
},
64+
},
5165
})
5266

53-
router.Use(corsMiddleware.Handler)
67+
// OpenAPI middleware валидации ответов
68+
responseValidator := ginmiddleware.OapiResponseValidator(swagger)
69+
hndlr := &handler.Handler{DB: db}
5470

55-
hndlr := &handler.Handler{
56-
DB: db,
57-
}
58-
svr := handler.NewServerInterfaceWrapper(hndlr)
71+
// API-группа, к которой применяются валидаторы
72+
apiGroup := router.Group("/", requestValidator, responseValidator)
73+
httpserver.RegisterHandlers(apiGroup, hndlr)
5974

60-
router.Mount("/api/", httpserver.HandlerFromMux(svr, router))
61-
router.Mount("/", http.HandlerFunc(httpserver.NewHtmlRouter))
75+
// HTML маршрутизатор для корня
76+
router.GET("/", httpserver.NewHtmlRouter())
77+
router.NoRoute(httpserver.NewHtmlRouter())
6278

63-
slog.Info("Server run on", slog.String("host", cfg.HTTP.Host), slog.String("port", cfg.HTTP.Port))
64-
err = http.ListenAndServe(cfg.HTTP.Host+":"+cfg.HTTP.Port, router)
65-
if err != nil {
79+
// Запуск сервера
80+
addr := cfg.HTTP.Host + ":" + cfg.HTTP.Port
81+
slog.Info("Server running on", slog.String("address", addr))
82+
if err := router.Run(addr); err != nil {
6683
slog.Error("Server error: " + err.Error())
84+
os.Exit(1)
6785
}
6886
}

go.mod

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,65 @@ module ctf01d
33
go 1.24.0
44

55
require (
6+
github.com/getkin/kin-openapi v0.131.0
7+
github.com/gin-contrib/cors v1.7.4
8+
github.com/gin-contrib/sessions v1.0.2
9+
github.com/gin-gonic/gin v1.10.0
610
github.com/go-chi/chi/v5 v5.2.1
7-
github.com/go-chi/cors v1.2.1
811
github.com/google/uuid v1.6.0
912
github.com/ilyakaznacheev/cleanenv v1.5.0
1013
github.com/jaswdr/faker v1.19.1
1114
github.com/jaswdr/faker/v2 v2.3.3
1215
github.com/lib/pq v1.10.9
1316
github.com/oapi-codegen/runtime v1.1.1
17+
github.com/stretchr/testify v1.10.0
1418
go.uber.org/automaxprocs v1.6.0
1519
golang.org/x/crypto v0.36.0
1620
)
1721

1822
require (
1923
github.com/BurntSushi/toml v1.5.0 // indirect
2024
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
25+
github.com/bytedance/sonic v1.13.2 // indirect
26+
github.com/bytedance/sonic/loader v0.2.4 // indirect
27+
github.com/cloudwego/base64x v0.1.5 // indirect
28+
github.com/davecgh/go-spew v1.1.1 // indirect
29+
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
30+
github.com/gin-contrib/sse v1.0.0 // indirect
31+
github.com/go-openapi/jsonpointer v0.21.1 // indirect
32+
github.com/go-openapi/swag v0.23.1 // indirect
33+
github.com/go-playground/locales v0.14.1 // indirect
34+
github.com/go-playground/universal-translator v0.18.1 // indirect
35+
github.com/go-playground/validator/v10 v10.26.0 // indirect
36+
github.com/goccy/go-json v0.10.5 // indirect
37+
github.com/gomodule/redigo v1.9.2 // indirect
38+
github.com/gorilla/context v1.1.2 // indirect
39+
github.com/gorilla/mux v1.8.1 // indirect
40+
github.com/gorilla/securecookie v1.1.2 // indirect
41+
github.com/gorilla/sessions v1.4.0 // indirect
2142
github.com/joho/godotenv v1.5.1 // indirect
22-
github.com/kr/pretty v0.3.1 // indirect
23-
github.com/rogpeppe/go-internal v1.12.0 // indirect
24-
github.com/stretchr/testify v1.9.0 // indirect
25-
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
43+
github.com/josharian/intern v1.0.0 // indirect
44+
github.com/json-iterator/go v1.1.12 // indirect
45+
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
46+
github.com/leodido/go-urn v1.4.0 // indirect
47+
github.com/mailru/easyjson v0.9.0 // indirect
48+
github.com/mattn/go-isatty v0.0.20 // indirect
49+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
50+
github.com/modern-go/reflect2 v1.0.2 // indirect
51+
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
52+
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect
53+
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect
54+
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
55+
github.com/perimeterx/marshmallow v1.1.5 // indirect
56+
github.com/pmezard/go-difflib v1.0.0 // indirect
57+
github.com/snowdreamtech/redistore v0.0.0-20231007100540-6364ca2c97b4 // indirect
58+
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
59+
github.com/ugorji/go/codec v1.2.12 // indirect
60+
golang.org/x/arch v0.15.0 // indirect
61+
golang.org/x/net v0.38.0 // indirect
62+
golang.org/x/sys v0.31.0 // indirect
63+
golang.org/x/text v0.23.0 // indirect
64+
google.golang.org/protobuf v1.36.6 // indirect
2665
gopkg.in/yaml.v3 v3.0.1 // indirect
2766
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect
2867
)

0 commit comments

Comments
 (0)