Skip to content

Commit

Permalink
refactor auth
Browse files Browse the repository at this point in the history
Signed-off-by: Sylvia Lei <[email protected]>
  • Loading branch information
Wwwsylvia committed Apr 27, 2023
1 parent 2e56dd4 commit ebaf16a
Show file tree
Hide file tree
Showing 13 changed files with 83 additions and 681 deletions.
43 changes: 21 additions & 22 deletions cmd/notation/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ import (
"os"
"strings"

"github.com/notaryproject/notation/internal/auth"
"github.com/notaryproject/notation/internal/cmd"
"github.com/notaryproject/notation/pkg/auth"
credentials "github.com/oras-project/oras-credentials-go"
"github.com/spf13/cobra"
"golang.org/x/term"
orasauth "oras.land/oras-go/v2/registry/remote/auth"
)

const urlConfigureCredentialsStore = "https://notaryproject.dev/docs/how-to/registry-authentication/#configure-docker-credential-store-for-linux"

type loginOpts struct {
cmd.LoggingFlagOpts
SecureFlagOpts
Expand Down Expand Up @@ -83,37 +86,33 @@ func runLogin(ctx context.Context, opts *loginOpts) error {
return err
}
}
cred := newCredentialFromInput(
opts.Username,
opts.Password,
)

