diff --git a/src/internal/server/access_handler.go b/src/internal/server/access_handler.go index fe9e204..ecf577b 100644 --- a/src/internal/server/access_handler.go +++ b/src/internal/server/access_handler.go @@ -4,6 +4,7 @@ import ( dto "git.ego.freeddns.org/egommerce/api-entities/identity/dto" domain "git.ego.freeddns.org/egommerce/identity-service/domain/repository" "git.ego.freeddns.org/egommerce/identity-service/internal/service" + "git.ego.freeddns.org/egommerce/identity-service/internal/ui" "github.com/gofiber/fiber/v2" ) @@ -18,8 +19,8 @@ func (s *Server) AccessHandlerFn(c *fiber.Ctx) error { header := new(dto.AuthorizationHeaderDTO) c.ReqHeaderParser(header) - err := guardSrv.CheckUserPermissions(header, url, srvName) - if err != nil { + accessUI := ui.NewAccessActionUI(guardSrv, s.GetDatabase(), s.GetCache()) + if err := accessUI.Execute(header, url, srvName); err != nil { return s.Error(c, fiber.StatusNotFound, err.Error()) } diff --git a/src/internal/server/login_handler.go b/src/internal/server/login_handler.go index 469e68e..727e513 100644 --- a/src/internal/server/login_handler.go +++ b/src/internal/server/login_handler.go @@ -2,9 +2,7 @@ package server import ( dto "git.ego.freeddns.org/egommerce/api-entities/identity/dto" - - domain "git.ego.freeddns.org/egommerce/identity-service/domain/repository" - "git.ego.freeddns.org/egommerce/identity-service/internal/service" + "git.ego.freeddns.org/egommerce/identity-service/internal/ui" "github.com/gofiber/fiber/v2" ) @@ -15,15 +13,9 @@ func (s *Server) LoginHandlerFn(c *fiber.Ctx) error { return s.Error(c, fiber.StatusBadRequest, "Error parsing input") } - repo := domain.NewUserRepository(s.GetDatabase()) - authSrv := service.NewAuthService(repo, s.GetCache()) - - token, err := authSrv.Login(data.Username, data.Password) - if err != nil { - if err == service.ErrUnableToCacheToken { - return s.Error(c, fiber.StatusInternalServerError, err.Error()) - } - + loginUI := ui.NewLoginActionUI(s.GetDatabase(), s.GetCache()) + token, err := loginUI.Execute(data) + if err != nil { // TODO: handle other response status codes return s.Error(c, fiber.StatusBadRequest, err.Error()) } diff --git a/src/internal/server/refresh_handler.go b/src/internal/server/refresh_handler.go index 79bfefe..4e04285 100644 --- a/src/internal/server/refresh_handler.go +++ b/src/internal/server/refresh_handler.go @@ -4,6 +4,7 @@ import ( dto "git.ego.freeddns.org/egommerce/api-entities/identity/dto" domain "git.ego.freeddns.org/egommerce/identity-service/domain/repository" "git.ego.freeddns.org/egommerce/identity-service/internal/service" + "git.ego.freeddns.org/egommerce/identity-service/internal/ui" "github.com/gofiber/fiber/v2" ) @@ -17,14 +18,11 @@ func (s *Server) RefreshHandlerFn(c *fiber.Ctx) error { repo := domain.NewUserRepository(s.GetDatabase()) authSrv := service.NewAuthService(repo, s.GetCache()) - token, err := authSrv.RefreshToken(data.AccessToken) + refreshTokenActionUI := ui.NewRefreshTokenActionUI(authSrv) + token, err := refreshTokenActionUI.Execute(data) if err != nil { - if err == service.ErrUnableToCacheToken { - return s.Error(c, fiber.StatusInternalServerError, err.Error()) - } - return s.Error(c, fiber.StatusBadRequest, err.Error()) } - return c.JSON(&dto.AuthLoginResponseDTO{Token: token}) + return c.JSON(&dto.AuthRefreshTokenResponseDTO{Token: token}) } diff --git a/src/internal/service/auth.go b/src/internal/service/auth.go index b7bceb8..867cecc 100644 --- a/src/internal/service/auth.go +++ b/src/internal/service/auth.go @@ -15,10 +15,11 @@ import ( var ( passSrv *PaswordService - ErrLoginIncorrect = errors.New("login incorrect") - ErrUnableToCacheToken = errors.New("unable to save tokens in cache") - ErrInvalidAccessToken = errors.New("invalid access token") - ErrParsingAccessToken = errors.New("error while parsing access token") + ErrLoginIncorrect = errors.New("login incorrect") + ErrUnableToCacheToken = errors.New("unable to save tokens in cache") + ErrInvalidAccessToken = errors.New("invalid access token") + ErrParsingAccessToken = errors.New("error while parsing access token") + ErrUnableToCacheUserID = errors.New("unable to save User ID in cache") ) func init() { @@ -40,6 +41,7 @@ func NewAuthService(userRepo *domain.UserRepository, cache *redis.Client) *AuthS func (a *AuthService) Login(login, passwd string) (string, error) { user, err := a.userRepo.FindByUsername(login) if err != nil { + // TODO place code below in better place... // if err = database.NoRowsInQuerySet(err); err != nil { // return "", errors.New("no user found") // } @@ -57,16 +59,20 @@ func (a *AuthService) Login(login, passwd string) (string, error) { return "", ErrUnableToCacheToken } - // REFACTOR: save uid in cache under user:$ACCES_TOKEN key + // REFACTOR: save uid in cache under "user:$ACCES_TOKEN" key res := a.cache.Set(context.Background(), "user:"+accessToken, user.ID, accessTokenExpireTime) if err := res.Err(); err != nil { fmt.Println("failed to save user:$ACCESS_TOKEN in cache: ", err.Error()) + + return "", ErrUnableToCacheUserID } return accessToken, nil } func (a *AuthService) RefreshToken(accessToken string) (string, error) { + // POSSIBLE BIG SECURITY ISSUE- WHEN REFRESH WITH ABANDONED (or EXPIRED) + // ACCESS TOKEN WE GET NEW ACCESS TOKEN token, claims, err := jwtSrv.ValidateAccessToken(accessToken) if err != nil || !token.Valid { return "", ErrInvalidAccessToken diff --git a/src/internal/ui/access_action.go b/src/internal/ui/access_action.go new file mode 100644 index 0000000..1df3eac --- /dev/null +++ b/src/internal/ui/access_action.go @@ -0,0 +1,32 @@ +package ui + +import ( + dto "git.ego.freeddns.org/egommerce/api-entities/identity/dto" + "git.ego.freeddns.org/egommerce/identity-service/internal/service" + + "github.com/go-redis/redis/v8" + "github.com/jackc/pgx/v5/pgxpool" +) + +type AccessActionUI struct { + guard *service.Guard + db *pgxpool.Pool + cache *redis.Client +} + +func NewAccessActionUI(guard *service.Guard, db *pgxpool.Pool, cache *redis.Client) *AccessActionUI { + return &AccessActionUI{ + guard: guard, + db: db, + cache: cache, + } +} + +func (ui *AccessActionUI) Execute(data *dto.AuthorizationHeaderDTO, url, srvName string) error { + err := ui.guard.CheckUserPermissions(data, url, srvName) + if err != nil { + return err + } + + return nil +} diff --git a/src/internal/ui/login_action.go b/src/internal/ui/login_action.go new file mode 100644 index 0000000..2db3e96 --- /dev/null +++ b/src/internal/ui/login_action.go @@ -0,0 +1,38 @@ +package ui + +import ( + dto "git.ego.freeddns.org/egommerce/api-entities/identity/dto" + domain "git.ego.freeddns.org/egommerce/identity-service/domain/repository" + "git.ego.freeddns.org/egommerce/identity-service/internal/service" + + "github.com/go-redis/redis/v8" + "github.com/jackc/pgx/v5/pgxpool" +) + +type LoginActionUI struct { + db *pgxpool.Pool + cache *redis.Client +} + +func NewLoginActionUI(db *pgxpool.Pool, cache *redis.Client) *LoginActionUI { + return &LoginActionUI{ + db: db, + cache: cache, + } +} + +func (ui *LoginActionUI) Execute(data *dto.AuthLoginRequestDTO) (string, error) { + repo := domain.NewUserRepository(ui.db) + authSrv := service.NewAuthService(repo, ui.cache) + + token, err := authSrv.Login(data.Username, data.Password) + if err != nil { + if err == service.ErrUnableToCacheToken { + return "", err + } + + return "", err + } + + return token, nil +} diff --git a/src/internal/ui/refresh_action.go b/src/internal/ui/refresh_action.go new file mode 100644 index 0000000..d55e345 --- /dev/null +++ b/src/internal/ui/refresh_action.go @@ -0,0 +1,29 @@ +package ui + +import ( + dto "git.ego.freeddns.org/egommerce/api-entities/identity/dto" + "git.ego.freeddns.org/egommerce/identity-service/internal/service" +) + +type RefreshTokenActionUI struct { + auth *service.AuthService +} + +func NewRefreshTokenActionUI(auth *service.AuthService) *RefreshTokenActionUI { + return &RefreshTokenActionUI{ + auth: auth, + } +} + +func (ui *RefreshTokenActionUI) Execute(data *dto.AuthRefreshTokenRequestDTO) (string, error) { + token, err := ui.auth.RefreshToken(data.AccessToken) + if err != nil { + if err == service.ErrUnableToCacheToken { // FIXME: Move to RefreshHandlerFn + return "", err + } + + return "", err + } + + return token, nil +}