Skip to content

Commit 254f3f6

Browse files
committed
refactor: reorganize auth and credential
Signed-off-by: Terry Howe <terrylhowe@gmail.com>
1 parent 71beefa commit 254f3f6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1804
-889
lines changed

docs/tutorial/quickstart.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func main() {
6868
repo.Client = &auth.Client{
6969
Client: retry.DefaultClient,
7070
Cache: auth.NewCache(),
71-
Credential: auth.StaticCredential(repo.Reference.Registry, auth.Credential{
71+
CredentialFunc: auth.StaticCredential(repo.Reference.Registry, properties.Credential{
7272
Username: "username",
7373
Password: "password",
7474
}),
@@ -287,7 +287,7 @@ func main() {
287287
repo.Client = &auth.Client{
288288
Client: retry.DefaultClient,
289289
Cache: auth.NewCache(),
290-
Credential: auth.StaticCredential(repo.Reference.Registry, auth.Credential{
290+
CredentialFunc: auth.StaticCredential(repo.Reference.Registry, properties.Credential{
291291
Username: "username",
292292
Password: "password",
293293
}),

example_copy_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ 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"
41+
"oras.land/oras-go/v2/registry/remote/properties"
4042
"oras.land/oras-go/v2/registry/remote/retry"
4143
)
4244

@@ -451,7 +453,7 @@ func Example_extendedCopyArtifactAndReferrersToRepository() {
451453
repo.Client = &auth.Client{
452454
Client: retry.DefaultClient,
453455
Cache: auth.NewCache(),
454-
Credential: auth.StaticCredential(registry, auth.Credential{
456+
CredentialFunc: credentials.StaticCredentialFunc(registry, properties.Credential{
455457
Username: "username",
456458
Password: "password",
457459
}),

example_test.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"oras.land/oras-go/v2/registry/remote"
2727
"oras.land/oras-go/v2/registry/remote/auth"
2828
"oras.land/oras-go/v2/registry/remote/credentials"
29+
"oras.land/oras-go/v2/registry/remote/properties"
2930
"oras.land/oras-go/v2/registry/remote/retry"
3031
)
3132

@@ -50,7 +51,7 @@ func Example_pullFilesFromRemoteRepository() {
5051
repo.Client = &auth.Client{
5152
Client: retry.DefaultClient,
5253
Cache: auth.NewCache(),
53-
Credential: auth.StaticCredential(reg, auth.Credential{
54+
CredentialFunc: credentials.StaticCredentialFunc(reg, properties.Credential{
5455
Username: "username",
5556
Password: "password",
5657
}),
@@ -85,7 +86,7 @@ func Example_pullImageFromRemoteRepository() {
8586
repo.Client = &auth.Client{
8687
Client: retry.DefaultClient,
8788
Cache: auth.NewCache(),
88-
Credential: auth.StaticCredential(reg, auth.Credential{
89+
CredentialFunc: credentials.StaticCredentialFunc(reg, properties.Credential{
8990
Username: "username",
9091
Password: "password",
9192
}),
@@ -125,9 +126,9 @@ func Example_pullImageUsingDockerCredentials() {
125126
panic(err)
126127
}
127128
repo.Client = &auth.Client{
128-
Client: retry.DefaultClient,
129-
Cache: auth.NewCache(),
130-
Credential: credentials.Credential(credStore), // Use the credentials store
129+
Client: retry.DefaultClient,
130+
Cache: auth.NewCache(),
131+
CredentialFunc: remote.GetCredentialFunc(credStore), // Use the credentials store
131132
}
132133

133134
// 2. Copy from the remote repository to the OCI layout store
@@ -190,7 +191,7 @@ func Example_pushFilesToRemoteRepository() {
190191
repo.Client = &auth.Client{
191192
Client: retry.DefaultClient,
192193
Cache: auth.NewCache(),
193-
Credential: auth.StaticCredential(reg, auth.Credential{
194+
CredentialFunc: credentials.StaticCredentialFunc(reg, properties.Credential{
194195
Username: "username",
195196
Password: "password",
196197
}),
@@ -218,7 +219,7 @@ func Example_attachBlobToRemoteRepository() {
218219
repo.Client = &auth.Client{
219220
Client: retry.DefaultClient,
220221
Cache: auth.NewCache(),
221-
Credential: auth.StaticCredential(registry, auth.Credential{
222+
CredentialFunc: credentials.StaticCredentialFunc(registry, properties.Credential{
222223
Username: "username",
223224
Password: "password",
224225
}),
Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@ 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"
25+
"oras.land/oras-go/v2/registry/remote/properties"
2526
)
2627

2728
// ErrClientTypeUnsupported is thrown by Login() when the registry's client type
@@ -32,7 +33,7 @@ var ErrClientTypeUnsupported = errors.New("client type not supported")
3233
// registry's client should be nil or of type *auth.Client. Login uses
3334
// a client local to the function and will not modify the original client of
3435
// the registry.
35-
func Login(ctx context.Context, store Store, reg *remote.Registry, cred auth.Credential) error {
36+
func Login(ctx context.Context, store credentials.Store, reg *Registry, cred properties.Credential) error {
3637
// create a clone of the original registry for login purpose
3738
regClone := *reg
3839
// we use the original client if applicable, otherwise use a default client
@@ -47,7 +48,7 @@ func Login(ctx context.Context, store Store, reg *remote.Registry, cred auth.Cre
4748
}
4849
regClone.Client = &authClient
4950
// update credentials with the client
50-
authClient.Credential = auth.StaticCredential(reg.Reference.Registry, cred)
51+
authClient.CredentialFunc = credentials.StaticCredentialFunc(reg.Reference.Registry, cred)
5152
// validate and store the credential
5253
if err := regClone.Ping(ctx); err != nil {
5354
return fmt.Errorf("failed to validate the credentials for %s: %w", regClone.Reference.Registry, err)
@@ -60,20 +61,20 @@ func Login(ctx context.Context, store Store, reg *remote.Registry, cred auth.Cre
6061
}
6162

6263
// Logout provides the logout functionality given the registry name.
63-
func Logout(ctx context.Context, store Store, registryName string) error {
64+
func Logout(ctx context.Context, store credentials.Store, registryName string) error {
6465
registryName = ServerAddressFromRegistry(registryName)
6566
if err := store.Delete(ctx, registryName); err != nil {
6667
return fmt.Errorf("failed to delete the credential for %s: %w", registryName, err)
6768
}
6869
return nil
6970
}
7071

71-
// 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+
// GetCredentialFunc returns a GetCredentialFunc() function that can be used by auth.Client.
73+
func GetCredentialFunc(store credentials.Store) credentials.CredentialFunc {
74+
return func(ctx context.Context, hostport string) (properties.Credential, error) {
7475
hostport = ServerAddressFromHostname(hostport)
7576
if hostport == "" {
76-
return auth.EmptyCredential, nil
77+
return properties.EmptyCredential, nil
7778
}
7879
return store.Get(ctx, hostport)
7980
}

registry/remote/auth/client.go

Lines changed: 11 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ 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"
32+
"oras.land/oras-go/v2/registry/remote/properties"
3133
"oras.land/oras-go/v2/registry/remote/retry"
3234
)
3335

@@ -66,29 +68,6 @@ var maxResponseBytes int64 = 128 * 1024 // 128 KiB
6668
// See also ClientID.
6769
var defaultClientID = "oras-go"
6870

69-
// CredentialFunc represents a function that resolves the credential for the
70-
// given registry (i.e. host:port).
71-
//
72-
// [EmptyCredential] is a valid return value and should not be considered as
73-
// an error.
74-
type CredentialFunc func(ctx context.Context, hostport string) (Credential, error)
75-
76-
// StaticCredential specifies static credentials for the given host.
77-
func StaticCredential(registry string, cred Credential) CredentialFunc {
78-
if registry == "docker.io" {
79-
// it is expected that traffic targeting "docker.io" will be redirected
80-
// to "registry-1.docker.io"
81-
// reference: https://github.com/moby/moby/blob/v24.0.0-beta.2/registry/config.go#L25-L48
82-
registry = "registry-1.docker.io"
83-
}
84-
return func(_ context.Context, hostport string) (Credential, error) {
85-
if hostport == registry {
86-
return cred, nil
87-
}
88-
return EmptyCredential, nil
89-
}
90-
}
91-
9271
// Client is an auth-decorated HTTP client.
9372
// Its zero value is a usable client that uses http.DefaultClient with no cache.
9473
type Client struct {
@@ -105,12 +84,12 @@ type Client struct {
10584
// Header contains the custom headers to be added to each request.
10685
Header http.Header
10786

108-
// Credential specifies the function for resolving the credential for the
87+
// CredentialFunc specifies the function for resolving the credential for the
10988
// given registry (i.e. host:port).
11089
// EmptyCredential is a valid return value and should not be considered as
11190
// an error.
11291
// If nil, the credential is always resolved to EmptyCredential.
113-
Credential CredentialFunc
92+
CredentialFunc credentials.CredentialFunc
11493

11594
// Cache caches credentials for direct accessing the remote registry.
11695
// If nil, no cache is used.
@@ -148,11 +127,11 @@ func (c *Client) send(req *http.Request) (*http.Response, error) {
148127
}
149128

150129
// credential resolves the credential for the given registry.
151-
func (c *Client) credential(ctx context.Context, reg string) (Credential, error) {
152-
if c.Credential == nil {
153-
return EmptyCredential, nil
130+
func (c *Client) credential(ctx context.Context, reg string) (properties.Credential, error) {
131+
if c.CredentialFunc == nil {
132+
return properties.EmptyCredential, nil
154133
}
155-
return c.Credential(ctx, reg)
134+
return c.CredentialFunc(ctx, reg)
156135
}
157136

158137
// cache resolves the cache.
@@ -291,7 +270,7 @@ func (c *Client) fetchBasicAuth(ctx context.Context, registry string) (string, e
291270
if err != nil {
292271
return "", fmt.Errorf("failed to resolve credential: %w", err)
293272
}
294-
if cred == EmptyCredential {
273+
if cred == properties.EmptyCredential {
295274
return "", ErrBasicCredentialNotFound
296275
}
297276
if cred.Username == "" || cred.Password == "" {
@@ -310,7 +289,7 @@ func (c *Client) fetchBearerToken(ctx context.Context, registry, realm, service
310289
if cred.AccessToken != "" {
311290
return cred.AccessToken, nil
312291
}
313-
if cred == EmptyCredential || (cred.RefreshToken == "" && !c.ForceAttemptOAuth2) {
292+
if cred == properties.EmptyCredential || (cred.RefreshToken == "" && !c.ForceAttemptOAuth2) {
314293
return c.fetchDistributionToken(ctx, realm, service, scopes, cred.Username, cred.Password)
315294
}
316295
return c.fetchOAuth2Token(ctx, realm, service, scopes, cred)
@@ -370,7 +349,7 @@ func (c *Client) fetchDistributionToken(ctx context.Context, realm, service stri
370349

371350
// fetchOAuth2Token fetches an OAuth2 access token.
372351
// Reference: https://distribution.github.io/distribution/spec/auth/oauth/
373-
func (c *Client) fetchOAuth2Token(ctx context.Context, realm, service string, scopes []string, cred Credential) (string, error) {
352+
func (c *Client) fetchOAuth2Token(ctx context.Context, realm, service string, scopes []string, cred properties.Credential) (string, error) {
374353
form := url.Values{}
375354
if cred.RefreshToken != "" {
376355
form.Set("grant_type", "refresh_token")

0 commit comments

Comments
 (0)