Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✅ Add namespace update ut #287

Merged
merged 1 commit into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions pkg/auth/artifact.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,29 @@
package auth

import (
"errors"
"fmt"

"github.com/labstack/echo/v4"
"github.com/rs/zerolog/log"
"gorm.io/gorm"

"github.com/go-sigma/sigma/pkg/types/enums"
)

// Tag ...
func (s service) Artifact(c echo.Context, artifactID int64, auth enums.Auth) bool {
func (s service) Artifact(c echo.Context, artifactID int64, auth enums.Auth) (bool, error) {
ctx := log.Logger.WithContext(c.Request().Context())

artifactService := s.artifactServiceFactory.New()
artifactObj, err := artifactService.Get(ctx, artifactID)
if err != nil {
log.Error().Err(err).Msg("Get artifact by id failed")
return false
if !errors.Is(err, gorm.ErrRecordNotFound) {
log.Error().Err(err).Int64("artifactID", artifactID).Msg("Get artifact by id failed")
return false, errors.Join(err, fmt.Errorf("Get artifact by id(%d) failed", artifactID))
}
log.Error().Err(err).Int64("artifactID", artifactID).Msg("Get artifact by id not found")
return false, errors.Join(err, fmt.Errorf("Get artifact by id(%d) not found", artifactID))
}
return s.Repository(c, artifactObj.RepositoryID, auth)
}
8 changes: 4 additions & 4 deletions pkg/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ import (
// Service is the interface for the auth service
type Service interface {
// Namespace ...
Namespace(c echo.Context, namespaceID int64, auth enums.Auth) bool
Namespace(c echo.Context, namespaceID int64, auth enums.Auth) (bool, error)
// Repository ...
Repository(c echo.Context, repositoryID int64, auth enums.Auth) bool
Repository(c echo.Context, repositoryID int64, auth enums.Auth) (bool, error)
// Tag ...
Tag(c echo.Context, tagID int64, auth enums.Auth) bool
Tag(c echo.Context, tagID int64, auth enums.Auth) (bool, error)
// Artifact ...
Artifact(c echo.Context, artifactID int64, auth enums.Auth) bool
Artifact(c echo.Context, artifactID int64, auth enums.Auth) (bool, error)
}

// ServiceFactory is the interface that provides the artifact service factory methods.
Expand Down
20 changes: 12 additions & 8 deletions pkg/auth/mocks/service.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 19 additions & 14 deletions pkg/auth/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package auth

import (
"errors"
"fmt"

"github.com/labstack/echo/v4"
"github.com/rs/zerolog/log"
Expand All @@ -27,53 +28,57 @@ import (
)

// Namespace ...
func (s service) Namespace(c echo.Context, namespaceID int64, auth enums.Auth) bool {
func (s service) Namespace(c echo.Context, namespaceID int64, auth enums.Auth) (bool, error) {
ctx := log.Logger.WithContext(c.Request().Context())

iuser := c.Get(consts.ContextUser)
if iuser == nil {
log.Error().Msg("Get user from header failed")
return false
return false, nil
}
user, ok := iuser.(*models.User)
if !ok {
log.Error().Msg("Convert user from header failed")
return false
return false, nil
}

// 1. check user is admin or not
if user.Role == enums.UserRoleAdmin || user.Role == enums.UserRoleRoot {
return true
return true, nil
}

// 2. check namespace visibility
namespaceService := s.namespaceServiceFactory.New()
namespaceObj, err := namespaceService.Get(ctx, namespaceID)
if err != nil {
log.Error().Err(err).Msg("Get namespace by id failed")
return false
if !errors.Is(err, gorm.ErrRecordNotFound) {
log.Error().Err(err).Msg("Get namespace by id failed")
return false, errors.Join(err, fmt.Errorf("Get namespace by id(%d) failed", namespaceID))
}
log.Error().Err(err).Msg("Get namespace by id not found")
return false, errors.Join(err, fmt.Errorf("Get namespace by id(%d) not found", namespaceID))
}
if namespaceObj.Visibility == enums.VisibilityPublic && auth == enums.AuthRead {
return true
return true, nil
}

// 3. check user is member of the namespace
roleService := s.roleServiceFactory.New()
namespaceMemberObj, err := roleService.GetNamespaceMember(ctx, namespaceID, user.ID)
if err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
log.Error().Err(err).Msg("Get namespace member failed")
if !errors.Is(err, gorm.ErrRecordNotFound) { // check user's role in this namespace
log.Error().Err(err).Msg("Get namespace member by namespace id and user id failed")
}
return false
return false, err
}
if namespaceMemberObj.Role == enums.NamespaceRoleReader && auth == enums.AuthRead {
return true
return true, nil
}
if namespaceMemberObj.Role == enums.NamespaceRoleManager && (auth == enums.AuthManage || auth == enums.AuthRead) {
return true
return true, nil
}
if namespaceMemberObj.Role == enums.NamespaceRoleAdmin && (auth == enums.AuthAdmin || auth == enums.AuthManage || auth == enums.AuthRead) {
return true
return true, nil
}
return false
return false, nil
}
14 changes: 11 additions & 3 deletions pkg/auth/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,28 @@
package auth

import (
"errors"
"fmt"

"github.com/labstack/echo/v4"
"github.com/rs/zerolog/log"
"gorm.io/gorm"

"github.com/go-sigma/sigma/pkg/types/enums"
)

// Repository ...
func (s service) Repository(c echo.Context, repositoryID int64, auth enums.Auth) bool {
func (s service) Repository(c echo.Context, repositoryID int64, auth enums.Auth) (bool, error) {
ctx := log.Logger.WithContext(c.Request().Context())
repositoryService := s.repositoryServiceFactory.New()
repositoryObj, err := repositoryService.Get(ctx, repositoryID)
if err != nil {
log.Error().Err(err).Msg("Get repository by id failed")
return false
if !errors.Is(err, gorm.ErrRecordNotFound) {
log.Error().Err(err).Int64("repositoryID", repositoryID).Msg("Get repository by id failed")
return false, errors.Join(err, fmt.Errorf("Get repository by id(%d) failed", repositoryID))
}
log.Error().Err(err).Int64("repositoryID", repositoryID).Msg("Get repository by id not found")
return false, errors.Join(err, fmt.Errorf("Get repository by id(%d) not found", repositoryID))
}
return s.Namespace(c, repositoryObj.NamespaceID, auth)
}
14 changes: 11 additions & 3 deletions pkg/auth/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,29 @@
package auth

import (
"errors"
"fmt"

"github.com/labstack/echo/v4"
"github.com/rs/zerolog/log"
"gorm.io/gorm"

"github.com/go-sigma/sigma/pkg/types/enums"
)

// Tag ...
func (s service) Tag(c echo.Context, tagID int64, auth enums.Auth) bool {
func (s service) Tag(c echo.Context, tagID int64, auth enums.Auth) (bool, error) {
ctx := log.Logger.WithContext(c.Request().Context())

tagService := s.tagServiceFactory.New()
tagObj, err := tagService.GetByID(ctx, tagID)
if err != nil {
log.Error().Err(err).Msg("Get tag by id failed")
return false
if !errors.Is(err, gorm.ErrRecordNotFound) {
log.Error().Err(err).Int64("tagID", tagID).Msg("Get tag by id failed")
return false, errors.Join(err, fmt.Errorf("Get tag by id(%d) failed", tagID))
}
log.Error().Err(err).Int64("tagID", tagID).Msg("Get tag by id not found")
return false, errors.Join(err, fmt.Errorf("Get tag by id(%d) not found", tagID))
}
return s.Repository(c, tagObj.RepositoryID, auth)
}
17 changes: 13 additions & 4 deletions pkg/handlers/distribution/base/tags_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"github.com/go-sigma/sigma/pkg/consts"
"github.com/go-sigma/sigma/pkg/dal/models"
"github.com/go-sigma/sigma/pkg/types/enums"
"github.com/go-sigma/sigma/pkg/utils"
"github.com/go-sigma/sigma/pkg/xerrors"
)

Expand Down Expand Up @@ -79,12 +80,20 @@
return xerrors.NewDSError(c, xerrors.DSErrCodeUnknown)
}

if !h.authServiceFactory.New().Repository(c, repositoryObj.ID, enums.AuthRead) {
log.Error().Int64("UserID", user.ID).Int64("NamespaceID", repositoryObj.ID).Msg("Auth check failed")
return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeUnauthorized, "No permission with this api")
authChecked, err := h.authServiceFactory.New().Repository(c, repositoryObj.ID, enums.AuthRead)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
log.Error().Err(errors.New(utils.UnwrapJoinedErrors(err))).Msg("Resource not found")
return xerrors.GenDSErrCodeResourceNotFound(err)
}
return xerrors.NewDSError(c, xerrors.DSErrCodeUnknown)

Check warning on line 89 in pkg/handlers/distribution/base/tags_list.go

View check run for this annotation

Codecov / codecov/patch

pkg/handlers/distribution/base/tags_list.go#L85-L89

Added lines #L85 - L89 were not covered by tests
}
if !authChecked {
log.Error().Int64("UserID", user.ID).Int64("RepositoryID", repositoryObj.ID).Msg("Auth check failed")
return xerrors.NewDSError(c, xerrors.DSErrCodeUnauthorized)

Check warning on line 93 in pkg/handlers/distribution/base/tags_list.go

View check run for this annotation

Codecov / codecov/patch

pkg/handlers/distribution/base/tags_list.go#L92-L93

Added lines #L92 - L93 were not covered by tests
}

lastFound := false
var lastFound bool
var lastID int64 = 0

tagService := h.tagServiceFactory.New()
Expand Down
14 changes: 12 additions & 2 deletions pkg/handlers/distribution/blob/blob_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"github.com/go-sigma/sigma/pkg/consts"
"github.com/go-sigma/sigma/pkg/dal/models"
"github.com/go-sigma/sigma/pkg/types/enums"
"github.com/go-sigma/sigma/pkg/utils"
"github.com/go-sigma/sigma/pkg/utils/imagerefs"
"github.com/go-sigma/sigma/pkg/validators"
"github.com/go-sigma/sigma/pkg/xerrors"
Expand Down Expand Up @@ -65,9 +66,18 @@
log.Error().Err(err).Str("Name", repository).Msg("Get repository by name failed")
return xerrors.NewDSError(c, xerrors.DSErrCodeBlobUnknown)
}
if !h.authServiceFactory.New().Repository(c, namespaceObj.ID, enums.AuthManage) {

authChecked, err := h.authServiceFactory.New().Repository(c, namespaceObj.ID, enums.AuthManage)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
log.Error().Err(errors.New(utils.UnwrapJoinedErrors(err))).Msg("Resource not found")
return xerrors.GenDSErrCodeResourceNotFound(err)
}
return xerrors.NewDSError(c, xerrors.DSErrCodeUnknown)

