Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func ListKeySlots(ctx context.Context, rawStore store.ObjectStore) ([]KeySlot, e
if err := requireEncryptedRepo(ctx, rawStore); err != nil {
return nil, err
}
slots, err := keychain.LoadKeySlots(rawStore)
slots, err := keychain.LoadKeySlots(ctx, rawStore)
if err != nil {
return nil, fmt.Errorf("load key slots: %w", err)
}
Expand All @@ -75,7 +75,7 @@ func ChangePassword(ctx context.Context, rawStore store.ObjectStore, kc keychain
if err := requireEncryptedRepo(ctx, rawStore); err != nil {
return err
}
slots, err := keychain.LoadKeySlots(rawStore)
slots, err := keychain.LoadKeySlots(ctx, rawStore)
if err != nil {
return fmt.Errorf("load key slots: %w", err)
}
Expand All @@ -87,7 +87,7 @@ func ChangePassword(ctx context.Context, rawStore store.ObjectStore, kc keychain
if err != nil {
return err
}
return keychain.ChangePasswordSlot(rawStore, masterKey, newPassword)
return keychain.ChangePasswordSlot(ctx, rawStore, masterKey, newPassword)
}

// AddRecoveryKey generates a BIP39 recovery key for the repository,
Expand All @@ -97,15 +97,15 @@ func AddRecoveryKey(ctx context.Context, rawStore store.ObjectStore, kc keychain
if err := requireEncryptedRepo(ctx, rawStore); err != nil {
return "", err
}
slots, err := keychain.LoadKeySlots(rawStore)
slots, err := keychain.LoadKeySlots(ctx, rawStore)
if err != nil {
return "", fmt.Errorf("load key slots: %w", err)
}
masterKey, err := kc.Resolve(ctx, slots)
if err != nil {
return "", fmt.Errorf("unlock repository: %w", err)
}
return keychain.AddRecoverySlot(rawStore, masterKey)
return keychain.AddRecoverySlot(ctx, rawStore, masterKey)
}

// LoadRepoConfig reads the repository marker from a raw (undecorated) store.
Expand Down Expand Up @@ -224,7 +224,7 @@ type Client struct {
reporter ui.Reporter
}

func NewClient(base store.ObjectStore, opts ...ClientOption) (*Client, error) {
func NewClient(ctx context.Context, base store.ObjectStore, opts ...ClientOption) (*Client, error) {
c := &Client{
enablePackfile: true, // Packfile is enabled by default
reporter: ui.NewNoOpReporter(),
Expand All @@ -235,7 +235,7 @@ func NewClient(base store.ObjectStore, opts ...ClientOption) (*Client, error) {

// Auto-detect encryption from the repo config if no explicit key is set.
if len(c.encryptionKey) == 0 {
encKey, err := c.resolveKeyFromConfig(base)
encKey, err := c.resolveKeyFromConfig(ctx, base)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -277,8 +277,7 @@ func NewClient(base store.ObjectStore, opts ...ClientOption) (*Client, error) {

// resolveKeyFromConfig reads the repo config and, if the repository is
// encrypted, uses the Keychain to resolve the master key and derive the encryption key.
func (c *Client) resolveKeyFromConfig(base store.ObjectStore) ([]byte, error) {
ctx := context.Background()
func (c *Client) resolveKeyFromConfig(ctx context.Context, base store.ObjectStore) ([]byte, error) {
cfg, err := LoadRepoConfig(ctx, base)
if err != nil {
return nil, fmt.Errorf("read repo config: %w", err)
Expand All @@ -289,7 +288,7 @@ func (c *Client) resolveKeyFromConfig(base store.ObjectStore) ([]byte, error) {
if !cfg.Encrypted {
return nil, nil
}
slots, err := keychain.LoadKeySlots(base)
slots, err := keychain.LoadKeySlots(ctx, base)
if err != nil {
return nil, fmt.Errorf("load key slots: %w", err)
}
Expand Down
16 changes: 8 additions & 8 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func TestChangePassword(t *testing.T) {
t.Fatalf("ChangePassword: %v", err)
}

slots, _ := keychain.LoadKeySlots(s)
slots, _ := keychain.LoadKeySlots(ctx, s)
if _, err := (keychain.Chain{keychain.WithPassword("old-pass")}).Resolve(ctx, slots); err == nil {
t.Error("old password should no longer work")
}
Expand Down Expand Up @@ -191,7 +191,7 @@ func TestAddRecoveryKey(t *testing.T) {
t.Error("expected non-empty mnemonic")
}

slots, _ := keychain.LoadKeySlots(s)
slots, _ := keychain.LoadKeySlots(ctx, s)
hasRecovery := false
for _, slot := range slots {
if slot.SlotType == "recovery" {
Expand Down Expand Up @@ -241,7 +241,7 @@ func TestClient_Cat_SingleObject(t *testing.T) {
t.Fatalf("Failed to put config: %v", err)
}

client, err := NewClient(base)
client, err := NewClient(context.Background(), base)
if err != nil {
t.Fatalf("Failed to create client: %v", err)
}
Expand Down Expand Up @@ -289,7 +289,7 @@ func TestClient_Cat_MultipleObjects(t *testing.T) {
}
}

client, err := NewClient(base)
client, err := NewClient(context.Background(), base)
if err != nil {
t.Fatalf("Failed to create client: %v", err)
}
Expand Down Expand Up @@ -323,7 +323,7 @@ func TestClient_Cat_ObjectNotFound(t *testing.T) {
t.Fatalf("Failed to setup mock data: %v", err)
}

client, err := NewClient(base)
client, err := NewClient(context.Background(), base)
if err != nil {
t.Fatalf("Failed to create client: %v", err)
}
Expand All @@ -347,7 +347,7 @@ func TestClient_Cat_NoKeys(t *testing.T) {
t.Fatalf("Failed to setup mock data: %v", err)
}

client, err := NewClient(base)
client, err := NewClient(context.Background(), base)
if err != nil {
t.Fatalf("Failed to create client: %v", err)
}
Expand Down Expand Up @@ -385,7 +385,7 @@ func TestClient_Cat_WithEncryption(t *testing.T) {
}

// Create client with encryption - it will wrap the store
client, err := NewClient(base, WithEncryptionKey(encKey))
client, err := NewClient(context.Background(), base, WithEncryptionKey(encKey))
if err != nil {
t.Fatalf("Failed to create client: %v", err)
}
Expand Down Expand Up @@ -438,7 +438,7 @@ func TestClient_Cat_WithCompression(t *testing.T) {
t.Fatalf("Failed to setup mock data: %v", err)
}

client, err := NewClient(base)
client, err := NewClient(context.Background(), base)
if err != nil {
t.Fatalf("Failed to create client: %v", err)
}
Expand Down
31 changes: 15 additions & 16 deletions cmd/cloudstic/cmd_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"github.com/cloudstic/cli/internal/paths"
)

func (r *runner) runAuth() int {
func (r *runner) runAuth(ctx context.Context) int {
if len(os.Args) < 3 {
_, _ = fmt.Fprintln(r.errOut, "Usage: cloudstic auth <subcommand> [options]")
_, _ = fmt.Fprintln(r.errOut, "")
Expand All @@ -23,19 +23,19 @@ func (r *runner) runAuth() int {

switch os.Args[2] {
case "list":
return r.runAuthList()
return r.runAuthList(ctx)
case "show":
return r.runAuthShow()
return r.runAuthShow(ctx)
case "new":
return r.runAuthNew()
return r.runAuthNew(ctx)
case "login":
return r.runAuthLogin()
return r.runAuthLogin(ctx)
default:
return r.fail("Unknown auth subcommand: %s", os.Args[2])
}
}

func (r *runner) runAuthList() int {
func (r *runner) runAuthList(ctx context.Context) int {
fs := flag.NewFlagSet("auth list", flag.ExitOnError)
profilesFile := fs.String("profiles-file", envDefault("CLOUDSTIC_PROFILES_FILE", defaultProfilesPathFallback()), "Path to profiles YAML file")
_ = fs.Parse(reorderArgs(fs, os.Args[3:]))
Expand All @@ -52,7 +52,7 @@ func (r *runner) runAuthList() int {
return 0
}

func (r *runner) runAuthShow() int {
func (r *runner) runAuthShow(ctx context.Context) int {
fs := flag.NewFlagSet("auth show", flag.ExitOnError)
profilesFile := fs.String("profiles-file", envDefault("CLOUDSTIC_PROFILES_FILE", defaultProfilesPathFallback()), "Path to profiles YAML file")
_ = fs.Parse(reorderArgs(fs, os.Args[3:]))
Expand All @@ -73,7 +73,7 @@ func (r *runner) runAuthShow() int {
return r.fail("usage: cloudstic auth show [-profiles-file <path>] <name>")
}
names := sortedKeys(cfg.Auth)
picked, pickErr := r.promptSelect("Select auth entry", names)
picked, pickErr := r.promptSelect(ctx, "Select auth entry", names)
if pickErr != nil {
return r.fail("Failed to select auth entry: %v", pickErr)
}
Expand All @@ -88,7 +88,7 @@ func (r *runner) runAuthShow() int {
return 0
}

func (r *runner) runAuthNew() int {
func (r *runner) runAuthNew(ctx context.Context) int {
fs := flag.NewFlagSet("auth new", flag.ExitOnError)
profilesFile := fs.String("profiles-file", envDefault("CLOUDSTIC_PROFILES_FILE", defaultProfilesPathFallback()), "Path to profiles YAML file")
name := fs.String("name", "", "Auth reference name")
Expand All @@ -101,7 +101,7 @@ func (r *runner) runAuthNew() int {

if *name == "" {
if r.canPrompt() {
v, err := r.promptLine("Auth reference name", "")
v, err := r.promptLine(ctx, "Auth reference name", "")
if err != nil {
return r.fail("Failed to read auth reference name: %v", err)
}
Expand All @@ -116,7 +116,7 @@ func (r *runner) runAuthNew() int {
}
if *provider != "google" && *provider != "onedrive" {
if r.canPrompt() {
picked, err := r.promptSelect("Select auth provider", []string{"google", "onedrive"})
picked, err := r.promptSelect(ctx, "Select auth provider", []string{"google", "onedrive"})
if err != nil {
return r.fail("Failed to read auth provider: %v", err)
}
Expand All @@ -132,7 +132,7 @@ func (r *runner) runAuthNew() int {
if *googleTokenFile == "" {
if r.canPrompt() {
def := defaultAuthTokenPath("google", *name)
v, err := r.promptLine("Google token file path", def)
v, err := r.promptLine(ctx, "Google token file path", def)
if err != nil {
return r.fail("Failed to read google token file path: %v", err)
}
Expand All @@ -152,7 +152,7 @@ func (r *runner) runAuthNew() int {
if *onedriveTokenFile == "" {
if r.canPrompt() {
def := defaultAuthTokenPath("onedrive", *name)
v, err := r.promptLine("OneDrive token file path", def)
v, err := r.promptLine(ctx, "OneDrive token file path", def)
if err != nil {
return r.fail("Failed to read onedrive token file path: %v", err)
}
Expand Down Expand Up @@ -183,7 +183,7 @@ func (r *runner) runAuthNew() int {
return 0
}

func (r *runner) runAuthLogin() int {
func (r *runner) runAuthLogin(ctx context.Context) int {
fs := flag.NewFlagSet("auth login", flag.ExitOnError)
profilesFile := fs.String("profiles-file", envDefault("CLOUDSTIC_PROFILES_FILE", defaultProfilesPathFallback()), "Path to profiles YAML file")
name := fs.String("name", "", "Auth reference name")
Expand All @@ -197,7 +197,7 @@ func (r *runner) runAuthLogin() int {
if *name == "" {
if r.canPrompt() {
names := sortedKeys(cfg.Auth)
picked, pickErr := r.promptSelect("Select auth entry", names)
picked, pickErr := r.promptSelect(ctx, "Select auth entry", names)
if pickErr != nil {
return r.fail("Failed to select auth entry: %v", pickErr)
}
Expand All @@ -214,7 +214,6 @@ func (r *runner) runAuthLogin() int {
}

g := newAuthGlobalFlags()
ctx := context.Background()

switch auth.Provider {
case "google":
Expand Down
Loading
Loading