1package repository
 2
 3import (
 4	"os"
 5	"path/filepath"
 6
 7	"github.com/99designs/keyring"
 8)
 9
10type Item = keyring.Item
11
12var ErrKeyringKeyNotFound = keyring.ErrKeyNotFound
13
14// Keyring provides the uniform interface over the underlying backends
15type Keyring interface {
16	// Get returns an Item matching the key or ErrKeyringKeyNotFound
17	Get(key string) (Item, error)
18	// Set stores an Item on the keyring. Set is idempotent.
19	Set(item Item) error
20	// Remove removes the item with matching key
21	Remove(key string) error
22	// Keys provides a slice of all keys stored on the keyring
23	Keys() ([]string, error)
24}
25
26func defaultKeyring() (Keyring, error) {
27	ucd, err := os.UserConfigDir()
28	if err != nil {
29		return nil, err
30	}
31
32	return keyring.Open(keyring.Config{
33		// only use the file backend until https://github.com/99designs/keyring/issues/74 is resolved
34		AllowedBackends: []keyring.BackendType{
35			keyring.FileBackend,
36		},
37
38		ServiceName: "git-bug",
39
40		// Fallback encrypted file
41		FileDir: filepath.Join(ucd, "git-bug", "keyring"),
42		// As we write the file in the user's config directory, this file should already be protected by the OS against
43		// other user's access. We actually don't terribly need to protect it further and a password prompt across all
44		// UI's would be a pain. Therefore we use here a constant password so the file will be unreadable by generic file
45		// scanners if the user's machine get compromised.
46		FilePasswordFunc: func(string) (string, error) {
47			return "git-bug", nil
48		},
49	})
50}
51
52// replaceKeyring allow to replace the Keyring of the underlying repo
53type replaceKeyring struct {
54	TestedRepo
55	keyring Keyring
56}
57
58func (rk replaceKeyring) Keyring() Keyring {
59	return rk.keyring
60}