Check warning on line 76 in pkg/handlers/distribution/blob/blob_delete.go

View check run for this annotation

Codecov / codecov/patch

pkg/handlers/distribution/blob/blob_delete.go#L70-L76

Added lines #L70 - L76 were not covered by tests
}
if !authChecked {

Check warning on line 78 in pkg/handlers/distribution/blob/blob_delete.go

View check run for this annotation

Codecov / codecov/patch

pkg/handlers/distribution/blob/blob_delete.go#L78

Added line #L78 was not covered by tests
log.Error().Int64("UserID", user.ID).Int64("NamespaceID", namespaceObj.ID).Msg("Auth check failed")
return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeUnauthorized, "No permission with this api")
return xerrors.NewDSError(c, xerrors.DSErrCodeUnauthorized)

Check warning on line 80 in pkg/handlers/distribution/blob/blob_delete.go

View check run for this annotation

Codecov / codecov/patch

pkg/handlers/distribution/blob/blob_delete.go#L80

Added line #L80 was not covered by tests
}

dgest, err := digest.Parse(strings.TrimPrefix(uri[strings.LastIndex(uri, "/"):], "/"))
Expand Down
13 changes: 11 additions & 2 deletions pkg/handlers/distribution/blob/blob_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,18 @@
log.Error().Err(err).Str("Name", repository).Msg("Get repository by name failed")
return xerrors.NewDSError(c, xerrors.DSErrCodeBlobUnknown)
}
if !h.authServiceFactory.New().Namespace(c, namespaceObj.ID, enums.AuthRead) {

authChecked, err := h.authServiceFactory.New().Namespace(c, namespaceObj.ID, enums.AuthRead)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
log.Error().Err(errors.New(utils.UnwrapJoinedErrors(err))).Msg("Resource not found")
return xerrors.GenDSErrCodeResourceNotFound(err)
}
return xerrors.NewDSError(c, xerrors.DSErrCodeUnknown)

