1package credentials
2
3import (
4	"strings"
5
6	"github.com/docker/cli/cli/config/types"
7)
8
9type store interface {
10	Save() error
11	GetAuthConfigs() map[string]types.AuthConfig
12	GetFilename() string
13}
14
15// fileStore implements a credentials store using
16// the docker configuration file to keep the credentials in plain text.
17type fileStore struct {
18	file store
19}
20
21// NewFileStore creates a new file credentials store.
22func NewFileStore(file store) Store {
23	return &fileStore{file: file}
24}
25
26// Erase removes the given credentials from the file store.
27func (c *fileStore) Erase(serverAddress string) error {
28	delete(c.file.GetAuthConfigs(), serverAddress)
29	return c.file.Save()
30}
31
32// Get retrieves credentials for a specific server from the file store.
33func (c *fileStore) Get(serverAddress string) (types.AuthConfig, error) {
34	authConfig, ok := c.file.GetAuthConfigs()[serverAddress]
35	if !ok {
36		// Maybe they have a legacy config file, we will iterate the keys converting
37		// them to the new format and testing
38		for r, ac := range c.file.GetAuthConfigs() {
39			if serverAddress == ConvertToHostname(r) {
40				return ac, nil
41			}
42		}
43
44		authConfig = types.AuthConfig{}
45	}
46	return authConfig, nil
47}
48
49func (c *fileStore) GetAll() (map[string]types.AuthConfig, error) {
50	return c.file.GetAuthConfigs(), nil
51}
52
53// Store saves the given credentials in the file store.
54func (c *fileStore) Store(authConfig types.AuthConfig) error {
55	c.file.GetAuthConfigs()[authConfig.ServerAddress] = authConfig
56	return c.file.Save()
57}
58
59func (c *fileStore) GetFilename() string {
60	return c.file.GetFilename()
61}
62
63func (c *fileStore) IsFileStore() bool {
64	return true
65}
66
67// ConvertToHostname converts a registry url which has http|https prepended
68// to just an hostname.
69// Copied from github.com/docker/docker/registry.ConvertToHostname to reduce dependencies.
70func ConvertToHostname(url string) string {
71	stripped := url
72	if strings.HasPrefix(url, "http://") {
73		stripped = strings.TrimPrefix(url, "http://")
74	} else if strings.HasPrefix(url, "https://") {
75		stripped = strings.TrimPrefix(url, "https://")
76	}
77
78	nameParts := strings.SplitN(stripped, "/", 2)
79
80	return nameParts[0]
81}
82