diff --git a/src/server/middleware/contenttrust/contenttrust.go b/src/server/middleware/contenttrust/contenttrust.go index 524532e14..dd313b328 100644 --- a/src/server/middleware/contenttrust/contenttrust.go +++ b/src/server/middleware/contenttrust/contenttrust.go @@ -1,11 +1,8 @@ package contenttrust import ( - "github.com/goharbor/harbor/src/common/utils/log" - "github.com/goharbor/harbor/src/core/config" - "github.com/goharbor/harbor/src/core/middlewares/util" internal_errors "github.com/goharbor/harbor/src/internal/error" - "github.com/goharbor/harbor/src/pkg/signature/notary" + "github.com/goharbor/harbor/src/pkg/signature" serror "github.com/goharbor/harbor/src/server/error" "github.com/goharbor/harbor/src/server/middleware" "net/http" @@ -27,7 +24,7 @@ func Middleware() func(http.Handler) http.Handler { rec := httptest.NewRecorder() next.ServeHTTP(rec, req) if rec.Result().StatusCode == http.StatusOK { - match, err := matchNotaryDigest(mf) + match, err := isArtifactSigned(req, mf) if err != nil { serror.SendError(rw, err) return @@ -61,36 +58,12 @@ func validate(req *http.Request) (bool, middleware.ArtifactInfo) { return true, af } -func matchNotaryDigest(af middleware.ArtifactInfo) (bool, error) { - if NotaryEndpoint == "" { - NotaryEndpoint = config.InternalNotaryEndpoint() - } - targets, err := notary.GetInternalTargets(NotaryEndpoint, util.TokenUsername, af.Repository) +// isArtifactSigned use the sign manager to check the signature, it could handle pull by tag or digtest +// if pull by digest, any tag of the artifact is signed, will return true. +func isArtifactSigned(req *http.Request, art middleware.ArtifactInfo) (bool, error) { + checker, err := signature.GetManager().GetCheckerByRepo(req.Context(), art.Repository) if err != nil { return false, err } - for _, t := range targets { - if af.Digest != "" { - d, err := notary.DigestFromTarget(t) - if err != nil { - return false, err - } - if af.Digest == d { - return true, nil - } - } else { - if t.Tag == af.Tag { - log.Debugf("found reference: %s in notary, try to match digest.", af.Tag) - d, err := notary.DigestFromTarget(t) - if err != nil { - return false, err - } - if af.Digest == d { - return true, nil - } - } - } - } - log.Debugf("image: %#v, not found in notary", af) - return false, nil + return checker.IsArtifactSigned(art.Digest), nil } diff --git a/src/server/middleware/immutable/deletemf.go b/src/server/middleware/immutable/deletemf.go deleted file mode 100644 index 7e6b4bc3d..000000000 --- a/src/server/middleware/immutable/deletemf.go +++ /dev/null @@ -1,61 +0,0 @@ -package immutable - -import ( - "errors" - "fmt" - "github.com/goharbor/harbor/src/api/artifact" - "github.com/goharbor/harbor/src/api/tag" - common_util "github.com/goharbor/harbor/src/common/utils" - internal_errors "github.com/goharbor/harbor/src/internal/error" - serror "github.com/goharbor/harbor/src/server/error" - "github.com/goharbor/harbor/src/server/middleware" - "net/http" -) - -// MiddlewareDelete ... -func MiddlewareDelete() func(http.Handler) http.Handler { - return func(next http.Handler) http.Handler { - return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { - if err := handleDelete(req); err != nil { - var e *ErrImmutable - if errors.As(err, &e) { - pkgE := internal_errors.New(e).WithCode(internal_errors.PreconditionCode) - serror.SendError(rw, pkgE) - return - } - pkgE := internal_errors.New(fmt.Errorf("error occurred when to handle request in immutable handler: %v", err)).WithCode(internal_errors.GeneralCode) - serror.SendError(rw, pkgE) - return - } - next.ServeHTTP(rw, req) - }) - } -} - -// handleDelete ... -func handleDelete(req *http.Request) error { - art, ok := middleware.ArtifactInfoFromContext(req.Context()) - if !ok { - return errors.New("cannot get the manifest information from request context") - } - - af, err := artifact.Ctl.GetByReference(req.Context(), art.Repository, art.Digest, &artifact.Option{ - WithTag: true, - TagOption: &tag.Option{WithImmutableStatus: true}, - }) - if err != nil { - if internal_errors.IsErr(err, internal_errors.NotFoundCode) { - return nil - } - return err - } - - _, repoName := common_util.ParseRepository(art.Repository) - for _, tag := range af.Tags { - if tag.Immutable { - return NewErrImmutable(repoName, tag.Name) - } - } - - return nil -} diff --git a/src/server/middleware/immutable/deletemf_test.go b/src/server/middleware/immutable/deletemf_test.go deleted file mode 100644 index f9933ba67..000000000 --- a/src/server/middleware/immutable/deletemf_test.go +++ /dev/null @@ -1,3 +0,0 @@ -package immutable - -// Tests are in the push_mf_test diff --git a/src/server/middleware/immutable/pushmf.go b/src/server/middleware/immutable/pushmf.go index 0b1ea14d5..738a06fbe 100644 --- a/src/server/middleware/immutable/pushmf.go +++ b/src/server/middleware/immutable/pushmf.go @@ -12,8 +12,8 @@ import ( "net/http" ) -// MiddlewarePush ... -func MiddlewarePush() func(http.Handler) http.Handler { +// Middleware ... +func Middleware() func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { if err := handlePush(req); err != nil { diff --git a/src/server/middleware/immutable/pushmf_test.go b/src/server/middleware/immutable/pushmf_test.go index 07395c0bf..69751fbbf 100644 --- a/src/server/middleware/immutable/pushmf_test.go +++ b/src/server/middleware/immutable/pushmf_test.go @@ -54,37 +54,7 @@ func doPutManifestRequest(projectID int64, projectName, name, tag, dgt string, n } *req = *(req.WithContext(internal_orm.NewContext(context.TODO(), dao.GetOrmer()))) *req = *(req.WithContext(context.WithValue(req.Context(), middleware.ArtifactInfoKey, afInfo))) - h := MiddlewarePush()(n) - h.ServeHTTP(util.NewCustomResponseWriter(rr), req) - - return rr.Code -} - -func doDeleteManifestRequest(projectID int64, projectName, name, tag, dgt string, next ...http.HandlerFunc) int { - repository := fmt.Sprintf("%s/%s", projectName, name) - - url := fmt.Sprintf("/v2/%s/manifests/%s", repository, tag) - req, _ := http.NewRequest("DELETE", url, nil) - - afInfo := &middleware.ArtifactInfo{ - ProjectName: projectName, - Repository: repository, - Tag: tag, - Digest: dgt, - } - rr := httptest.NewRecorder() - - var n http.HandlerFunc - if len(next) > 0 { - n = next[0] - } else { - n = func(w http.ResponseWriter, req *http.Request) { - w.WriteHeader(http.StatusCreated) - } - } - *req = *(req.WithContext(internal_orm.NewContext(context.TODO(), dao.GetOrmer()))) - *req = *(req.WithContext(context.WithValue(req.Context(), middleware.ArtifactInfoKey, afInfo))) - h := MiddlewareDelete()(n) + h := Middleware()(n) h.ServeHTTP(util.NewCustomResponseWriter(rr), req) return rr.Code @@ -203,12 +173,6 @@ func (suite *HandlerSuite) TestPutDeleteManifestCreated() { code2 := doPutManifestRequest(projectID, projectName, "photon", "latest", dgt) suite.Equal(http.StatusCreated, code2) - code3 := doDeleteManifestRequest(projectID, projectName, "photon", "release-1.10", dgt) - suite.Equal(http.StatusPreconditionFailed, code3) - - code4 := doDeleteManifestRequest(projectID, projectName, "photon", "latest", dgt) - suite.Equal(http.StatusPreconditionFailed, code4) - } func TestMain(m *testing.M) { diff --git a/src/server/registry/route.go b/src/server/registry/route.go index dc07a1b23..97fa12f0c 100644 --- a/src/server/registry/route.go +++ b/src/server/registry/route.go @@ -58,12 +58,11 @@ func RegisterRoutes() { root.NewRoute(). Method(http.MethodDelete). Path("/*/manifests/:reference"). - Middleware(immutable.MiddlewareDelete()). HandlerFunc(deleteManifest) root.NewRoute(). Method(http.MethodPut). Path("/*/manifests/:reference"). - Middleware(immutable.MiddlewarePush()). + Middleware(immutable.Middleware()). Middleware(blob.PutManifestMiddleware()). HandlerFunc(putManifest) // initiate blob upload