Check warning on line 85 in pkg/handlers/distribution/blob/blob_get.go

View check run for this annotation

Codecov / codecov/patch

pkg/handlers/distribution/blob/blob_get.go#L79-L85

Added lines #L79 - L85 were not covered by tests
}
if !authChecked {

Check warning on line 87 in pkg/handlers/distribution/blob/blob_get.go

View check run for this annotation

Codecov / codecov/patch

pkg/handlers/distribution/blob/blob_get.go#L87

Added line #L87 was not covered by tests
log.Error().Int64("UserID", user.ID).Int64("NamespaceID", namespaceObj.ID).Msg("Auth check failed")
return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeUnauthorized, "No permission with this api")
return xerrors.NewDSError(c, xerrors.DSErrCodeUnauthorized)

Check warning on line 89 in pkg/handlers/distribution/blob/blob_get.go

View check run for this annotation

Codecov / codecov/patch

pkg/handlers/distribution/blob/blob_get.go#L89

Added line #L89 was not covered by tests
}

dgest, err := digest.Parse(strings.TrimPrefix(uri[strings.LastIndex(uri, "/"):], "/"))
Expand Down
14 changes: 12 additions & 2 deletions pkg/handlers/distribution/blob/blob_head.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"github.com/go-sigma/sigma/pkg/handlers/distribution/clients"
"github.com/go-sigma/sigma/pkg/modules/cacher"
"github.com/go-sigma/sigma/pkg/types/enums"
"github.com/go-sigma/sigma/pkg/utils"
"github.com/go-sigma/sigma/pkg/utils/imagerefs"
"github.com/go-sigma/sigma/pkg/utils/ptr"
"github.com/go-sigma/sigma/pkg/validators"
Expand Down Expand Up @@ -69,9 +70,18 @@
log.Error().Err(err).Str("Name", repository).Msg("Get repository by name failed")
return xerrors.NewDSError(c, xerrors.DSErrCodeBlobUnknown)
}
if !h.authServiceFactory.New().Namespace(c, namespaceObj.ID, enums.AuthRead) {

authChecked, err := h.authServiceFactory.New().Namespace(c, namespaceObj.ID, enums.AuthRead)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
log.Error().Err(errors.New(utils.UnwrapJoinedErrors(err))).Msg("Resource not found")
return xerrors.GenDSErrCodeResourceNotFound(err)
}
return xerrors.NewDSError(c, xerrors.DSErrCodeUnknown)

