exportation 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: {}