Skip to content

Commit 4fcbfd2

Browse files
committed
refactor: reorganize auth and credential
Signed-off-by: Terry Howe <terrylhowe@gmail.com>
1 parent ba36eb5 commit 4fcbfd2

24 files changed

+877
-613
lines changed

example_copy_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
"oras.land/oras-go/v2/internal/spec"
3838
"oras.land/oras-go/v2/registry/remote"
3939
"oras.land/oras-go/v2/registry/remote/auth"
40+
"oras.land/oras-go/v2/registry/remote/credentials"
4041
"oras.land/oras-go/v2/registry/remote/retry"
4142
)
4243

@@ -451,7 +452,7 @@ func Example_extendedCopyArtifactAndReferrersToRepository() {
451452
repo.Client = &auth.Client{
452453
Client: retry.DefaultClient,
453454
Cache: auth.NewCache(),
454-
Credential: auth.StaticCredential(registry, auth.Credential{
455+
Credential: credentials.StaticCredential(registry, credentials.Credential{
455456
Username: "username",
456457
Password: "password",
457458
}),

example_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func Example_pullFilesFromRemoteRepository() {
5050
repo.Client = &auth.Client{
5151
Client: retry.DefaultClient,
5252
Cache: auth.NewCache(),
53-
Credential: auth.StaticCredential(reg, auth.Credential{
53+
Credential: credentials.StaticCredential(reg, credentials.Credential{
5454
Username: "username",
5555
Password: "password",
5656
}),
@@ -85,7 +85,7 @@ func Example_pullImageFromRemoteRepository() {
8585
repo.Client = &auth.Client{
8686
Client: retry.DefaultClient,
8787
Cache: auth.NewCache(),
88-
Credential: auth.StaticCredential(reg, auth.Credential{
88+
Credential: credentials.StaticCredential(reg, credentials.Credential{
8989
Username: "username",
9090
Password: "password",
9191
}),
@@ -127,7 +127,7 @@ func Example_pullImageUsingDockerCredentials() {
127127
repo.Client = &auth.Client{
128128
Client: retry.DefaultClient,
129129
Cache: auth.NewCache(),
130-
Credential: credentials.Credential(credStore), // Use the credentials store
130+
Credential: remote.Credential(credStore), // Use the credentials store
131131
}
132132

133133
// 2. Copy from the remote repository to the OCI layout store
@@ -190,7 +190,7 @@ func Example_pushFilesToRemoteRepository() {
190190
repo.Client = &auth.Client{
191191
Client: retry.DefaultClient,
192192
Cache: auth.NewCache(),
193-
Credential: auth.StaticCredential(reg, auth.Credential{
193+
Credential: credentials.StaticCredential(reg, credentials.Credential{
194194
Username: "username",
195195
Password: "password",
196196
}),
@@ -218,7 +218,7 @@ func Example_attachBlobToRemoteRepository() {
218218
repo.Client = &auth.Client{
219219
Client: retry.DefaultClient,
220220
Cache: auth.NewCache(),
221-
Credential: auth.StaticCredential(registry, auth.Credential{
221+
Credential: credentials.StaticCredential(registry, credentials.Credential{
222222
Username: "username",
223223
Password: "password",
224224
}),
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ See the License for the specific language governing permissions and
1313
limitations under the License.
1414
*/
1515

16-
package credentials
16+
package remote
1717

1818
import (
1919
"context"
2020
"errors"
2121
"fmt"
2222

23-
"oras.land/oras-go/v2/registry/remote"
2423
"oras.land/oras-go/v2/registry/remote/auth"
24+
"oras.land/oras-go/v2/registry/remote/credentials"
2525
)
2626

2727
// ErrClientTypeUnsupported is thrown by Login() when the registry's client type
@@ -32,7 +32,7 @@ var ErrClientTypeUnsupported = errors.New("client type not supported")
3232
// registry's client should be nil or of type *auth.Client. Login uses
3333
// a client local to the function and will not modify the original client of
3434
// the registry.
35-
func Login(ctx context.Context, store Store, reg *remote.Registry, cred auth.Credential) error {
35+
func Login(ctx context.Context, store credentials.Store, reg *Registry, cred credentials.Credential) error {
3636
// create a clone of the original registry for login purpose
3737
regClone := *reg
3838
// we use the original client if applicable, otherwise use a default client
@@ -47,7 +47,7 @@ func Login(ctx context.Context, store Store, reg *remote.Registry, cred auth.Cre
4747
}
4848
regClone.Client = &authClient
4949
// update credentials with the client
50-
authClient.Credential = auth.StaticCredential(reg.Reference.Registry, cred)
50+
authClient.Credential = credentials.StaticCredential(reg.Reference.Registry, cred)
5151
// validate and store the credential
5252
if err := regClone.Ping(ctx); err != nil {
5353
return fmt.Errorf("failed to validate the credentials for %s: %w", regClone.Reference.Registry, err)
@@ -60,7 +60,7 @@ func Login(ctx context.Context, store Store, reg *remote.Registry, cred auth.Cre
6060
}
6161

6262
// Logout provides the logout functionality given the registry name.
63-
func Logout(ctx context.Context, store Store, registryName string) error {
63+
func Logout(ctx context.Context, store credentials.Store, registryName string) error {
6464
registryName = ServerAddressFromRegistry(registryName)
6565
if err := store.Delete(ctx, registryName); err != nil {
6666
return fmt.Errorf("failed to delete the credential for %s: %w", registryName, err)
@@ -69,11 +69,11 @@ func Logout(ctx context.Context, store Store, registryName string) error {
6969
}
7070

7171
// Credential returns a Credential() function that can be used by auth.Client.
72-
func Credential(store Store) auth.CredentialFunc {
73-
return func(ctx context.Context, hostport string) (auth.Credential, error) {
72+
func Credential(store credentials.Store) credentials.CredentialFunc {
73+
return func(ctx context.Context, hostport string) (credentials.Credential, error) {
7474
hostport = ServerAddressFromHostname(hostport)
7575
if hostport == "" {
76-
return auth.EmptyCredential, nil
76+
return credentials.EmptyCredential, nil
7777
}
7878
return store.Get(ctx, hostport)
7979
}

registry/remote/auth/client.go

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"net/url"
2828
"strings"
2929

30+
"oras.land/oras-go/v2/registry/remote/credentials"
3031
"oras.land/oras-go/v2/registry/remote/internal/errutil"
3132
"oras.land/oras-go/v2/registry/remote/retry"
3233
)
@@ -58,29 +59,6 @@ var maxResponseBytes int64 = 128 * 1024 // 128 KiB
5859
// See also ClientID.
5960
var defaultClientID = "oras-go"
6061

61-
// CredentialFunc represents a function that resolves the credential for the
62-
// given registry (i.e. host:port).
63-
//
64-
// [EmptyCredential] is a valid return value and should not be considered as
65-
// an error.
66-
type CredentialFunc func(ctx context.Context, hostport string) (Credential, error)
67-
68-
// StaticCredential specifies static credentials for the given host.
69-
func StaticCredential(registry string, cred Credential) CredentialFunc {
70-
if registry == "docker.io" {
71-
// it is expected that traffic targeting "docker.io" will be redirected
72-
// to "registry-1.docker.io"
73-
// reference: https://github.com/moby/moby/blob/v24.0.0-beta.2/registry/config.go#L25-L48
74-
registry = "registry-1.docker.io"
75-
}
76-
return func(_ context.Context, hostport string) (Credential, error) {
77-
if hostport == registry {
78-
return cred, nil
79-
}
80-
return EmptyCredential, nil
81-
}
82-
}
83-
8462
// Client is an auth-decorated HTTP client.
8563
// Its zero value is a usable client that uses http.DefaultClient with no cache.
8664
type Client struct {
@@ -102,7 +80,7 @@ type Client struct {
10280
// EmptyCredential is a valid return value and should not be considered as
10381
// an error.
10482
// If nil, the credential is always resolved to EmptyCredential.
105-
Credential CredentialFunc
83+
Credential credentials.CredentialFunc
10684

10785
// Cache caches credentials for direct accessing the remote registry.
10886
// If nil, no cache is used.
@@ -140,9 +118,9 @@ func (c *Client) send(req *http.Request) (*http.Response, error) {
140118
}
141119

142120
// credential resolves the credential for the given registry.
143-
func (c *Client) credential(ctx context.Context, reg string) (Credential, error) {
121+
func (c *Client) credential(ctx context.Context, reg string) (credentials.Credential, error) {
144122
if c.Credential == nil {
145-
return EmptyCredential, nil
123+
return credentials.EmptyCredential, nil
146124
}
147125
return c.Credential(ctx, reg)
148126
}
@@ -283,7 +261,7 @@ func (c *Client) fetchBasicAuth(ctx context.Context, registry string) (string, e
283261
if err != nil {
284262
return "", fmt.Errorf("failed to resolve credential: %w", err)
285263
}
286-
if cred == EmptyCredential {
264+
if cred == credentials.EmptyCredential {
287265
return "", ErrBasicCredentialNotFound
288266
}
289267
if cred.Username == "" || cred.Password == "" {
@@ -302,7 +280,7 @@ func (c *Client) fetchBearerToken(ctx context.Context, registry, realm, service
302280
if cred.AccessToken != "" {
303281
return cred.AccessToken, nil
304282
}
305-
if cred == EmptyCredential || (cred.RefreshToken == "" && !c.ForceAttemptOAuth2) {
283+
if cred == credentials.EmptyCredential || (cred.RefreshToken == "" && !c.ForceAttemptOAuth2) {
306284
return c.fetchDistributionToken(ctx, realm, service, scopes, cred.Username, cred.Password)
307285
}
308286
return c.fetchOAuth2Token(ctx, realm, service, scopes, cred)
@@ -362,7 +340,7 @@ func (c *Client) fetchDistributionToken(ctx context.Context, realm, service stri
362340

363341
// fetchOAuth2Token fetches an OAuth2 access token.
364342
// Reference: https://distribution.github.io/distribution/spec/auth/oauth/
365-
func (c *Client) fetchOAuth2Token(ctx context.Context, realm, service string, scopes []string, cred Credential) (string, error) {
343+
func (c *Client) fetchOAuth2Token(ctx context.Context, realm, service string, scopes []string, cred credentials.Credential) (string, error) {
366344
form := url.Values{}
367345
if cred.RefreshToken != "" {
368346
form.Set("grant_type", "refresh_token")

0 commit comments

Comments
 (0)