exportation 0.1.0 → 0.2.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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +69 -0
  3. data/bin/exportation +71 -24
  4. data/lib/exportation.rb +18 -19
  5. metadata +31 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 59620a48ca2b2f33b91e71f3f89e17005ed8070b
4
- data.tar.gz: 2bd448ebeeb9db0ce4eb62a8c6a287f3610f8c22
3
+ metadata.gz: fa309452b28fa8fe7c2459cdd8adc644c09dbfc0
4
+ data.tar.gz: 67696b8b638f49165d57ccad2369acd3bab94921
5
5
  SHA512:
6
- metadata.gz: bf283454025f616082913549e591ac2a512cd018393e6bb462f3ae89f2697d4c691f5eaace8e494eeef6bed71f1620fae3cf8263fb74ac75eeb8f5350c83a33d
7
- data.tar.gz: f9f64013471f489cc0434ea56e3f278490b0ef475df28f37a13b834da9bd080603794d2967f0a12f463f4c82568767b95841e8f545e2403380da7bd3535b4055
6
+ metadata.gz: 666f9867ff1e4754cd2d5ea93152cbcb31bf2bd3f7febe7a42784b4f2e9309af2ef328a931affce03e6e16962999bb08d5fee44e2ab9f96d49c32da1ebdc70c8
7
+ data.tar.gz: b129a2ff9826990e9c86439b32348132580232c79815ad4c7bb4a0edb93a2d17f1aa4984637342307a9cd2d5e3497ddbee5a05ce87462115cd6082b06efdf47d
data/README.md CHANGED
@@ -1,10 +1,71 @@
1
1
  # exportation
2
2
  CLI tool of easy exporting, encrypting, and decrypting of certificates and private keys.
3
3
 
4
+ **Important:** The `export` command will take control of your "Keychain Access" app so keep all hands off your computer while that command runs
5
+
6
+ ### Example usage (with prompt)
7
+ ```sh
8
+ $: exportation export
9
+ Name: RokkinCat LLC
10
+ Path to save to (default: './'): ./examples
11
+ Filename to save as (default: 'export'): dist
12
+ Password for private key (default: ''): shhh
13
+ Info Take all hands off your computer! exportation is going to take control of 'Keychain Access'
14
+ ```
15
+
16
+ ![Example of exportation](readme_assets/example.gif)
17
+
18
+ ### Why
19
+ - Export **and** encrypt certificates **and** private keys **into** repos
20
+ - CI tools (may need these to distrubute builds to Apple TestFlight Beta :apple:)
21
+ - For other developers (for when you are on vacation and they need to make a distribution build :grimacing:)
22
+
23
+ ### How
24
+ - Makes use of AppleScript to control "Keychain Access"
25
+ - Opens "Keychain Access"
26
+ - Selects "Login" and "Certificates" for the left side
27
+ - Searches for the certificate you are looking for from `--name`
28
+ - Exports private key
29
+ - Right clicks it and selects export
30
+ - Changes the save path to your current directory (by default) or what was passed in through `--path`
31
+ - Saves the file to `exported.p12`
32
+ - Enters a blank password (by default) or what was passed in through `--password`
33
+ - Saves
34
+ - Exports certificate
35
+ - Right clicks it and selects export
36
+ - Changes the save path to your current directory (by default) or what was passed in through `--path`
37
+ - Saves the file to `exported.cer`
38
+ - Saves
39
+
4
40
  ### Features in progress
