Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added unlock_keychain action #580

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions docs/Actions.md
Expand Up @@ -230,6 +230,27 @@ create_keychain(
)
```

### `unlock_keychain`

Unlock existing keychain and add it to the keychain search list.

```ruby
unlock_keychain(
path: "/path/to/KeychainName.keychain",
password: "mysecret"
)
```

If the keychain file is located in the standard location `~/Library/Keychains`, then it is sufficient to provide the keychain file name, or file name with suffix.

```ruby
unlock_keychain(
path: "KeychainName",
password: "mysecret"
)
```


### `delete_keychain`

Delete a keychain, can be used after creating one with `create_keychain`.
Expand Down
97 changes: 97 additions & 0 deletions lib/fastlane/actions/unlock_keychain.rb
@@ -0,0 +1,97 @@
module Fastlane
module Actions
class UnlockKeychainAction < Action
def self.run(params)
keychain_path = self.expand_keychain_path(params[:path])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant self detected.

add_to_search_list = params[:add_to_search_list]

if keychain_path.empty?
raise "Could not find the keychain file: #{keychain_path}".red
end

# add to search list if not already added
if add_to_search_list
add_keychain_to_search_list(keychain_path)
end

escaped_path = keychain_path.shellescape
escaped_password = params[:password].shellescape

commands = []
# unlock given keychain and disable lock and timeout
commands << Fastlane::Actions.sh("security unlock-keychain -p #{escaped_password} #{escaped_path}", log: false)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [119/80]

commands << Fastlane::Actions.sh("security set-keychain-settings #{escaped_path}", log: false)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [102/80]

commands
end

def self.add_keychain_to_search_list(keychain_path)
escaped_path = keychain_path.shellescape

result = Fastlane::Actions.sh("security list-keychains", log: false)

# add the keychain to the keychains list
# the basic strategy is to open the keychain file with Keychain Access
unless result.include?(keychain_path)
commands = []
commands << Fastlane::Actions.sh("open #{escaped_path}")
commands
end
end

def self.expand_keychain_path(keychain_path)
possible_locations = []
possible_locations << keychain_path
possible_locations << "~/Library/Keychains/#{keychain_path}"
possible_locations << "~/Library/Keychains/#{keychain_path}.keychain"

possible_locations.each do |location|
expanded_location = File.expand_path(location)
if File.exist?(expanded_location)
return expanded_location
end
end

return ""

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant return detected.

end

#####################################################
# @!group Documentation
#####################################################

def self.description
"Unlock a keychain"
end

def self.details
"Unlocks the give keychain file and adds it to the keychain search list."

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [81/80]

end

def self.available_options
[
FastlaneCore::ConfigItem.new(key: :path,
env_name: "FL_UNLOCK_KEYCHAIN_PATH",
description: "Path to the Keychain file",
optional: false),
FastlaneCore::ConfigItem.new(key: :password,
env_name: "FL_UNLOCK_KEYCHAIN_PASSWORD",
description: "Keychain password",
optional: false),
FastlaneCore::ConfigItem.new(key: :add_to_search_list,
env_name: "FL_UNLOCK_KEYCHAIN_ADD_TO_SEARCH_LIST",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [89/80]

description: "Add to keychain search list",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [82/80]

is_string: false,
default_value: true)

]
end

def self.authors
["xfreebird"]
end

def self.is_supported?(platform)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename is_supported? to supported?.

platform == :ios
end
end
end
end
118 changes: 7 additions & 111 deletions spec/actions_specs/create_keychain_spec.rb
@@ -1,124 +1,20 @@
describe Fastlane do
describe Fastlane::FastFile do
describe "Create keychain Integration" do
describe "Unlock keychain Integration" do

it "works with name and password" do
result = Fastlane::FastFile.new.parse("lane :test do
create_keychain ({
name: 'test.keychain',
password: 'testpassword',
})
end").runner.execute(:test)

expect(result.size).to eq 2
expect(result[0]).to eq 'security create-keychain -p testpassword test.keychain'

expect(result[1]).to start_with 'security set-keychain-settings'
expect(result[1]).to include '-t 300'
expect(result[1]).to_not include '-l'
expect(result[1]).to_not include '-u'
expect(result[1]).to include '~/Library/Keychains/test.keychain'
end

it "works with name and password that contain spaces or `\"`" do
result = Fastlane::FastFile.new.parse("lane :test do
create_keychain ({
name: 'test.keychain',
password: '\"test password\"',
})
end").runner.execute(:test)

expect(result.size).to eq 2
expect(result[0]).to eq %(security create-keychain -p \\\"test\\ password\\\" test.keychain)
end
it "works with path and password and existing keychain" do
expanded_path = File.expand_path("~/Library/Keychains/login.keychain")

it "works with keychain-settings and name and password" do
result = Fastlane::FastFile.new.parse("lane :test do
create_keychain ({
name: 'test.keychain',
unlock_keychain ({
path: '#{expanded_path}',
password: 'testpassword',
timeout: 600,
lock_when_sleeps: true,
lock_after_timeout: true,
})
end").runner.execute(:test)

expect(result.size).to eq 2
expect(result[0]).to eq 'security create-keychain -p testpassword test.keychain'

expect(result[1]).to start_with 'security set-keychain-settings'
expect(result[1]).to include '-t 600'
expect(result[1]).to include '-l'
expect(result[1]).to include '-u'
expect(result[1]).to include '~/Library/Keychains/test.keychain'
end

it "works with default_keychain and name and password" do
result = Fastlane::FastFile.new.parse("lane :test do
create_keychain ({
name: 'test.keychain',
password: 'testpassword',
default_keychain: true,
})
end").runner.execute(:test)

expect(result.size).to eq 3
expect(result[0]).to eq 'security create-keychain -p testpassword test.keychain'

expect(result[1]).to eq 'security default-keychain -s test.keychain'

expect(result[2]).to start_with 'security set-keychain-settings'
expect(result[2]).to include '-t 300'
expect(result[2]).to_not include '-l'
expect(result[2]).to_not include '-u'
expect(result[2]).to include '~/Library/Keychains/test.keychain'
end

it "works with unlock and name and password" do
result = Fastlane::FastFile.new.parse("lane :test do
create_keychain ({
name: 'test.keychain',
password: 'testpassword',
unlock: true,
})
end").runner.execute(:test)

expect(result.size).to eq 3
expect(result[0]).to eq 'security create-keychain -p testpassword test.keychain'

expect(result[1]).to eq 'security unlock-keychain -p testpassword test.keychain'

expect(result[2]).to start_with 'security set-keychain-settings'
expect(result[2]).to include '-t 300'
expect(result[2]).to_not include '-l'
expect(result[2]).to_not include '-u'
expect(result[2]).to include '~/Library/Keychains/test.keychain'
end

it "works with all params" do
result = Fastlane::FastFile.new.parse("lane :test do
create_keychain ({
name: 'test.keychain',
password: 'testpassword',
default_keychain: true,
unlock: true,
timeout: 600,
lock_when_sleeps: true,
lock_after_timeout: true,
})
end").runner.execute(:test)

expect(result.size).to eq 4
expect(result[0]).to eq 'security create-keychain -p testpassword test.keychain'

expect(result[1]).to eq 'security default-keychain -s test.keychain'
expect(result[2]).to eq 'security unlock-keychain -p testpassword test.keychain'

expect(result[3]).to start_with 'security set-keychain-settings'
expect(result[3]).to include '-t 600'
expect(result[3]).to include '-l'
expect(result[3]).to include '-u'
expect(result[3]).to include '~/Library/Keychains/test.keychain'
expect(result[0]).to eq "security unlock-keychain -p testpassword #{expanded_path}"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [91/80]

expect(result[1]).to eq "security set-keychain-settings #{expanded_path}"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [81/80]

end
end
end
Expand Down