credentials_manager 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +17 -1
- data/bin/fastlane-credentials +5 -0
- data/lib/credentials_manager/account_manager.rb +10 -6
- data/lib/credentials_manager/appfile_config.rb +1 -1
- data/lib/credentials_manager/cli.rb +66 -0
- data/lib/credentials_manager/version.rb +1 -1
- data/lib/credentials_manager.rb +4 -1
- metadata +26 -11
- data/lib/credentials_manager/password_manager.rb +0 -118
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56e040d8cf60d61b4e29453dde3f9081bc9db207
|
4
|
+
data.tar.gz: cafa285c842eb3ffcf34d309f43caa9c7d199d08
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd17eb3bc978edfb5c48d9683b473583f52d87f113777254e6b7bea97659ab92ad7cea982728926b2ed3dcded407200928078c69e83fe3bc05730a94f6f35d49
|
7
|
+
data.tar.gz: ca7de8051914d4ceb75ffc5088e40afb73b11eb8b4dc2b3cef9b87f9fa3b77e123af5366fd9cbab88c28e3ee07e3f5934ed0f488aa9bf0226bd29b3c05704c80
|
data/README.md
CHANGED
@@ -3,7 +3,23 @@ CredentialsManager
|
|
3
3
|
|
4
4
|
`CredentialsManager` is used by most components in the [fastlane.tools](https://fastlane.tools) toolchain.
|
5
5
|
|
6
|
-
All code related to your username and password can be found here: [
|
6
|
+
All code related to your username and password can be found here: [account_manager.rb](https://github.com/fastlane/CredentialsManager/blob/master/lib/credentials_manager/account_manager.rb)
|
7
|
+
|
8
|
+
## Usage
|
9
|
+
Along with the [Ruby libraries](https://github.com/fastlane/credentials_manager#implementing-a-custom-solution) you can use the command line interface to add credentials to the keychain.
|
10
|
+
|
11
|
+
**Adding Credentials**
|
12
|
+
```sh
|
13
|
+
$ fastlane-credentials add --username tcook
|
14
|
+
Password: *********
|
15
|
+
Credential tcook:********* added to keychain.
|
16
|
+
```
|
17
|
+
|
18
|
+
**Removing Credentials**
|
19
|
+
```sh
|
20
|
+
$ fastlane-credentials remove --username tcook
|
21
|
+
password has been deleted.
|
22
|
+
```
|
7
23
|
|
8
24
|
## Storing in the keychain
|
9
25
|
|
@@ -41,6 +41,15 @@ module CredentialsManager
|
|
41
41
|
false
|
42
42
|
end
|
43
43
|
|
44
|
+
def add_to_keychain
|
45
|
+
Security::InternetPassword.add(server_name, user, password)
|
46
|
+
end
|
47
|
+
|
48
|
+
def remove_from_keychain
|
49
|
+
Security::InternetPassword.delete(server: server_name)
|
50
|
+
@password = nil
|
51
|
+
end
|
52
|
+
|
44
53
|
private
|
45
54
|
|
46
55
|
def ask_for_login
|
@@ -64,7 +73,7 @@ module CredentialsManager
|
|
64
73
|
return true if (/darwin/ =~ RUBY_PLATFORM).nil? # mac?, since we don't have access to the helper here
|
65
74
|
|
66
75
|
# Now we store this information in the keychain
|
67
|
-
if
|
76
|
+
if add_to_keychain
|
68
77
|
return true
|
69
78
|
else
|
70
79
|
puts "Could not store password in keychain".red
|
@@ -72,11 +81,6 @@ module CredentialsManager
|
|
72
81
|
end
|
73
82
|
end
|
74
83
|
|
75
|
-
def remove_from_keychain
|
76
|
-
Security::InternetPassword.delete(server: server_name)
|
77
|
-
@password = nil
|
78
|
-
end
|
79
|
-
|
80
84
|
def server_name
|
81
85
|
"deliver.#{user}"
|
82
86
|
end
|
@@ -117,7 +117,7 @@ module CredentialsManager
|
|
117
117
|
if lane_name.to_s.split(" ").count > 1
|
118
118
|
# That's the legacy syntax 'platform name'
|
119
119
|
puts "You use deprecated syntax '#{lane_name}' in your Appfile.".yellow
|
120
|
-
puts "Please follow the Appfile guide: https://github.com/
|
120
|
+
puts "Please follow the Appfile guide: https://github.com/fastlane/fastlane/blob/master/docs/Appfile.md".yellow
|
121
121
|
platform, lane_name = lane_name.split(" ")
|
122
122
|
|
123
123
|
return unless platform == ENV["FASTLANE_PLATFORM_NAME"]
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'credentials_manager/version'
|
2
|
+
require 'commander'
|
3
|
+
|
4
|
+
module CredentialsManager
|
5
|
+
class CLI
|
6
|
+
include Commander::Methods
|
7
|
+
|
8
|
+
# Parses command options and executes actions
|
9
|
+
def run
|
10
|
+
program :name, 'CredentialsManager'
|
11
|
+
program :version, ::CredentialsManager::VERSION
|
12
|
+
program :description, 'Manage credentials for fastlane tools.'
|
13
|
+
|
14
|
+
# Command to add entry to Keychain
|
15
|
+
command :add do |c|
|
16
|
+
c.syntax = 'fastlane-credentials add'
|
17
|
+
c.description = 'Adds a fastlane credential to the keychain.'
|
18
|
+
|
19
|
+
c.option '--username username', String, 'Username to add.'
|
20
|
+
c.option '--password password', String, 'Password to add.'
|
21
|
+
|
22
|
+
c.action do |args, options|
|
23
|
+
username = options.username || ask('Username: ')
|
24
|
+
password = options.password || ask('Password: ') { |q| q.echo = '*' }
|
25
|
+
|
26
|
+
add(username, password)
|
27
|
+
|
28
|
+
puts "Credential #{username}:#{'*' * password.length} added to keychain."
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Command to remove credential from Keychain
|
33
|
+
command :remove do |c|
|
34
|
+
c.syntax = 'fastlane-credentials remove'
|
35
|
+
c.description = 'Removes a fastlane credential from the keychain.'
|
36
|
+
|
37
|
+
c.option '--username username', String, 'Username to remove.'
|
38
|
+
|
39
|
+
c.action do |args, options|
|
40
|
+
username = options.username || ask('Username: ')
|
41
|
+
|
42
|
+
remove(username)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
run!
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# Add entry to Apple Keychain using AccountManager
|
52
|
+
def add(username, password)
|
53
|
+
CredentialsManager::AccountManager.new(
|
54
|
+
user: username,
|
55
|
+
password: password
|
56
|
+
).add_to_keychain
|
57
|
+
end
|
58
|
+
|
59
|
+
# Remove entry from Apple Keychain using AccountManager
|
60
|
+
def remove(username)
|
61
|
+
CredentialsManager::AccountManager.new(
|
62
|
+
user: username
|
63
|
+
).remove_from_keychain
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/credentials_manager.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
-
require 'credentials_manager/password_manager'
|
2
1
|
require 'credentials_manager/account_manager'
|
2
|
+
require 'credentials_manager/cli'
|
3
|
+
require 'credentials_manager/appfile_config'
|
3
4
|
|
4
5
|
# Third Party code
|
5
6
|
require 'colored'
|
7
|
+
require 'security'
|
8
|
+
require 'highline/import' # to hide the entered password
|
6
9
|
|
7
10
|
module CredentialsManager
|
8
11
|
end
|
metadata
CHANGED
@@ -1,43 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: credentials_manager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felix Krause
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: colored
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: commander
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 4.3.5
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 4.3.5
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: highline
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.7.1
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.7.1
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: security
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -167,16 +181,18 @@ dependencies:
|
|
167
181
|
description: Password manager used in fastlane.tools
|
168
182
|
email:
|
169
183
|
- fastlane@krausefx.com
|
170
|
-
executables:
|
184
|
+
executables:
|
185
|
+
- fastlane-credentials
|
171
186
|
extensions: []
|
172
187
|
extra_rdoc_files: []
|
173
188
|
files:
|
174
189
|
- LICENSE
|
175
190
|
- README.md
|
191
|
+
- bin/fastlane-credentials
|
176
192
|
- lib/credentials_manager.rb
|
177
193
|
- lib/credentials_manager/account_manager.rb
|
178
194
|
- lib/credentials_manager/appfile_config.rb
|
179
|
-
- lib/credentials_manager/
|
195
|
+
- lib/credentials_manager/cli.rb
|
180
196
|
- lib/credentials_manager/version.rb
|
181
197
|
homepage: https://fastlane.tools
|
182
198
|
licenses:
|
@@ -203,4 +219,3 @@ signing_key:
|
|
203
219
|
specification_version: 4
|
204
220
|
summary: Password manager used in fastlane.tools
|
205
221
|
test_files: []
|
206
|
-
has_rdoc:
|
@@ -1,118 +0,0 @@
|
|
1
|
-
require 'security'
|
2
|
-
require 'highline/import' # to hide the entered password
|
3
|
-
require 'credentials_manager/appfile_config'
|
4
|
-
|
5
|
-
module CredentialsManager
|
6
|
-
# Handles reading out the password from the keychain or asking for login data
|
7
|
-
class PasswordManager
|
8
|
-
# @return [String] The username / email address of the currently logged in user
|
9
|
-
attr_accessor :username
|
10
|
-
# @return [String] The password of the currently logged in user
|
11
|
-
attr_accessor :password
|
12
|
-
|
13
|
-
HOST = "deliver" # there *is* a string appended
|
14
|
-
private_constant :HOST
|
15
|
-
|
16
|
-
# A singleton object, which also makes sure, to use the correct Apple ID
|
17
|
-
# @param id_to_use (String) The Apple ID email address which should be used
|
18
|
-
# @param ask_if_missing (boolean) true by default: if no credentials are found, should the user be asked?
|
19
|
-
def self.shared_manager(id_to_use = nil, ask_if_missing = true)
|
20
|
-
@instance ||= {}
|
21
|
-
return @instance[id_to_use] if @instance[id_to_use]
|
22
|
-
if id_to_use
|
23
|
-
@instance[id_to_use] ||= PasswordManager.new(id_to_use, ask_if_missing)
|
24
|
-
else
|
25
|
-
# No user given, let's see if we have a previously used one
|
26
|
-
return @instance.values.first if @instance.values.count > 0
|
27
|
-
|
28
|
-
# Create a new one
|
29
|
-
@instance[id_to_use] ||= PasswordManager.new(id_to_use, ask_if_missing)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.logout
|
34
|
-
@instance = nil
|
35
|
-
end
|
36
|
-
|
37
|
-
# A new instance of PasswordManager.
|
38
|
-
#
|
39
|
-
# This already check the Keychain if there is a username and password stored.
|
40
|
-
# If that's not the case, it will ask for login data via stdin
|
41
|
-
# @param id_to_use (String) Apple ID (e.g. user@apple.com) which should be used for this upload.
|
42
|
-
# if given, only the password will be asked/loaded.
|
43
|
-
# @param ask_if_missing (boolean) true by default: if no credentials are found, should the user be asked?
|
44
|
-
def initialize(id_to_use = nil, ask_if_missing = true)
|
45
|
-
self.username ||= id_to_use || ENV["DELIVER_USER"] || AppfileConfig.try_fetch_value(:apple_id) || load_from_keychain[0]
|
46
|
-
self.password ||= ENV["DELIVER_PASSWORD"] || load_from_keychain[1]
|
47
|
-
|
48
|
-
if (self.username || '').length == 0 or (self.password || '').length == 0
|
49
|
-
if ask_if_missing
|
50
|
-
puts "No username or password given. You can set environment variables:"
|
51
|
-
puts "DELIVER_USER, DELIVER_PASSWORD"
|
52
|
-
|
53
|
-
ask_for_login
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# This method is called, when the iTunes backend returns that the login data is wrong
|
59
|
-
# This will ask the user, if he wants to re-enter the password
|
60
|
-
def password_seems_wrong
|
61
|
-
puts "It seems like the username or password for the account '#{self.username}' is wrong.".red
|
62
|
-
puts "Please open the Keychain app, switch to `Passwords` and search for `deliver.`".red
|
63
|
-
puts "You can then either remove the outdated entry or directly update it.".red
|
64
|
-
end
|
65
|
-
|
66
|
-
private
|
67
|
-
|
68
|
-
def ask_for_login
|
69
|
-
puts "-------------------------------------------------------------------------------------".green
|
70
|
-
puts "The login information you enter will be stored in your Mac OS Keychain".green
|
71
|
-
puts "More information about that on GitHub: https://github.com/fastlane/credentials_manager".green
|
72
|
-
puts "-------------------------------------------------------------------------------------".green
|
73
|
-
|
74
|
-
username_was_there = self.username
|
75
|
-
|
76
|
-
self.username = ask("Username: ") while (self.username || '').length == 0
|
77
|
-
|
78
|
-
self.password ||= load_from_keychain[1] # maybe there was already something stored in the keychain
|
79
|
-
|
80
|
-
if (self.password || '').length > 0
|
81
|
-
return true
|
82
|
-
else
|
83
|
-
while (self.password || '').length == 0
|
84
|
-
text = "Password: "
|
85
|
-
text = "Password (for #{self.username}): " if username_was_there
|
86
|
-
self.password = ask(text) { |q| q.echo = "*" }
|
87
|
-
end
|
88
|
-
|
89
|
-
# Now we store this information in the keychain
|
90
|
-
# Example usage taken from https://github.com/nomad/cupertino/blob/master/lib/cupertino/provisioning_portal/commands/login.rb
|
91
|
-
unless ENV["FASTLANE_DONT_STORE_PASSWORD"]
|
92
|
-
if Security::InternetPassword.add(hostname, self.username, self.password)
|
93
|
-
return true
|
94
|
-
else
|
95
|
-
puts "Could not store password in keychain".red
|
96
|
-
return false
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
def remove_from_keychain
|
103
|
-
puts "Removing keychain item: #{hostname}".yellow
|
104
|
-
Security::InternetPassword.delete(server: hostname)
|
105
|
-
end
|
106
|
-
|
107
|
-
def load_from_keychain
|
108
|
-
pass = Security::InternetPassword.find(server: hostname)
|
109
|
-
|
110
|
-
return [pass.attributes['acct'], pass.password] if pass
|
111
|
-
return [nil, nil]
|
112
|
-
end
|
113
|
-
|
114
|
-
def hostname
|
115
|
-
[HOST, self.username].join('.')
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|