Check warning on line 80 in pkg/handlers/distribution/blob/blob_head.go

View check run for this annotation

Codecov / codecov/patch

pkg/handlers/distribution/blob/blob_head.go#L74-L80

Added lines #L74 - L80 were not covered by tests
}
if !authChecked {

Check warning on line 82 in pkg/handlers/distribution/blob/blob_head.go

View check run for this annotation

Codecov / codecov/patch

pkg/handlers/distribution/blob/blob_head.go#L82

Added line #L82 was not covered by tests
log.Error().Int64("UserID", user.ID).Int64("NamespaceID", namespaceObj.ID).Msg("Auth check failed")
return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeUnauthorized, "No permission with this api")
return xerrors.NewDSError(c, xerrors.DSErrCodeUnauthorized)

Check warning on line 84 in pkg/handlers/distribution/blob/blob_head.go

View check run for this annotation

Codecov / codecov/patch

pkg/handlers/distribution/blob/blob_head.go#L84

Added line #L84 was not covered by tests
}

dgest, err := digest.Parse(strings.TrimPrefix(uri[strings.LastIndex(uri, "/"):], "/"))
Expand Down
14 changes: 12 additions & 2 deletions pkg/handlers/distribution/manifest/manifest_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"github.com/go-sigma/sigma/pkg/dal/models"
"github.com/go-sigma/sigma/pkg/dal/query"
"github.com/go-sigma/sigma/pkg/types/enums"
"github.com/go-sigma/sigma/pkg/utils"
"github.com/go-sigma/sigma/pkg/utils/imagerefs"
"github.com/go-sigma/sigma/pkg/validators"
"github.com/go-sigma/sigma/pkg/xerrors"
Expand Down Expand Up @@ -67,9 +68,18 @@
log.Error().Err(err).Str("Name", repository).Msg("Get repository by name failed")
return xerrors.NewDSError(c, xerrors.DSErrCodeBlobUnknown)
}
if !h.authServiceFactory.New().Namespace(c, namespaceObj.ID, enums.AuthManage) {

authChecked, err := h.authServiceFactory.New().Namespace(c, namespaceObj.ID, enums.AuthManage)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
log.Error().Err(errors.New(utils.UnwrapJoinedErrors(err))).Msg("Resource not found")
return xerrors.GenDSErrCodeResourceNotFound(err)
}
return xerrors.NewDSError(c, xerrors.DSErrCodeUnknown)

Check warning on line 78 in pkg/handlers/distribution/manifest/manifest_delete.go

View check run for this annotation

Codecov / codecov/patch

pkg/handlers/distribution/manifest/manifest_delete.go#L74-L78

Added lines #L74 - L78 were not covered by tests
}
if !authChecked {
log.Error().Int64("UserID", user.ID).Int64("NamespaceID", namespaceObj.ID).Msg("Auth check failed")
return xerrors.NewHTTPError(c, xerrors.HTTPErrCodeUnauthorized, "No permission with this api")
return xerrors.NewDSError(c, xerrors.DSErrCodeUnauthorized)

Check warning on line 82 in pkg/handlers/distribution/manifest/manifest_delete.go

View check run for this annotation

Codecov / codecov/patch

pkg/handlers/distribution/manifest/manifest_delete.go#L82

Added line #L82 was not covered by tests
}

ref := strings.TrimPrefix(uri[strings.LastIndex(uri, "/"):], "/")
Expand Down
Loading
Loading