Class: Vkit::Core::CredentialStore

Inherits:
Object
  • Object
show all
Defined in:
lib/vkit/core/credential_store.rb

Constant Summary collapse

SERVICE =
"vkit"
ACCOUNT =
"credentials"

Instance Method Summary collapse

Constructor Details

#initializeCredentialStore

Returns a new instance of CredentialStore.



12
13
14
15
# File 'lib/vkit/core/credential_store.rb', line 12

def initialize
  @os = RbConfig::CONFIG["host_os"]
  @fallback_path = File.join(Dir.home, ".vkit", "credentials.json")
end

Instance Method Details

#clear!Object



68
69
70
71
72
73
74
75
76
77
# File 'lib/vkit/core/credential_store.rb', line 68

def clear!
  case
  when mac?
    mac_keychain_delete
  when linux? && secret_tool_available?
    linux_secret_service_delete
  else
    file_delete
  end
end

#clear_token!Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/vkit/core/credential_store.rb', line 79

def clear_token!
  payload = load_payload
  return unless payload

  payload.delete("token")

  case
  when mac?
    mac_keychain_store(payload)
  when linux? && secret_tool_available?
    linux_secret_service_store(payload)
  else
    file_store(payload)
  end
end

#endpointObject



52
53
54
# File 'lib/vkit/core/credential_store.rb', line 52

def endpoint
  load_payload&.dig("endpoint")
end

#file_deleteObject



197
198
199
# File 'lib/vkit/core/credential_store.rb', line 197

def file_delete
  FileUtils.rm_f(@fallback_path)
end

#file_loadObject



190
191
192
193
194
195
# File 'lib/vkit/core/credential_store.rb', line 190

def file_load
  return nil unless File.exist?(@fallback_path)
  JSON.parse(File.read(@fallback_path))
rescue
  nil
end

#file_store(payload) ⇒ Object



184
185
186
187
188
# File 'lib/vkit/core/credential_store.rb', line 184

def file_store(payload)
  FileUtils.mkdir_p(File.dirname(@fallback_path))
  File.write(@fallback_path, JSON.pretty_generate(payload))
  File.chmod(0o600, @fallback_path)
end

#linux?Boolean

Returns:

  • (Boolean)


110
111
112
# File 'lib/vkit/core/credential_store.rb', line 110

def linux?
  @os =~ /linux/
end

#linux_secret_service_deleteObject



180
181
182
# File 'lib/vkit/core/credential_store.rb', line 180

def linux_secret_service_delete
  linux_secret_service_store({})
end

#linux_secret_service_loadObject



165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/vkit/core/credential_store.rb', line 165

def linux_secret_service_load
  stdout, _stderr, status =
    Open3.capture3(
      "secret-tool",
      "lookup",
      "service", SERVICE,
      "account", ACCOUNT
    )

  return nil unless status.success?
  JSON.parse(stdout)
rescue
  nil
end

#linux_secret_service_store(payload) ⇒ Object



154
155
156
157
158
159
160
161
162
163
# File 'lib/vkit/core/credential_store.rb', line 154

def linux_secret_service_store(payload)
  Open3.capture3(
    "secret-tool",
    "store",
    "--label=VaultKit Credentials",
    "service", SERVICE,
    "account", ACCOUNT,
    stdin_data: payload.to_json
  )
end

#load_payloadObject



95
96
97
98
99
100
101
102
103
104
# File 'lib/vkit/core/credential_store.rb', line 95

def load_payload
  case
  when mac?
    mac_keychain_load
  when linux? && secret_tool_available?
    linux_secret_service_load
  else
    file_load
  end
end

#logged_in?Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/vkit/core/credential_store.rb', line 64

def logged_in?
  !!(endpoint && token)
end

#mac?Boolean

Returns:

  • (Boolean)


106
107
108
# File 'lib/vkit/core/credential_store.rb', line 106

def mac?
  @os =~ /darwin/
end

#mac_keychain_deleteObject



144
145
146
147
148
149
150
151
152
# File 'lib/vkit/core/credential_store.rb', line 144

def mac_keychain_delete
  system(
    "security", "delete-generic-password",
    "-a", ACCOUNT,
    "-s", SERVICE,
    out: File::NULL,
    err: File::NULL
  )
end

#mac_keychain_loadObject



129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/vkit/core/credential_store.rb', line 129

def mac_keychain_load
  stdout, _stderr, status =
    Open3.capture3(
      "security", "find-generic-password",
      "-a", ACCOUNT,
      "-s", SERVICE,
      "-w"
    )

  return nil unless status.success?
  JSON.parse(stdout)
rescue
  nil
end

#mac_keychain_store(payload) ⇒ Object



118
119
120
121
122
123
124
125
126
127
# File 'lib/vkit/core/credential_store.rb', line 118

def mac_keychain_store(payload)
  mac_keychain_delete
  system(
    "security", "add-generic-password",
    "-a", ACCOUNT,
    "-s", SERVICE,
    "-w", payload.to_json,
    "-U"
  )
end

#save(endpoint:, token:, user:) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/vkit/core/credential_store.rb', line 17

def save(endpoint:, token:, user:)
  payload = {
    "endpoint" => endpoint,
    "token" => token,
    "user" => user
  }

  case
  when mac?
    mac_keychain_store(payload)
  when linux? && secret_tool_available?
    linux_secret_service_store(payload)
  else
    file_store(payload)
  end

  true
end

#save_user(user) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/vkit/core/credential_store.rb', line 36

def save_user(user)
  payload = load_payload
  return unless payload

  payload["user"] = user

  case
  when mac?
    mac_keychain_store(payload)
  when linux? && secret_tool_available?
    linux_secret_service_store(payload)
  else
    file_store(payload)
  end
end

#secret_tool_available?Boolean

Returns:

  • (Boolean)


114
115
116
# File 'lib/vkit/core/credential_store.rb', line 114

def secret_tool_available?
  system("which secret-tool > /dev/null 2>&1")
end

#tokenObject



56
57
58
# File 'lib/vkit/core/credential_store.rb', line 56

def token
  load_payload&.dig("token")
end

#userObject



60
61
62
# File 'lib/vkit/core/credential_store.rb', line 60

def user
  load_payload&.dig("user")
end