...

Source file src/oras.land/oras-go/pkg/auth/docker/client.go

Documentation: oras.land/oras-go/pkg/auth/docker

     1  /*
     2  Copyright The ORAS Authors.
     3  Licensed under the Apache License, Version 2.0 (the "License");
     4  you may not use this file except in compliance with the License.
     5  You may obtain a copy of the License at
     6  
     7  http://www.apache.org/licenses/LICENSE-2.0
     8  
     9  Unless required by applicable law or agreed to in writing, software
    10  distributed under the License is distributed on an "AS IS" BASIS,
    11  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  See the License for the specific language governing permissions and
    13  limitations under the License.
    14  */
    15  
    16  package docker
    17  
    18  import (
    19  	"os"
    20  
    21  	"github.com/docker/cli/cli/config"
    22  	"github.com/docker/cli/cli/config/configfile"
    23  	"github.com/docker/cli/cli/config/credentials"
    24  	"github.com/pkg/errors"
    25  
    26  	"oras.land/oras-go/pkg/auth"
    27  )
    28  
    29  // Client provides authentication operations for docker registries.
    30  type Client struct {
    31  	configs []*configfile.ConfigFile
    32  }
    33  
    34  // NewClient creates a new auth client based on provided config paths.
    35  // If not config path is provided, the default path is used.
    36  // Credentials are read from the first config and fall backs to next.
    37  // All changes will only be written to the first config file.
    38  func NewClient(configPaths ...string) (auth.Client, error) {
    39  	if len(configPaths) == 0 {
    40  		cfg, err := config.Load(config.Dir())
    41  		if err != nil {
    42  			return nil, err
    43  		}
    44  		if !cfg.ContainsAuth() {
    45  			cfg.CredentialsStore = credentials.DetectDefaultStore(cfg.CredentialsStore)
    46  		}
    47  
    48  		return &Client{
    49  			configs: []*configfile.ConfigFile{cfg},
    50  		}, nil
    51  	}
    52  
    53  	var configs []*configfile.ConfigFile
    54  	for _, path := range configPaths {
    55  		cfg, err := loadConfigFile(path)
    56  		if err != nil {
    57  			return nil, errors.Wrap(err, path)
    58  		}
    59  		configs = append(configs, cfg)
    60  	}
    61  
    62  	return &Client{
    63  		configs: configs,
    64  	}, nil
    65  }
    66  
    67  // NewClientWithDockerFallback creates a new auth client
    68  // which falls back on Docker's default config path.
    69  // This allows support for ~/.docker/config.json as a fallback,
    70  // as well as support for the DOCKER_CONFIG environment variable.
    71  func NewClientWithDockerFallback(configPaths ...string) (auth.Client, error) {
    72  	if len(configPaths) == 0 {
    73  		return NewClient()
    74  	}
    75  
    76  	var configs []*configfile.ConfigFile
    77  	for _, path := range configPaths {
    78  		cfg, err := loadConfigFile(path)
    79  		if err != nil {
    80  			return nil, errors.Wrap(err, path)
    81  		}
    82  		configs = append(configs, cfg)
    83  	}
    84  
    85  	// Add the Docker default config last
    86  	dockerFallbackCfg, err := config.Load(config.Dir())
    87  	if err != nil {
    88  		return nil, err
    89  	}
    90  	if !dockerFallbackCfg.ContainsAuth() {
    91  		dockerFallbackCfg.CredentialsStore = credentials.DetectDefaultStore(dockerFallbackCfg.CredentialsStore)
    92  	}
    93  	configs = append(configs, dockerFallbackCfg)
    94  
    95  	return &Client{
    96  		configs: configs,
    97  	}, nil
    98  }
    99  
   100  func (c *Client) primaryCredentialsStore(hostname string) credentials.Store {
   101  	return c.configs[0].GetCredentialsStore(hostname)
   102  }
   103  
   104  // loadConfigFile reads the configuration files from the given path.
   105  func loadConfigFile(path string) (*configfile.ConfigFile, error) {
   106  	cfg := configfile.New(path)
   107  	if _, err := os.Stat(path); err == nil {
   108  		file, err := os.Open(path)
   109  		if err != nil {
   110  			return nil, err
   111  		}
   112  		defer file.Close()
   113  		if err := cfg.LoadFromReader(file); err != nil {
   114  			return nil, err
   115  		}
   116  	} else if !os.IsNotExist(err) {
   117  		return nil, err
   118  	}
   119  	if !cfg.ContainsAuth() {
   120  		cfg.CredentialsStore = credentials.DetectDefaultStore(cfg.CredentialsStore)
   121  	}
   122  	return cfg, nil
   123  }
   124  

View as plain text