fix: fix quay adapter catalog api return error

Signed-off-by: chlins <chlins.zhang@gmail.com>
This commit is contained in:
chlins 2020-10-19 18:22:37 +08:00 committed by Ziming
parent 0caa5b8dae
commit e6f90f1559
6 changed files with 156 additions and 7 deletions

View File

@ -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)
}
}

View File

@ -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"

View File

@ -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"

View File

@ -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)
}

View File

@ -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))
}

View File

@ -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 (