Module: Wiq::Credentials

Defined in:
lib/wiq/credentials.rb

Overview

File-backed credential store. ~/.config/wiq/credentials.json, mode 0600. Shape:

{
  "<host>": {
    "<alias>": { "token": "...", "token_prefix": "...", "name": "...",
                 "profile": {...}, "stored_at": "..." },
    "<alias>": { ... }
  }
}

Constant Summary collapse

DEFAULT_PATH =
File.join(Dir.home, ".config", "wiq", "credentials.json")
DEFAULT_ALIAS =
"default"

Class Method Summary collapse

Class Method Details

.aliases_for(host) ⇒ Object



39
40
41
# File 'lib/wiq/credentials.rb', line 39

def aliases_for(host)
  Array((load_all[host] || {}).keys)
end

.all_entriesObject

Flat list across hosts × aliases. Useful for ‘wiq auth list`. Excludes the raw token; callers should never log tokens.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/wiq/credentials.rb', line 49

def all_entries
  load_all.flat_map do |host, by_alias|
    by_alias.map do |alias_name, entry|
      {
        "host" => host,
        "alias" => alias_name,
        "token_prefix" => entry["token_prefix"],
        "name" => entry["name"],
        "profile" => entry["profile"],
        "stored_at" => entry["stored_at"]
      }
    end
  end
end

.for_host(host, alias_name) ⇒ Object



35
36
37
# File 'lib/wiq/credentials.rb', line 35

def for_host(host, alias_name)
  load_all.dig(host, alias_name)
end

.hostsObject



43
44
45
# File 'lib/wiq/credentials.rb', line 43

def hosts
  load_all.keys
end

.load_allObject



27
28
29
30
31
32
33
# File 'lib/wiq/credentials.rb', line 27

def load_all
  return {} unless File.exist?(path)

  JSON.parse(File.read(path))
rescue JSON::ParserError
  {}
end

.pathObject



23
24
25
# File 'lib/wiq/credentials.rb', line 23

def path
  ENV["WIQ_CREDENTIALS_PATH"] || DEFAULT_PATH
end

.remove(host, alias_name) ⇒ Object



77
78
79
80
81
82
83
84
85
86
# File 'lib/wiq/credentials.rb', line 77

def remove(host, alias_name)
  data = load_all
  bucket = data[host]
  return false unless bucket
  return false unless bucket.delete(alias_name)

  data.delete(host) if bucket.empty?
  write(data)
  true
end

.store(host:, alias_name:, token:, token_prefix: nil, name: nil, profile: nil) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/wiq/credentials.rb', line 64

def store(host:, alias_name:, token:, token_prefix: nil, name: nil, profile: nil)
  data = load_all
  data[host] ||= {}
  data[host][alias_name] = {
    "token" => token,
    "token_prefix" => token_prefix,
    "name" => name,
    "profile" => profile,
    "stored_at" => Time.now.utc.iso8601
  }.compact
  write(data)
end

.write(data) ⇒ Object



88
89
90
91
92
93
# File 'lib/wiq/credentials.rb', line 88

def write(data)
  FileUtils.mkdir_p(File.dirname(path))
  File.open(path, File::WRONLY | File::CREAT | File::TRUNC, 0o600) do |f|
    f.write(JSON.pretty_generate(data))
  end
end