diff --git a/src/internal/server/access_handler.go b/src/internal/server/access_handler.go index 9320274..fe9e204 100644 --- a/src/internal/server/access_handler.go +++ b/src/internal/server/access_handler.go @@ -1,8 +1,6 @@ package server import ( - "fmt" - 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" @@ -14,36 +12,16 @@ func (s *Server) AccessHandlerFn(c *fiber.Ctx) error { roleRepo := domain.NewRoleRepository(s.GetDatabase()) urlRepo := domain.NewURLAccessRepository(s.GetDatabase()) authSrv := service.NewAuthService(userRepo, s.GetCache()) + guardSrv := service.NewGuardService(authSrv, userRepo, roleRepo, urlRepo) url, srvName := c.Query("q"), c.Query("srv") - header := new(dto.AuthorizationHeaderDTO) c.ReqHeaderParser(header) - token, err := authSrv.GetTokenFromAuthorizationHeader(header.Authorization) - if err != nil { // FIXME probably never get here cause of jwt parsing in middlewares + err := guardSrv.CheckUserPermissions(header, url, srvName) + if err != nil { return s.Error(c, fiber.StatusNotFound, err.Error()) } - uid, _ := authSrv.GetUIDByAccesssToken(token) - user, err := userRepo.FindByID(uid) - if err != nil { - return s.Error(c, fiber.StatusNotFound, "user not found") - } - - role := roleRepo.GetUserRole(user) - - urlAcc, err := urlRepo.FindByURLAndServiceForRole(url, srvName, role.Name) - if err != nil { - return s.Error(c, fiber.StatusNotFound, "user has not required permission") - } - - fmt.Printf("urlAcc: %#v", urlAcc) - - // roles := urlRepo.FindForUser() - // guardSrv := service.NewGuardService() - - // guard.CheckAccess("asd") - return c.SendStatus(fiber.StatusNoContent) } diff --git a/src/internal/service/auth.go b/src/internal/service/auth.go index 40f666f..b7bceb8 100644 --- a/src/internal/service/auth.go +++ b/src/internal/service/auth.go @@ -25,19 +25,19 @@ func init() { passSrv = NewPasswordService() } -type Auth struct { +type AuthService struct { userRepo *domain.UserRepository cache *redis.Client } -func NewAuthService(userRepo *domain.UserRepository, cache *redis.Client) *Auth { - return &Auth{ +func NewAuthService(userRepo *domain.UserRepository, cache *redis.Client) *AuthService { + return &AuthService{ userRepo: userRepo, cache: cache, } } -func (a *Auth) Login(login, passwd string) (string, error) { +func (a *AuthService) Login(login, passwd string) (string, error) { user, err := a.userRepo.FindByUsername(login) if err != nil { // if err = database.NoRowsInQuerySet(err); err != nil { @@ -66,7 +66,7 @@ func (a *Auth) Login(login, passwd string) (string, error) { return accessToken, nil } -func (a *Auth) RefreshToken(accessToken string) (string, error) { +func (a *AuthService) RefreshToken(accessToken string) (string, error) { token, claims, err := jwtSrv.ValidateAccessToken(accessToken) if err != nil || !token.Valid { return "", ErrInvalidAccessToken @@ -95,7 +95,7 @@ func (a *Auth) RefreshToken(accessToken string) (string, error) { return newAccessToken, nil } -func (a *Auth) Register(email, login, passwd string) (string, error) { +func (a *AuthService) Register(email, login, passwd string) (string, error) { passwd, _ = passSrv.Hash(passwd) id, err := a.userRepo.Create(&entity.User{ @@ -110,7 +110,7 @@ func (a *Auth) Register(email, login, passwd string) (string, error) { return id, nil } -func (a *Auth) GetTokenFromAuthorizationHeader(header string) (string, error) { +func (a *AuthService) getTokenFromAuthorizationHeader(header string) (string, error) { split := strings.Split(header, " ") if len(split) != 2 { return "", ErrParsingAccessToken @@ -119,7 +119,7 @@ func (a *Auth) GetTokenFromAuthorizationHeader(header string) (string, error) { return split[1], nil } -func (a *Auth) GetUIDByAccesssToken(aToken string) (string, error) { +func (a *AuthService) getUIDByAccesssToken(aToken string) (string, error) { res := a.cache.Get(context.Background(), "user:"+aToken) if err := res.Err(); err != nil { return "", err @@ -130,7 +130,7 @@ func (a *Auth) GetUIDByAccesssToken(aToken string) (string, error) { return uid, nil } -func (a *Auth) saveTokensToCache(id, aToken, rToken string) error { +func (a *AuthService) saveTokensToCache(id, aToken, rToken string) error { res := a.cache.Set(context.Background(), "auth:access_token:"+id, aToken, accessTokenExpireTime) if err := res.Err(); err != nil { fmt.Println("failed to save access token in cache: ", err.Error()) diff --git a/src/internal/service/guard.go b/src/internal/service/guard.go new file mode 100644 index 0000000..91e499b --- /dev/null +++ b/src/internal/service/guard.go @@ -0,0 +1,45 @@ +package service + +import ( + "errors" + + dto "git.ego.freeddns.org/egommerce/api-entities/identity/dto" + domain "git.ego.freeddns.org/egommerce/identity-service/domain/repository" +) + +type Guard struct { + authSrv *AuthService + userRepo *domain.UserRepository + roleRepo *domain.RoleRepository + urlRepo *domain.URLAccessRepository +} + +func NewGuardService(authSrv *AuthService, userRepo *domain.UserRepository, roleRepo *domain.RoleRepository, urlRepo *domain.URLAccessRepository) *Guard { + return &Guard{ + authSrv: authSrv, + userRepo: userRepo, + roleRepo: roleRepo, + urlRepo: urlRepo, + } +} + +func (g *Guard) CheckUserPermissions(authHeader *dto.AuthorizationHeaderDTO, url, srvName string) error { + token, err := g.authSrv.getTokenFromAuthorizationHeader(authHeader.Authorization) + if err != nil { // FIXME probably never get here cause of jwt parsing in middlewares + return err + } + + uid, _ := g.authSrv.getUIDByAccesssToken(token) + user, err := g.userRepo.FindByID(uid) + if err != nil { + return errors.New("user not found") + } + + role := g.roleRepo.GetUserRole(user) + + if _, err := g.urlRepo.FindByURLAndServiceForRole(url, srvName, role.Name); err != nil { + return errors.New("user has not required permission") + } + + return nil +}