if err := validateAuthConfig(ctx, opts, serverAddress); err != nil {
return err
registry, err := getRegistryClient(ctx, &opts.SecureFlagOpts, serverAddress)
if err != nil {
return fmt.Errorf("failed to get registry client: %v", err)
}

nativeStore, err := auth.GetCredentialsStore(ctx, serverAddress)
registryName := registry.Reference.Registry
credsStore, err := auth.NewCredentialsStore()
if err != nil {
return fmt.Errorf("could not get the credentials store: %v", err)
return fmt.Errorf("failed to get credentials store: %v", err)
}

// init creds
creds := newCredentialFromInput(
opts.Username,
opts.Password,
)
if err = nativeStore.Store(serverAddress, creds); err != nil {
return fmt.Errorf("failed to store credentials: %v", err)
if err := credentials.Login(ctx, credsStore, registry, cred); err != nil {
if errors.Is(err, credentials.ErrPlaintextPutDisabled) {
// this error indicates that native store is not available
return fmt.Errorf("failed to save the credential for %s: credentials store config was not set up, please refer to %s for more information",
registryName, urlConfigureCredentialsStore)
}
return fmt.Errorf("failed to login to %s: %v", registryName, err)
}

fmt.Println("Login Succeeded")
return nil
}

func validateAuthConfig(ctx context.Context, opts *loginOpts, serverAddress string) error {
registry, err := getRegistryClient(ctx, &opts.SecureFlagOpts, serverAddress)
if err != nil {
return err
}
return registry.Ping(ctx)
}

func newCredentialFromInput(username, password string) orasauth.Credential {
c := orasauth.Credential{
Username: username,
Expand Down
15 changes: 6 additions & 9 deletions cmd/notation/logout.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import (
"errors"
"fmt"

"github.com/notaryproject/notation/internal/auth"
"github.com/notaryproject/notation/internal/cmd"
"github.com/notaryproject/notation/pkg/auth"
credentials "github.com/oras-project/oras-credentials-go"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -40,16 +41,12 @@ func logoutCommand(opts *logoutOpts) *cobra.Command {
func runLogout(ctx context.Context, opts *logoutOpts) error {
// set log level
ctx = opts.LoggingFlagOpts.SetLoggerLevel(ctx)

// initialize
serverAddress := opts.server
nativeStore, err := auth.GetCredentialsStore(ctx, serverAddress)
credsStore, err := auth.NewCredentialsStore()
if err != nil {
return err
return fmt.Errorf("failed to get credentials store: %v", err)
}
err = nativeStore.Erase(serverAddress)
if err != nil {
return err
if err := credentials.Logout(ctx, credsStore, opts.server); err != nil {
return fmt.Errorf("failed to logout of %s: %v", opts.server, err)
}

fmt.Println("Logout Succeeded")
Expand Down
58 changes: 23 additions & 35 deletions cmd/notation/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ package main
import (
"context"
"errors"
"fmt"
"net"
"net/http"

"github.com/notaryproject/notation-go/log"
notationregistry "github.com/notaryproject/notation-go/registry"
notationerrors "github.com/notaryproject/notation/cmd/notation/internal/errors"
notationauth "github.com/notaryproject/notation/internal/auth"
"github.com/notaryproject/notation/internal/trace"
"github.com/notaryproject/notation/internal/version"
loginauth "github.com/notaryproject/notation/pkg/auth"
"github.com/notaryproject/notation/pkg/configutil"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -161,7 +162,6 @@ func setHttpDebugLog(ctx context.Context, authClient *auth.Client) {

func getAuthClient(ctx context.Context, opts *SecureFlagOpts, ref registry.Reference) (*auth.Client, bool, error) {
var plainHTTP bool

if opts.PlainHTTP {
plainHTTP = opts.PlainHTTP
} else {
Expand All @@ -172,53 +172,41 @@ func getAuthClient(ctx context.Context, opts *SecureFlagOpts, ref registry.Refer
}
}
}
cred := auth.Credential{
Username: opts.Username,
Password: opts.Password,

credsStore, err := notationauth.NewCredentialsStore()
if err != nil {
return nil, false, fmt.Errorf("failed to get credentials store: %w", err)
}
if cred.Username == "" {
var cred auth.Credential
if opts.Username == "" && opts.Password == "" {
// use existing credential
var err error
cred, err = credsStore.Get(ctx, ref.Registry)
if err != nil {
return nil, false, err
}
} else if opts.Username == "" {
cred = auth.Credential{
RefreshToken: cred.Password,
}
}
if cred == auth.EmptyCredential {
var err error
cred, err = getSavedCreds(ctx, ref.Registry)
// local registry may not need credentials
if err != nil && !errors.Is(err, loginauth.ErrCredentialsConfigNotSet) {
return nil, false, err
} else {
cred = auth.Credential{
Username: opts.Username,
Password: opts.Password,
}
}

// build authClient
authClient := &auth.Client{
Credential: func(ctx context.Context, registry string) (auth.Credential, error) {
switch registry {
case ref.Host():
return cred, nil
default:
return auth.EmptyCredential, nil
}
},
Cache: auth.NewCache(),
ClientID: "notation",
Credential: auth.StaticCredential(ref.Host(), cred),
Cache: auth.NewCache(),
ClientID: "notation",
}
authClient.SetUserAgent("notation/" + version.GetVersion())

// update authClient
setHttpDebugLog(ctx, authClient)

return authClient, plainHTTP, nil
}

func getSavedCreds(ctx context.Context, serverAddress string) (auth.Credential, error) {
nativeStore, err := loginauth.GetCredentialsStore(ctx, serverAddress)
if err != nil {
return auth.EmptyCredential, err
}

return nativeStore.Get(serverAddress)
}

func pingReferrersAPI(ctx context.Context, remoteRepo *remote.Repository) error {
logger := log.GetLogger(ctx)
if err := remoteRepo.SetReferrersCapability(true); err != nil {
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ module github.com/notaryproject/notation
go 1.20

require (
github.com/docker/docker-credential-helpers v0.7.0
github.com/notaryproject/notation-core-go v1.0.0-rc.3
github.com/notaryproject/notation-go v1.0.0-rc.4
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.0-rc2
github.com/oras-project/oras-credentials-go v0.0.0-20230424070720-ba6b33c40845
github.com/sirupsen/logrus v1.9.0
github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5
Expand All @@ -17,6 +17,7 @@ require (

require (
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
github.com/go-ldap/ldap/v3 v3.4.4 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034=
github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
github.com/oras-project/oras-credentials-go v0.0.0-20230424070720-ba6b33c40845 h1:lE/TKx3cblnIRMazUdXgHmoM8TXs4fZqv3EXvEF3A2I=
github.com/oras-project/oras-credentials-go v0.0.0-20230424070720-ba6b33c40845/go.mod h1:yww9XqMCWjNh4Z7S5Ek7KeV9j/yhbyVxgSinGdNNwEg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
Expand Down
29 changes: 29 additions & 0 deletions internal/auth/credentials.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package auth

import (
"fmt"

"github.com/notaryproject/notation-go/dir"
credentials "github.com/oras-project/oras-credentials-go"
)

// NewCredentialsStore returns a new credentials store from the settings in the
// configuration file.
func NewCredentialsStore() (credentials.Store, error) {
configPath, err := dir.ConfigFS().SysPath(dir.PathConfigFile)
if err != nil {
return nil, fmt.Errorf("failed to load config file: %w", err)
}

opts := credentials.StoreOptions{AllowPlaintextPut: false}
primaryStore, err := credentials.NewStore(configPath, opts)
if err != nil {
return nil, fmt.Errorf("failed to create credential store from config file: %w", err)
}

fallbackStore, err := credentials.NewStoreFromDocker(opts)
if err != nil {
return nil, fmt.Errorf("failed to create credential store from docker config file: %w", err)
}
return credentials.NewStoreWithFallbacks(primaryStore, fallbackStore), nil
}
13 changes: 0 additions & 13 deletions pkg/auth/api.go

This file was deleted.

75 changes: 0 additions & 75 deletions pkg/auth/credential.go

This file was deleted.

Loading

0 comments on commit ebaf16a

Please sign in to comment.