Skip to content

Commit

Permalink
fix credential provider handling (#611)
Browse files Browse the repository at this point in the history
* fix crednetial provider handling

* add consumer type for signing service
  • Loading branch information
mandelsoft authored Dec 29, 2023
1 parent fade9c4 commit dce53f2
Show file tree
Hide file tree
Showing 11 changed files with 221 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
package identity

import (
"fmt"
"strings"

"github.com/open-component-model/ocm/pkg/common"
"github.com/open-component-model/ocm/pkg/contexts/credentials/cpi"
"github.com/open-component-model/ocm/pkg/contexts/credentials/identity/hostpath"
"github.com/open-component-model/ocm/pkg/listformat"
"github.com/open-component-model/ocm/pkg/utils"
)

const CONSUMER_TYPE = "Buildcredentials" + common.OCM_TYPE_GROUP_SUFFIX
Expand Down Expand Up @@ -43,3 +47,18 @@ It matches the <code>`+CONSUMER_TYPE+`</code> consumer type and additionally act
the <code>`+hostpath.IDENTITY_TYPE+`</code> type.`,
attrs)
}

func GetConsumerId(configURL string) (cpi.ConsumerIdentity, error) {
parsedURL, err := utils.ParseURL(configURL)
if err != nil {
return nil, fmt.Errorf("unable to parse url: %w", err)
}

id := cpi.NewConsumerIdentity(CONSUMER_TYPE)
id.SetNonEmptyValue(ID_HOSTNAME, parsedURL.Host)
id.SetNonEmptyValue(ID_SCHEME, parsedURL.Scheme)
id.SetNonEmptyValue(ID_PATHPREFIX, strings.Trim(parsedURL.Path, "/"))
id.SetNonEmptyValue(ID_PORT, parsedURL.Port())

return id, nil
}
16 changes: 16 additions & 0 deletions pkg/contexts/credentials/repositories/gardenerconfig/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import (
"github.com/mandelsoft/vfs/pkg/vfs"

"github.com/open-component-model/ocm/pkg/contexts/credentials/cpi"
"github.com/open-component-model/ocm/pkg/contexts/credentials/internal"
gardenercfgcpi "github.com/open-component-model/ocm/pkg/contexts/credentials/repositories/gardenerconfig/cpi"
"github.com/open-component-model/ocm/pkg/contexts/credentials/repositories/gardenerconfig/identity"
"github.com/open-component-model/ocm/pkg/contexts/datacontext/attrs/vfsattr"
"github.com/open-component-model/ocm/pkg/errors"
)
Expand All @@ -42,6 +44,8 @@ type Repository struct {
fs vfs.FileSystem
}

var _ cpi.ConsumerIdentityProvider = (*Repository)(nil)

func NewRepository(ctx cpi.Context, url string, configType gardenercfgcpi.ConfigType, cipher Cipher, key []byte, propagateConsumerIdentity bool) (*Repository, error) {
r := &Repository{
ctx: ctx,
Expand All @@ -60,6 +64,18 @@ func NewRepository(ctx cpi.Context, url string, configType gardenercfgcpi.Config

var _ cpi.Repository = &Repository{}

func (r *Repository) GetConsumerId(uctx ...internal.UsageContext) internal.ConsumerIdentity {
id, err := identity.GetConsumerId(r.url)
if err != nil {
return nil
}
return id
}

func (r *Repository) GetIdentityMatcher() string {
return identity.CONSUMER_TYPE
}

func (r *Repository) ExistsCredentials(name string) (bool, error) {
r.lock.RLock()
defer r.lock.RUnlock()
Expand Down
27 changes: 17 additions & 10 deletions pkg/contexts/credentials/repositories/gardenerconfig/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ package gardenerconfig

import (
"fmt"
"strings"

"github.com/open-component-model/ocm/pkg/contexts/credentials/cpi"
"github.com/open-component-model/ocm/pkg/contexts/credentials/internal"
gardenercfgcpi "github.com/open-component-model/ocm/pkg/contexts/credentials/repositories/gardenerconfig/cpi"
"github.com/open-component-model/ocm/pkg/contexts/credentials/repositories/gardenerconfig/identity"
"github.com/open-component-model/ocm/pkg/runtime"
"github.com/open-component-model/ocm/pkg/utils"
)

const (
Expand All @@ -34,6 +33,8 @@ type RepositorySpec struct {
PropagateConsumerIdentity bool `json:"propagateConsumerIdentity"`
}

var _ cpi.ConsumerIdentityProvider = (*RepositorySpec)(nil)

// NewRepositorySpec creates a new memory RepositorySpec.
func NewRepositorySpec(url string, configType gardenercfgcpi.ConfigType, cipher Cipher, propagateConsumerIdentity bool) *RepositorySpec {
return &RepositorySpec{
Expand Down Expand Up @@ -64,17 +65,23 @@ func (a *RepositorySpec) Repository(ctx cpi.Context, creds cpi.Credentials) (cpi
return repos.GetRepository(ctx, a.URL, a.ConfigType, a.Cipher, key, a.PropagateConsumerIdentity)
}

func getKey(cctx cpi.Context, configURL string) ([]byte, error) {
parsedURL, err := utils.ParseURL(configURL)
func (a *RepositorySpec) GetConsumerId(uctx ...internal.UsageContext) internal.ConsumerIdentity {
id, err := identity.GetConsumerId(a.URL)
if err != nil {
return nil, fmt.Errorf("unable to parse url: %w", err)
return nil
}
return id
}

func (a *RepositorySpec) GetIdentityMatcher() string {
return identity.CONSUMER_TYPE
}

id := cpi.NewConsumerIdentity(identity.CONSUMER_TYPE)
id.SetNonEmptyValue(identity.ID_HOSTNAME, parsedURL.Host)
id.SetNonEmptyValue(identity.ID_SCHEME, parsedURL.Scheme)
id.SetNonEmptyValue(identity.ID_PATHPREFIX, strings.Trim(parsedURL.Path, "/"))
id.SetNonEmptyValue(identity.ID_PORT, parsedURL.Port())
func getKey(cctx cpi.Context, configURL string) ([]byte, error) {
id, err := identity.GetConsumerId(configURL)
if err != nil {
return nil, err
}

creds, err := cpi.CredentialsForConsumer(cctx, id)
if err != nil {
Expand Down
16 changes: 16 additions & 0 deletions pkg/contexts/credentials/repositories/vault/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"golang.org/x/exp/slices"

"github.com/open-component-model/ocm/pkg/contexts/credentials/cpi"
"github.com/open-component-model/ocm/pkg/contexts/credentials/internal"
"github.com/open-component-model/ocm/pkg/contexts/credentials/repositories/vault/identity"
"github.com/open-component-model/ocm/pkg/optionutils"
"github.com/open-component-model/ocm/pkg/runtime"
)
Expand All @@ -32,6 +34,8 @@ type RepositorySpec struct {
Options `json:",inline"`
}

var _ cpi.ConsumerIdentityProvider = (*RepositorySpec)(nil)

// NewRepositorySpec creates a new memory RepositorySpec.
func NewRepositorySpec(url string, opts ...Option) *RepositorySpec {
return &RepositorySpec{
Expand Down Expand Up @@ -68,3 +72,15 @@ func (a *RepositorySpec) GetKey() cpi.ProviderIdentity {
}
return cpi.ProviderIdentity(spec.ServerURL)
}

func (a *RepositorySpec) GetConsumerId(uctx ...internal.UsageContext) internal.ConsumerIdentity {
id, err := identity.GetConsumerId(a.ServerURL, a.Namespace, a.SecretsEngine, a.Path)
if err != nil {
return nil
}
return id
}

func (a *RepositorySpec) GetIdentityMatcher() string {
return identity.CONSUMER_TYPE
}
11 changes: 10 additions & 1 deletion pkg/contexts/credentials/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
package credentials

import (
"github.com/open-component-model/ocm/pkg/errors"
"github.com/open-component-model/ocm/pkg/utils"
)

func GetProvidedConsumerId(obj interface{}, uctx ...UsageContext) ConsumerIdentity {
return utils.UnwrappingCall(obj, func(provider ConsumerIdentityProvider) ConsumerIdentity {
return provider.GetConsumerId()
return provider.GetConsumerId(uctx...)
})
}

Expand All @@ -19,3 +20,11 @@ func GetProvidedIdentityMatcher(obj interface{}) string {
return provider.GetIdentityMatcher()
})
}

func CredentialsFor(ctx ContextProvider, obj interface{}, uctx ...UsageContext) (Credentials, error) {
id := GetProvidedConsumerId(obj, uctx...)
if id == nil {
return nil, errors.ErrNotSupported(KIND_CONSUMER)
}
return CredentialsForConsumer(ctx, id)
}
32 changes: 30 additions & 2 deletions pkg/contexts/oci/repositories/ocireg/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import (
"github.com/containerd/containerd/reference"

"github.com/open-component-model/ocm/pkg/contexts/credentials"
"github.com/open-component-model/ocm/pkg/contexts/credentials/builtin/oci/identity"
"github.com/open-component-model/ocm/pkg/contexts/oci/cpi"
"github.com/open-component-model/ocm/pkg/runtime"
"github.com/open-component-model/ocm/pkg/utils"
)

const (
Expand Down Expand Up @@ -50,7 +52,10 @@ type RepositorySpec struct {
LegacyTypes *bool `json:"legacyTypes,omitempty"`
}

var _ cpi.RepositorySpec = (*RepositorySpec)(nil)
var (
_ cpi.RepositorySpec = (*RepositorySpec)(nil)
_ credentials.ConsumerIdentityProvider = (*RepositorySpec)(nil)
)

// NewRepositorySpec creates a new RepositorySpec.
func NewRepositorySpec(baseURL string) *RepositorySpec {
Expand Down Expand Up @@ -79,7 +84,7 @@ func (a *RepositorySpec) UniformRepositorySpec() *cpi.UniformRepositorySpec {
return cpi.UniformRepositorySpecForHostURL(Type, a.BaseURL)
}

func (a *RepositorySpec) Repository(ctx cpi.Context, creds credentials.Credentials) (cpi.Repository, error) {
func (a *RepositorySpec) getInfo(creds credentials.Credentials) (*RepositoryInfo, error) {
var u *url.URL
info := &RepositoryInfo{}
legacy := false
Expand Down Expand Up @@ -116,5 +121,28 @@ func (a *RepositorySpec) Repository(ctx cpi.Context, creds credentials.Credentia
info.Creds = creds
info.Legacy = legacy

return info, nil
}

func (a *RepositorySpec) Repository(ctx cpi.Context, creds credentials.Credentials) (cpi.Repository, error) {
info, err := a.getInfo(creds)
if err != nil {
return nil, err
}
return NewRepository(ctx, a, info)
}

func (a *RepositorySpec) GetConsumerId(uctx ...credentials.UsageContext) credentials.ConsumerIdentity {
info, err := a.getInfo(nil)
if err != nil {
return nil
}
if c, ok := utils.Optional(uctx...).(credentials.StringUsageContext); ok {
return identity.GetConsumerId(info.Locator, c.String())
}
return identity.GetConsumerId(info.Locator, "")
}

func (a *RepositorySpec) GetIdentityMatcher() string {
return identity.CONSUMER_TYPE
}
7 changes: 7 additions & 0 deletions pkg/contexts/ocm/cpi/repocpi/bridge_r.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/open-component-model/ocm/pkg/errors"
"github.com/open-component-model/ocm/pkg/refmgmt"
"github.com/open-component-model/ocm/pkg/refmgmt/resource"
"github.com/open-component-model/ocm/pkg/utils"
)

type ComponentAccessInfo struct {
Expand Down Expand Up @@ -42,6 +43,8 @@ type repositoryBridge struct {
impl RepositoryImpl
}

var _ utils.Unwrappable = (*repositoryBridge)(nil)

func newRepositoryBridge(impl RepositoryImpl, kind string, closer ...io.Closer) RepositoryBridge {
base := resource.NewSimpleResourceImplBase[cpi.Repository](closer...)
b := &repositoryBridge{
Expand All @@ -66,6 +69,10 @@ func (b *repositoryBridge) GetContext() cpi.Context {
return b.ctx
}

func (b *repositoryBridge) Unwrap() interface{} {
return b.impl
}

func (b *repositoryBridge) GetSpecification() cpi.RepositorySpec {
return b.impl.GetSpecification()
}
Expand Down
53 changes: 53 additions & 0 deletions pkg/contexts/ocm/repositories/genericocireg/cred_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// SPDX-FileCopyrightText: 2022 SAP SE or an SAP affiliate company and Open Component Model contributors.
//
// SPDX-License-Identifier: Apache-2.0

package genericocireg_test

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/open-component-model/ocm/pkg/common"
"github.com/open-component-model/ocm/pkg/contexts/credentials"
ociidentity "github.com/open-component-model/ocm/pkg/contexts/credentials/builtin/oci/identity"
"github.com/open-component-model/ocm/pkg/contexts/datacontext"
"github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/ocireg"
. "github.com/open-component-model/ocm/pkg/testutils"

"github.com/open-component-model/ocm/pkg/contexts/ocm"
"github.com/open-component-model/ocm/pkg/finalizer"
)

var _ = Describe("consumer id handling", func() {
It("creates a dummy component", func() {
var finalize finalizer.Finalizer
defer Defer(finalize.Finalize)

ctx := ocm.New(datacontext.MODE_EXTENDED)
credctx := ctx.CredentialsContext()

creds := ociidentity.SimpleCredentials("test", "password")
spec := ocireg.NewRepositorySpec("ghcr.io/open-component-model/test")

id := credentials.GetProvidedConsumerId(spec, credentials.StringUsageContext(COMPONENT))
Expect(id).To(Equal(credentials.NewConsumerIdentity(ociidentity.CONSUMER_TYPE, ociidentity.ID_HOSTNAME, "ghcr.io", ociidentity.ID_PATHPREFIX, "open-component-model/test/component-descriptors/"+COMPONENT)))

id = credentials.GetProvidedConsumerId(spec)
Expect(id).To(Equal(credentials.NewConsumerIdentity(ociidentity.CONSUMER_TYPE, ociidentity.ID_HOSTNAME, "ghcr.io", ociidentity.ID_PATHPREFIX, "open-component-model/test")))

credctx.SetCredentialsForConsumer(id, creds)

repo := finalizer.ClosingWith(&finalize, Must(DefaultContext.RepositoryForSpec(spec)))

id = credentials.GetProvidedConsumerId(repo, credentials.StringUsageContext(COMPONENT))
Expect(id).To(Equal(credentials.NewConsumerIdentity(ociidentity.CONSUMER_TYPE, ociidentity.ID_HOSTNAME, "ghcr.io", ociidentity.ID_PATHPREFIX, "open-component-model/test/component-descriptors/"+COMPONENT)))

creds = Must(credentials.CredentialsForConsumer(credctx, id))

Expect(creds.Properties()).To(Equal(common.Properties{
ociidentity.ATTR_USERNAME: "test",
ociidentity.ATTR_PASSWORD: "password",
}))
})

})
16 changes: 16 additions & 0 deletions pkg/contexts/ocm/repositories/genericocireg/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ package genericocireg

import (
"encoding/json"
"path"

"github.com/sirupsen/logrus"

"github.com/open-component-model/ocm/pkg/contexts/credentials"
"github.com/open-component-model/ocm/pkg/contexts/oci"
"github.com/open-component-model/ocm/pkg/contexts/oci/repositories/ocireg"
"github.com/open-component-model/ocm/pkg/contexts/ocm/cpi"
"github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/genericocireg/componentmapping"
"github.com/open-component-model/ocm/pkg/errors"
"github.com/open-component-model/ocm/pkg/runtime"
"github.com/open-component-model/ocm/pkg/utils"
)

// ComponentNameMapping describes the method that is used to map the "Component Name", "Component Version"-tuples
Expand Down Expand Up @@ -99,6 +102,7 @@ var (
_ cpi.PrefixProvider = (*RepositorySpec)(nil)
_ cpi.IntermediateRepositorySpecAspect = (*RepositorySpec)(nil)
_ json.Marshaler = (*RepositorySpec)(nil)
_ credentials.ConsumerIdentityProvider = (*RepositorySpec)(nil)
)

func NewRepositorySpec(spec oci.RepositorySpec, meta *ComponentRepositoryMeta) *RepositorySpec {
Expand Down Expand Up @@ -165,6 +169,18 @@ func (s *RepositorySpec) Repository(ctx cpi.Context, creds credentials.Credentia
return NewRepository(ctx, &s.ComponentRepositoryMeta, r), nil
}

func (s *RepositorySpec) GetConsumerId(uctx ...credentials.UsageContext) credentials.ConsumerIdentity {
prefix := s.SubPath
if c, ok := utils.Optional(uctx...).(credentials.StringUsageContext); ok {
prefix = path.Join(prefix, componentmapping.ComponentDescriptorNamespace, c.String())
}
return credentials.GetProvidedConsumerId(s.RepositorySpec, credentials.StringUsageContext(prefix))
}

func (s *RepositorySpec) GetIdentityMatcher() string {
return credentials.GetProvidedIdentityMatcher(s.RepositorySpec)
}

func DefaultComponentRepositoryMeta(meta *ComponentRepositoryMeta) *ComponentRepositoryMeta {
if meta == nil {
meta = &ComponentRepositoryMeta{}
Expand Down
Loading

0 comments on commit dce53f2

Please sign in to comment.