diff --git a/app/module/users/controller/users.controller.go b/app/module/users/controller/users.controller.go index cbd797b..a91b1bf 100644 --- a/app/module/users/controller/users.controller.go +++ b/app/module/users/controller/users.controller.go @@ -20,6 +20,7 @@ type UsersController interface { Show(c *fiber.Ctx) error Save(c *fiber.Ctx) error Update(c *fiber.Ctx) error + Login(c *fiber.Ctx) error Delete(c *fiber.Ctx) error } @@ -167,6 +168,39 @@ func (_i *usersController) Update(c *fiber.Ctx) error { }) } +// Login Users +// @Summary Login Users +// @Description API for Login Users +// @Tags Users +// @Security Bearer +// @Param payload body request.UserLogin true "Required payload" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /users/login [post] +func (_i *usersController) Login(c *fiber.Ctx) error { + req := new(request.UserLogin) + if err := utilVal.ParseAndValidate(c, req); err != nil { + return err + } + + loginResponse, err := _i.usersService.Login(*req) + if err != nil { + return utilRes.Resp(c, utilRes.Response{ + Success: false, + Code: 401, + Messages: utilRes.Messages{err.Error()}, + }) + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Users successfully login"}, + Data: loginResponse, + }) +} + // Delete Users // @Summary delete Users // @Description API for delete Users diff --git a/app/module/users/request/users.request.go b/app/module/users/request/users.request.go index 59c464c..48d4d25 100644 --- a/app/module/users/request/users.request.go +++ b/app/module/users/request/users.request.go @@ -36,6 +36,7 @@ type UsersCreateRequest struct { LastEducation string `json:"lastEducation" validate:"required"` UserRoleId int `json:"userRoleId" validate:"required"` UserLevelId int `json:"userLevelId" validate:"required"` + Password string `json:"password" validate:"required"` } func (req UsersCreateRequest) ToEntity() *entity.Users { @@ -93,6 +94,11 @@ func (req UsersUpdateRequest) ToEntity() *entity.Users { } } +type UserLogin struct { + Username string `json:"username" validate:"required,lowercase"` + Password string `json:"password" validate:"required"` +} + type UsersQueryRequestContext struct { Username string `json:"username"` Email string `json:"email"` diff --git a/app/module/users/service/users.service.go b/app/module/users/service/users.service.go index 9fdf0e3..696b7aa 100644 --- a/app/module/users/service/users.service.go +++ b/app/module/users/service/users.service.go @@ -1,19 +1,22 @@ package service import ( + "github.com/Nerzal/gocloak/v13" "github.com/rs/zerolog" "go-humas-be/app/module/users/mapper" "go-humas-be/app/module/users/repository" "go-humas-be/app/module/users/request" "go-humas-be/app/module/users/response" + "go-humas-be/config/config" "go-humas-be/utils/paginator" utilSvc "go-humas-be/utils/service" ) // UsersService type usersService struct { - Repo repository.UsersRepository - Log zerolog.Logger + Repo repository.UsersRepository + Log zerolog.Logger + Keycloak *config.KeycloakConfig } // UsersService define interface of IUsersService @@ -21,16 +24,18 @@ type UsersService interface { All(req request.UsersQueryRequest) (users []*response.UsersResponse, paging paginator.Pagination, err error) Show(id uint) (users *response.UsersResponse, err error) Save(req request.UsersCreateRequest, authToken string) (err error) + Login(req request.UserLogin) (res *gocloak.JWT, err error) Update(id uint, req request.UsersUpdateRequest) (err error) Delete(id uint) error } // NewUsersService init UsersService -func NewUsersService(repo repository.UsersRepository, log zerolog.Logger) UsersService { +func NewUsersService(repo repository.UsersRepository, log zerolog.Logger, keycloak *config.KeycloakConfig) UsersService { return &usersService{ - Repo: repo, - Log: log, + Repo: repo, + Log: log, + Keycloak: keycloak, } } @@ -64,12 +69,41 @@ func (_i *usersService) Save(req request.UsersCreateRequest, authToken string) ( createdBy := utilSvc.GetUserInfo(_i.Log, _i.Repo, authToken) newReq.CreatedById = &createdBy.ID + keycloakId, err := _i.Keycloak.CreateUser(req.Fullname, req.Email, req.Username, req.Password) + if err != nil { + return err + } + + newReq.KeycloakId = &keycloakId + return _i.Repo.Create(newReq) } +func (_i *usersService) Login(req request.UserLogin) (res *gocloak.JWT, err error) { + _i.Log.Info().Interface("data", req).Msg("") + + loginResponse, err := _i.Keycloak.Login(req.Username, req.Password) + if err != nil { + return nil, err + } + return loginResponse, nil +} + func (_i *usersService) Update(id uint, req request.UsersUpdateRequest) (err error) { _i.Log.Info().Interface("data", req).Msg("") - return _i.Repo.Update(id, req.ToEntity()) + newReq := req.ToEntity() + + findUser, err := _i.Repo.FindOne(id) + if err != nil { + return err + } + + err = _i.Keycloak.UpdateUser(findUser.KeycloakId, req.Fullname, req.Email) + if err != nil { + return err + } + + return _i.Repo.Update(id, newReq) } func (_i *usersService) Delete(id uint) error { diff --git a/app/module/users/users.module.go b/app/module/users/users.module.go index d10a291..d0cb570 100644 --- a/app/module/users/users.module.go +++ b/app/module/users/users.module.go @@ -48,6 +48,7 @@ func (_i *UsersRouter) RegisterUsersRoutes() { router.Get("/:id", usersController.Show) router.Post("/", usersController.Save) router.Put("/:id", usersController.Update) + router.Post("/login", usersController.Login) router.Delete("/:id", usersController.Delete) }) } diff --git a/config/config/index.config.go b/config/config/index.config.go index 92b9fdf..49733c7 100644 --- a/config/config/index.config.go +++ b/config/config/index.config.go @@ -81,12 +81,22 @@ type objectStorage = struct { } } +type keycloak = struct { + Endpoint string `toml:"endpoint"` + Realm string `toml:"realm"` + ClientId string `toml:"client-id"` + ClientSecret string `toml:"client-secret"` + AdminUsername string `toml:"admin-username"` + AdminPassword string `toml:"admin-password"` +} + type Config struct { App app DB db Logger logger Middleware middleware ObjectStorage objectStorage + Keycloak keycloak } // NewConfig : initialize config diff --git a/config/config/keycloak.config.go b/config/config/keycloak.config.go new file mode 100644 index 0000000..fed9f9d --- /dev/null +++ b/config/config/keycloak.config.go @@ -0,0 +1,122 @@ +package config + +import ( + "context" + "errors" + "github.com/Nerzal/gocloak/v13" +) + +// MinioSetup struct +type KeycloakConfig struct { + Cfg *Config +} + +func NewKeycloakConfig(cfg *Config) *KeycloakConfig { + keycloakSetup := &KeycloakConfig{ + Cfg: cfg, + } + + return keycloakSetup +} + +func (_keycloak *KeycloakConfig) Login(username string, password string) (*gocloak.JWT, error) { + ctx := context.Background() + client := gocloak.NewClient(_keycloak.Cfg.Keycloak.Endpoint) + loginResponse, err := client.Login( + ctx, + _keycloak.Cfg.Keycloak.ClientId, + _keycloak.Cfg.Keycloak.ClientSecret, + _keycloak.Cfg.Keycloak.Realm, + username, + password, + ) + if err != nil { + return nil, errors.New("Invalid User Credentials") + } + + return loginResponse, nil +} + +func (_keycloak *KeycloakConfig) CreateUser(fullname string, email string, username string, password string) (string, error) { + ctx := context.Background() + client := gocloak.NewClient(_keycloak.Cfg.Keycloak.Endpoint) + token, err := client.Login( + ctx, + _keycloak.Cfg.Keycloak.ClientId, + _keycloak.Cfg.Keycloak.ClientSecret, + _keycloak.Cfg.Keycloak.Realm, + _keycloak.Cfg.Keycloak.AdminUsername, + _keycloak.Cfg.Keycloak.AdminPassword, + ) + if err != nil { + panic("Something wrong with the credentials or url") + } + + var group []string + group = append(group, "humas") + user := gocloak.User{ + FirstName: gocloak.StringP(fullname), + LastName: gocloak.StringP(""), + Email: gocloak.StringP(email), + Enabled: gocloak.BoolP(true), + Username: gocloak.StringP(username), + Groups: &group, + } + + keycloakId, err := client.CreateUser(ctx, token.AccessToken, _keycloak.Cfg.Keycloak.Realm, user) + if err != nil { + panic("Oh no!, failed to create user :(") + } + + err = _keycloak.SetPassword(token.AccessToken, keycloakId, password) + if err != nil { + return "", err + } + + return keycloakId, nil +} + +func (_keycloak *KeycloakConfig) UpdateUser(keycloakId *string, fullname string, email string) error { + ctx := context.Background() + client := gocloak.NewClient(_keycloak.Cfg.Keycloak.Endpoint) + token, err := client.Login( + ctx, + _keycloak.Cfg.Keycloak.ClientId, + _keycloak.Cfg.Keycloak.ClientSecret, + _keycloak.Cfg.Keycloak.Realm, + _keycloak.Cfg.Keycloak.AdminUsername, + _keycloak.Cfg.Keycloak.AdminPassword, + ) + if err != nil { + panic("Something wrong with the credentials or url") + } + + var group []string + group = append(group, "humas") + user := gocloak.User{ + ID: keycloakId, + FirstName: gocloak.StringP(fullname), + LastName: gocloak.StringP(""), + Email: gocloak.StringP(email), + Groups: &group, + } + + err = client.UpdateUser(ctx, token.AccessToken, _keycloak.Cfg.Keycloak.Realm, user) + if err != nil { + panic(err) + } + + return err +} + +func (_keycloak *KeycloakConfig) SetPassword(token string, keycloakId string, password string) error { + ctx := context.Background() + client := gocloak.NewClient(_keycloak.Cfg.Keycloak.Endpoint) + + err := client.SetPassword(ctx, token, keycloakId, _keycloak.Cfg.Keycloak.Realm, password, false) + if err != nil { + panic("Oh no!, failed to set password :(") + } + + return nil +} diff --git a/config/toml/config.toml b/config/toml/config.toml index 45ce2f3..44d16d6 100644 --- a/config/toml/config.toml +++ b/config/toml/config.toml @@ -46,4 +46,12 @@ enable = true [middleware.limiter] enable = false max = 20 -expiration_seconds = 60 \ No newline at end of file +expiration_seconds = 60 + +[keycloak] +endpoint = "http://103.82.242.92:8008" +realm = "humas" +client-id = "humas-app" +client-secret = "8HV15QgqvQyNmisvZBQblQi4d27zys7l" +admin-username = "admin" +admin-password = "P@ssw0rd.1" \ No newline at end of file diff --git a/docs/swagger/docs.go b/docs/swagger/docs.go index 3cd2627..795aef8 100644 --- a/docs/swagger/docs.go +++ b/docs/swagger/docs.go @@ -5568,6 +5568,57 @@ const docTemplate = `{ } } }, + "/users/login": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Login Users", + "tags": [ + "Users" + ], + "summary": "Login Users", + "parameters": [ + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserLogin" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, "/users/{id}": { "get": { "security": [ @@ -6248,6 +6299,21 @@ const docTemplate = `{ } } }, + "request.UserLogin": { + "type": "object", + "required": [ + "password", + "username" + ], + "properties": { + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, "request.UserRoleAccessesCreateRequest": { "type": "object", "required": [ @@ -6395,6 +6461,7 @@ const docTemplate = `{ "identityNumber", "identityType", "lastEducation", + "password", "phoneNumber", "userLevelId", "userRoleId", @@ -6426,6 +6493,9 @@ const docTemplate = `{ "lastEducation": { "type": "string" }, + "password": { + "type": "string" + }, "phoneNumber": { "type": "string" }, diff --git a/docs/swagger/swagger.json b/docs/swagger/swagger.json index 0512713..07bda8c 100644 --- a/docs/swagger/swagger.json +++ b/docs/swagger/swagger.json @@ -5557,6 +5557,57 @@ } } }, + "/users/login": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Login Users", + "tags": [ + "Users" + ], + "summary": "Login Users", + "parameters": [ + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserLogin" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, "/users/{id}": { "get": { "security": [ @@ -6237,6 +6288,21 @@ } } }, + "request.UserLogin": { + "type": "object", + "required": [ + "password", + "username" + ], + "properties": { + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, "request.UserRoleAccessesCreateRequest": { "type": "object", "required": [ @@ -6384,6 +6450,7 @@ "identityNumber", "identityType", "lastEducation", + "password", "phoneNumber", "userLevelId", "userRoleId", @@ -6415,6 +6482,9 @@ "lastEducation": { "type": "string" }, + "password": { + "type": "string" + }, "phoneNumber": { "type": "string" }, diff --git a/docs/swagger/swagger.yaml b/docs/swagger/swagger.yaml index 6389524..fdea809 100644 --- a/docs/swagger/swagger.yaml +++ b/docs/swagger/swagger.yaml @@ -366,6 +366,16 @@ definitions: - parentLevelId - provinceId type: object + request.UserLogin: + properties: + password: + type: string + username: + type: string + required: + - password + - username + type: object request.UserRoleAccessesCreateRequest: properties: isAdminEnabled: @@ -481,6 +491,8 @@ definitions: type: string lastEducation: type: string + password: + type: string phoneNumber: type: string userLevelId: @@ -500,6 +512,7 @@ definitions: - identityNumber - identityType - lastEducation + - password - phoneNumber - userLevelId - userRoleId @@ -4207,4 +4220,36 @@ paths: summary: update Users tags: - Users + /users/login: + post: + description: API for Login Users + parameters: + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserLogin' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Login Users + tags: + - Users swagger: "2.0" diff --git a/go.mod b/go.mod index ddb8955..ee34d40 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module go-humas-be go 1.21.6 require ( + github.com/Nerzal/gocloak/v13 v13.9.0 github.com/arsmn/fiber-swagger/v2 v2.31.1 github.com/efectn/fx-zerolog v1.1.0 github.com/go-playground/locales v0.14.1 @@ -28,6 +29,7 @@ require ( github.com/go-openapi/jsonreference v0.20.5 // indirect github.com/go-openapi/spec v0.20.15 // indirect github.com/go-openapi/swag v0.22.10 // indirect + github.com/go-resty/resty/v2 v2.7.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect @@ -47,10 +49,13 @@ require ( github.com/minio/sha256-simd v1.0.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/philhofer/fwd v1.1.2 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/xid v1.5.0 // indirect + github.com/segmentio/ksuid v1.0.4 // indirect github.com/swaggo/files v1.0.1 // indirect github.com/tinylib/msgp v1.1.8 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect diff --git a/go.sum b/go.sum index b06f871..3ea4963 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/Nerzal/gocloak/v13 v13.9.0 h1:YWsJsdM5b0yhM2Ba3MLydiOlujkBry4TtdzfIzSVZhw= +github.com/Nerzal/gocloak/v13 v13.9.0/go.mod h1:YYuDcXZ7K2zKECyVP7pPqjKxx2AzYSpKDj8d6GuyM10= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= @@ -46,6 +48,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.17.0 h1:SmVVlfAOtlZncTxRuinDPomC2DkXJ4E5T9gDA0AIH74= github.com/go-playground/validator/v10 v10.17.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= +github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofiber/fiber/v2 v2.31.0/go.mod h1:1Ega6O199a3Y7yDGuM9FyXDPYQfv+7/y48wl6WCwUF4= github.com/gofiber/fiber/v2 v2.52.4 h1:P+T+4iK7VaqUsq2PALYEfBBo6bJZ4q3FP8cZ84EggTM= @@ -111,6 +115,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= @@ -120,6 +126,7 @@ github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOS github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -133,6 +140,8 @@ github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= +github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -195,6 +204,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= diff --git a/main.go b/main.go index a4e9498..8a4a5ff 100644 --- a/main.go +++ b/main.go @@ -45,6 +45,8 @@ func main() { fx.Provide(middleware.NewMiddleware), // data storage fx.Provide(config.NewMinio), + // user management + fx.Provide(config.NewKeycloakConfig), // router fx.Provide(router.NewRouter),