5
41
  - Integrate with [fastlane](https://github.com/KrauseFx/fastlane) :rocket:
6
42
  - Create a separate keychain with the certificates and private keys for use on CI systems :grinning:
7
43
 
44
+ ### Caveats
45
+ - Some phases of the script might run slow due to using AppleScript
46
+ - Initial load may take up to 5ish seconds
47
+ - Waiting for private key password to be entered may take up to 7ish seconds
48
+ - May need to give "Accessibility" access to **ARDAgent** and **Terminal**
49
+
50
+ ## Installation
51
+
52
+ ### Install gem
53
+ ```sh
54
+ gem install exportation
55
+ ```
56
+
57
+ ### Give "Accessibility" access
58
+ - Open up "Security & Privacy" preferences
59
+ - Select "Accessibility"
60
+ - Add **ARDAgent** and **Terminal**
61
+ - Click "+"
62
+ - Press CMD+SHIT+G (to go to specific folder)
63
+ - **ARDAgent** should be under `/System/Library/CoreServices/RemoteManagement/`
64
+ - **Terminal** should be under `/Applications/Utilities/`
65
+
66
+ ![](readme_assets/access.png)
67
+ **You won't need to give Heroes, Script Editor, or Steam permissions for exportation** :wink:
68
+
8
69
  ## Commands
9
70
  Exportation has three different commands: `export`, `encrypt`, and `decrypt`.
10
71
 
@@ -41,3 +102,11 @@ Always put all for arguments in strings because I don't do AppleScript well :gri
41
102
  ```sh
42
103
  osascript applescript/exportation.scpt "~/directory_you_want_to_export_to/" "dist" "iPhone Distribution: Your Company LLC" "thepassword"
43
104
  ```
105
+
106
+ ## Author
107
+
108
+ Josh Holtz, me@joshholtz.com, [@joshdholtz](https://twitter.com/joshdholtz)
109
+
110
+ ## License
111
+
112
+ exportation is available under the MIT license. See the LICENSE file for more info.
data/bin/exportation CHANGED
@@ -6,10 +6,16 @@ require 'exportation'
6
6
 
7
7
  require 'rubygems'
8
8
  require 'commander'
9
+ require 'colorize'
10
+ require 'terminal-notifier'
9
11
 
10
12
  class ExportationApplication
11
13
  include Commander::Methods
12
14
 
15
+ def is_empty?(str)
16
+ str.nil? || str.length == 0
17
+ end
18
+
13
19
  def run
14
20
  program :name, 'Exportation'
15
21
  program :version, '0.1.0'
@@ -22,57 +28,98 @@ class ExportationApplication
22
28
  c.option '--filename STRING', String, 'File name to save certificate and private key as'
23
29
  c.option '--name STRING', String, 'Common name of the cert as it is displayed in Keychain Access'
24
30
  c.option '--password STRING', String, 'Password to use for the private key'
31
+ c.option '--noprompt', 'Do not prompt for missing options'
25
32
  c.action do |args, options|
26
- options.default path: "./", filename:"exported", password: ""
27
-
28
- raise "--name is required" unless options.name
29
33
 
30
- Exportation::Export.new(
31
- path: options.path,
32
- filename: options.filename,
33
- name: options.name,
34
- password: options.password
35
- ).run
34
+ begin
35
+ unless options.noprompt
36
+ options.name = ask("Name: ") unless options.name
37
+ options.path = ask("Path to save to (default: './'): ") unless options.path
38
+ options.filename = ask("Filename to save as (default: 'export'): ") unless options.filename
39
+ options.password = ask("Password for private key (default: ''): ") unless options.password
40
+ end
41
+
42
+ options.path = './' if is_empty?(options.path)
43
+ options.filename = 'exported' if is_empty?(options.filename)
44
+ options.password = '' if is_empty?(options.password)
45
+
46
+ raise "'name' is required" if is_empty?(options.name)
47
+ log "Info".blue, "Take all hands off your computer! exportation is going to take control of 'Keychain Access'".blue
48
+
49
+ Exportation::Export.new(
50
+ path: options.path,
51
+ filename: options.filename,
52
+ name: options.name,
53
+ password: options.password
54
+ ).run
55
+
56
+ TerminalNotifier.notify('Certificate and private key exported!', title: 'exportation')
57
+ rescue Exception => e
58
+ TerminalNotifier.notify('Export failed :(', title: 'exportation')
59
+ log "Error".red, e.message.red
60
+ end
36
61
 
37
62
  end
38
63
  end
39
64
 
40
65
  command :encrypt do |c|
41
- c.syntax = 'exportation encrypt [options]'
66
+ c.syntax = 'exportation encrypt [file_path1] [file_path2] ... [options]'
42
67
  c.description = 'Encrypts certificates, private keys, and provisioning profiles with AES'
43
68
  c.option '--password STRING', String, 'Password to use for the encryption'
44
69
  c.option '--output STRING', String, 'Output directory for files (defaults to where original files are located)'
45
70
  c.option '--force', 'Forces all files to decrypted (will encrypt decrypted files)'
71
+ c.option '--noprompt', 'Do not prompt for missing options'
46
72
  c.action do |args, options|
47
73
  options.default output: nil
48
74
 
49
- raise "--password is required" unless options.password
75
+ begin
76
+ unless options.noprompt
77
+ options.password = ask("Password: ") unless options.password
78
+ options.output= ask("Output path (default: location of unencrypted files): ") unless options.output
79
+ end
50
80
 
51
- Exportation::Crypter.new(
52
- files: args,
53
- password: options.password,
54
- output: options.output
55
- ).run :en, options.force
81
+ raise "no files were passed through arguments" if args.empty?
82
+ raise "'password' is required" if is_empty?(options.password)
83
+
84
+ Exportation::Crypter.new(
85
+ files: args,
86
+ password: options.password,
87
+ output: options.output
88
+ ).run :en, options.force
89
+ rescue Exception => e
90
+ log "Error".red, e.message.red
91
+ end
56
92
 
57
93
  end
58
94
  end
59
95
 
60
96
  command :decrypt do |c|
61
- c.syntax = 'exportation decrypt [options]'
97
+ c.syntax = 'exportation decrypt [file_path1] [file_path2] ... [options]'
62
98
  c.description = 'Decrypts certificates, private keys, and provisioning profiles with AES'
63
99
  c.option '--password STRING', String, 'Password to use for the decryption'
64
100
  c.option '--output STRING', String, 'Output directory for files (defaults to where original files are located)'
65
101
  c.option '--force', 'Forces all files to decrypted (will encrypt decrypted files)'
102
+ c.option '--noprompt', 'Do not prompt for missing options'
66
103
  c.action do |args, options|
67
104
  options.default output: nil
68
105
 
69
- raise "--password is required" unless options.password
70
-
71
- Exportation::Crypter.new(
72
- files: args,
73
- password: options.password,
74
- output: options.output
75
- ).run :de, options.force
106
+ begin
107
+ unless options.noprompt
108
+ options.password = ask("Password: ") unless options.password
109
+ options.output= ask("Output path (default: location of encrypted files): ") unless options.output
110
+ end
111
+
112
+ raise "no files were passed through arguments" if args.empty?
113
+ raise "'password' is required" if is_empty?(options.password)
114
+
115
+ Exportation::Crypter.new(
116
+ files: args,
117
+ password: options.password,
118
+ output: options.output
119
+ ).run :de, options.force
120
+ rescue Exception => e
121
+ log "Error".red, e.message.red
122
+ end
76
123
 
77
124
  end
78
125
  end
data/lib/exportation.rb CHANGED
@@ -2,10 +2,8 @@ module Exportation
2
2
 
3
3
  def self.gem_path
4
4
  if Gem::Specification::find_all_by_name('exportation').any?
5
- puts "looking in gem specification - #{Gem::Specification.find_by_name('exportation').gem_dir}"
6
5
  return Gem::Specification.find_by_name('exportation').gem_dir
7
6
  else
8
- puts "using current directory"
9
7
  return './'
10
8
  end
11
9
  end
@@ -71,24 +69,25 @@ module Exportation
71
69
 
72
70
  # Does the stuff
73
71
  files.each do |file|
74
- if File.exists? file
75
- output_file = file
76
- if output
77
- output_file = File.join(output, File.basename(file))
78
- end
79
-
80
- if crypt == :en
81
- output_file += '.enc'
82
- elsif crypt == :de
83
- output_file = output_file.gsub('.enc','')
84
- end
85
-
86
- bash = "openssl aes-256-cbc -k \"#{password}\" -in #{file} -out #{output_file} -a"
87
- puts "Running: #{bash}"
88
- `#{bash}`
89
- else
90
- puts "File does not exist - #{file}"
72
+ file = './' + file unless file.start_with? '/'
73
+ if File.exists? file
74
+ output_file = file
75
+ if !output.nil? && output.length > 0
76
+ output_file = File.join(output, File.basename(file))
91
77
  end
78
+
79
+ if crypt == :en
80
+ output_file += '.enc'
81
+ elsif crypt == :de
82
+ output_file = output_file.gsub('.enc','')
83
+ end
84
+
85
+ bash = "openssl aes-256-cbc -k \"#{password}\" -in #{file} -out #{output_file} -a"
86
+ puts "Running: #{bash}"
87
+ `#{bash}`
88
+ else
89
+ puts "File does not exist - #{file}"
90
+ end
92
91
  end
93
92
 
94
93
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exportation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Holtz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-18 00:00:00.000000000 Z
11
+ date: 2015-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dotenv
@@ -38,6 +38,34 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '4.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: colorize
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.7'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: terminal-notifier
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.6'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.6'
41
69
  description: CLI tool of easy exporting, encrypting, and decrypting of certificates
42
70
  and private keys using Keychain Acess and openssl
43
71
  email: me@joshholtz.com
@@ -51,7 +79,7 @@ files:
51
79
  - applescript/exportation.scpt
52
80
  - bin/exportation
53
81
  - lib/exportation.rb
54
- homepage: https://github.com/joshdholtz/fastlane-env-lanes
82
+ homepage: https://github.com/joshdholtz/exportation
55
83
  licenses:
56
84
  - MIT
57
85
  metadata: {}