From 73981062a9e9b76426b28029e14a5755b5cb6777 Mon Sep 17 00:00:00 2001 From: chlins Date: Mon, 19 Oct 2020 18:22:37 +0800 Subject: [PATCH] fix: fix quay adapter catalog api return error Signed-off-by: chlins --- src/replication/adapter/quay/adapter.go | 23 +++++-- .../adapter/quay/{ => auth}/apikey.go | 16 ++++- .../adapter/quay/{ => auth}/apikey_test.go | 16 ++++- .../adapter/quay/auth/authorizer.go | 62 +++++++++++++++++++ .../adapter/quay/auth/authorizer_test.go | 32 ++++++++++ src/replication/adapter/quay/types.go | 14 +++++ 6 files changed, 156 insertions(+), 7 deletions(-) rename src/replication/adapter/quay/{ => auth}/apikey.go (60%) rename src/replication/adapter/quay/{ => auth}/apikey_test.go (68%) create mode 100644 src/replication/adapter/quay/auth/authorizer.go create mode 100644 src/replication/adapter/quay/auth/authorizer_test.go diff --git a/src/replication/adapter/quay/adapter.go b/src/replication/adapter/quay/adapter.go index d07b1b614..55a324f98 100644 --- a/src/replication/adapter/quay/adapter.go +++ b/src/replication/adapter/quay/adapter.go @@ -1,3 +1,17 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package quay import ( @@ -13,9 +27,9 @@ import ( common_http "github.com/goharbor/harbor/src/common/http" "github.com/goharbor/harbor/src/common/http/modifier" "github.com/goharbor/harbor/src/lib/log" - "github.com/goharbor/harbor/src/pkg/registry/auth" adp "github.com/goharbor/harbor/src/replication/adapter" "github.com/goharbor/harbor/src/replication/adapter/native" + qauth "github.com/goharbor/harbor/src/replication/adapter/quay/auth" "github.com/goharbor/harbor/src/replication/model" "github.com/goharbor/harbor/src/replication/util" ) @@ -42,9 +56,8 @@ func init() { } func newAdapter(registry *model.Registry) (*adapter, error) { - var modifiers []modifier.Modifier - var ( + modifiers []modifier.Modifier autoCreateNs bool tokenAuthorizer, apiKeyAuthorizer modifier.Modifier ) @@ -55,10 +68,10 @@ func newAdapter(registry *model.Registry) (*adapter, error) { if err != nil { return nil, err } - tokenAuthorizer = auth.NewAuthorizer(jsonCred.AccountName, jsonCred.DockerCliPassword, registry.Insecure) + tokenAuthorizer = qauth.NewAuthorizer(jsonCred.AccountName, jsonCred.DockerCliPassword, registry.Insecure) if len(jsonCred.OAuth2Token) != 0 { autoCreateNs = true - apiKeyAuthorizer = NewAPIKeyAuthorizer("Authorization", fmt.Sprintf("Bearer %s", jsonCred.OAuth2Token), APIKeyInHeader) + apiKeyAuthorizer = qauth.NewAPIKeyAuthorizer("Authorization", fmt.Sprintf("Bearer %s", jsonCred.OAuth2Token), qauth.APIKeyInHeader) } } diff --git a/src/replication/adapter/quay/apikey.go b/src/replication/adapter/quay/auth/apikey.go similarity index 60% rename from src/replication/adapter/quay/apikey.go rename to src/replication/adapter/quay/auth/apikey.go index a92e0c201..4d0998e4d 100644 --- a/src/replication/adapter/quay/apikey.go +++ b/src/replication/adapter/quay/auth/apikey.go @@ -1,4 +1,18 @@ -package quay +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package auth import ( "fmt" diff --git a/src/replication/adapter/quay/apikey_test.go b/src/replication/adapter/quay/auth/apikey_test.go similarity index 68% rename from src/replication/adapter/quay/apikey_test.go rename to src/replication/adapter/quay/auth/apikey_test.go index cb2cafe9a..f1453068f 100644 --- a/src/replication/adapter/quay/apikey_test.go +++ b/src/replication/adapter/quay/auth/apikey_test.go @@ -1,4 +1,18 @@ -package quay +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package auth import ( "net/http" diff --git a/src/replication/adapter/quay/auth/authorizer.go b/src/replication/adapter/quay/auth/authorizer.go new file mode 100644 index 000000000..f568750b4 --- /dev/null +++ b/src/replication/adapter/quay/auth/authorizer.go @@ -0,0 +1,62 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package auth + +import ( + "net/http" + "regexp" + "strings" + + "github.com/goharbor/harbor/src/lib" + "github.com/goharbor/harbor/src/pkg/registry/auth" +) + +// authorizer is a customize authorizer for quay adapter which +// inherits lib authorizer. +type authorizer struct { + innerAuthorizer lib.Authorizer +} + +// NewAuthorizer creates an authorizer instance. +func NewAuthorizer(username, password string, insecure bool) lib.Authorizer { + return &authorizer{innerAuthorizer: auth.NewAuthorizer(username, password, insecure)} +} + +// Modify implements the lib.Authorizer. +func (a *authorizer) Modify(req *http.Request) error { + // if request api is catalog, remove the suffix _catalog + // to avoid lib authorizer parse scope and adds scope when + // request token. + // cause: https://github.com/goharbor/harbor/issues/13200 + if isCatalog(req) { + // rewrite path + oldPath := req.URL.Path + defer func() { + // resume path + req.URL.Path = oldPath + }() + req.URL.Path = strings.TrimRight(req.URL.Path, "_catalog") + } + + return a.innerAuthorizer.Modify(req) +} + +var catalog = regexp.MustCompile("/v2/_catalog$") + +// isCatalog detects if the api is /v2/_catalog. +func isCatalog(req *http.Request) bool { + path := strings.TrimRight(req.URL.Path, "/") + return catalog.MatchString(path) +} diff --git a/src/replication/adapter/quay/auth/authorizer_test.go b/src/replication/adapter/quay/auth/authorizer_test.go new file mode 100644 index 000000000..eeda9c46f --- /dev/null +++ b/src/replication/adapter/quay/auth/authorizer_test.go @@ -0,0 +1,32 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package auth + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestAuthorizer(t *testing.T) { + req1, err := http.NewRequest("GET", "http://1.1.1.1/v2/_catalog", nil) + assert.NoError(t, err) + assert.True(t, isCatalog(req1)) + + req2, err := http.NewRequest("GET", "http://1.1.1.1/v2/library/nginx/tags/list", nil) + assert.NoError(t, err) + assert.False(t, isCatalog(req2)) +} diff --git a/src/replication/adapter/quay/types.go b/src/replication/adapter/quay/types.go index 6d684b0aa..c1ca20741 100644 --- a/src/replication/adapter/quay/types.go +++ b/src/replication/adapter/quay/types.go @@ -1,3 +1,17 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package quay import (