Skip to content

Commit

Permalink
Adding the option to remove multiple keys at once by using wildcard p…
Browse files Browse the repository at this point in the history
…attern matching or a new argument option '--all'
  • Loading branch information
chrisfsampaio committed Dec 31, 2015
1 parent 55ab294 commit 2b31fd0
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 21 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ CocoaPods-keys has 3 other commands:
Which will output the value of the key to STDOUT, useful for scripting.
* `pod keys rm [key] [optional project]`
Will remove a key from a project.
Will remove a key from a project.
If Wildcards are included, it will remove the keys matching the pattern. E.g.: `pod keys rm "G*og*"` will remove *all* the keys that begin with 'G', have 'og' in the middle and end with anything.
To nuke all the keys, run either `pod keys rm "*"` or `pod keys rm --all`
* `pod keys generate [optional project]`
Will generate the obfuscated Objective-C keys class (mainly used internally).
Expand Down
76 changes: 56 additions & 20 deletions lib/pod/command/keys/rm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,39 @@ module Pod
class Command
class Keys
class Rm < Keys
self.summary = 'Remove a key-value pair from a project.'
self.summary = 'Removes key-value pairs from a project.'

self.description = <<-DESC
Remove a key, and it's value from a project
Removes a key, and it's value from a project.
If Wildcards are included, it will remove the keys matching the pattern.
E.g.: `pod keys rm \"G*og*\"` will remove *all* the keys that begin
with 'G', have 'og' in the middle and end with anything.
To nuke all the keys, run either `pod keys rm "*"` or `pod keys rm --all`
A second optional operator can be done to force a project name.
DESC

self.arguments = [CLAide::Argument.new('key', true), CLAide::Argument.new('project_name', false)]

def self.options
[[
'--all', 'Remove all the stored keys without asking'
]].concat(super)
end

def initialize(argv)
@key_name = argv.shift_argument
@project_name = argv.shift_argument
@wipe_all = argv.flag?('all')
super
end

def validate!
super
verify_podfile_exists!
help! 'A key name is required for lookup.' unless @key_name
help! 'A key name is required for lookup.' unless @key_name || @wipe_all
end

def run
Expand All @@ -35,26 +48,49 @@ def run
raise Informative, 'Could not find a project to remove the key from.'
end

if keyring.keys.include? @key_name
keyring.save(@key_name, '')
keyring.keys.delete @key_name
CocoaPodsKeys::KeyringLiberator.save_keyring(keyring)

prefix = CocoaPodsKeys::Keyring.keychain_prefix
login = prefix + keyring.name
delete_generic = `security delete-generic-password -a #{@key_name.shellescape} -l #{login.shellescape} 2>&1`

if delete_generic.include? 'security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.'
raise Informative, "Removed value for #{@key_name}, but could not delete from Keychain."
elsif delete_generic.include? 'password has been deleted.'
raise Informative, "Removed value for #{@key_name}, and deleted associated key in Keychain."
else
raise Informative, "Removed value for #{@key_name}."
end
if @wipe_all
@key_name = '*'
end

matching_keys = matches(keyring.keys)
if matching_keys.count > 0
messages = matching_keys.map { |e| delete_key(e, keyring) }
raise Informative, messages.join("\n")
else
raise Informative, "Could not find key that matched \"#{@key_name}\"."
end
end

def delete_key(key, keyring)
keyring.save(key, '')
keyring.keys.delete key
CocoaPodsKeys::KeyringLiberator.save_keyring(keyring)

prefix = CocoaPodsKeys::Keyring.keychain_prefix
login = prefix + keyring.name
delete_generic = `security delete-generic-password -a #{key.shellescape} -l #{login.shellescape} 2>&1`

if delete_generic.include? 'security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.'
return "Removed value for #{key}, but could not delete from Keychain."
elsif delete_generic.include? 'password has been deleted.'
return "Removed value for #{key}, and deleted associated key in Keychain."
else
raise Informative, "Could not find key named #{@key_name}."
return "Removed value for #{key}."
end
end

def matches(keys)
if @key_name.include? '*'
return keys.select { |e| e =~ create_regex(@key_name) }
else
return keys.select { |e| e == @key_name }
end
end

def create_regex(pattern)
regex_str = "^#{pattern.gsub('*', '.*')}$"
Regexp.new(regex_str)
end
end
end
end
Expand Down

0 comments on commit 2b31fd0

Please sign in to comment.