fastlane-plugin-cryptex 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6286c3236e933597fcaa231151783c966173268c
4
+ data.tar.gz: c2e7ecfbfbc3fc0fcec787d3197373b389ab4c92
5
+ SHA512:
6
+ metadata.gz: b655c7072780622600f14be3cde5d3b5991999ab8d3616fc7ceef21d2b420ee3e23549fb0264ee11a8fdd4e45e7dd4040ed5b2a92dcf568fa7a383334b28941f
7
+ data.tar.gz: cde2607785293bb1c723d6d9af184424e65f124edb6df600f434fcd9dbf8dc74d1b03f0e06457c0179a7be5d0c04cdcd8b2b003bf0ed48412ecc4941365bbf0c
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Helmut Januschka <h.januschka@krone.at>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,138 @@
1
+ # cryptex plugin
2
+
3
+ [![fastlane Plugin Badge](https://rawcdn.githack.com/fastlane/fastlane/master/fastlane/assets/plugin-badge.svg)](https://rubygems.org/gems/fastlane-plugin-cryptex)
4
+
5
+ ## Getting Started
6
+
7
+ This project is a [fastlane](https://github.com/fastlane/fastlane) plugin. To get started with `fastlane-plugin-cryptex`, add it to your project by running:
8
+
9
+ ```bash
10
+ fastlane add_plugin cryptex
11
+ ```
12
+
13
+ ## About cryptex
14
+
15
+ Android Key Store Git repo
16
+
17
+ **Note to author:** Add a more detailed description about this plugin here. If your plugin contains multiple actions, make sure to mention them here.
18
+
19
+ ## Example
20
+
21
+ ```ruby
22
+
23
+ lane :test do
24
+ # Generate a new Android Keystore
25
+
26
+ cryptex_generate_keystore(
27
+ destination: "sample.keystore",
28
+ fullname: "Helmut Januschka",
29
+ city: "Vienna",
30
+ alias: "releaseKey"
31
+ )
32
+
33
+ # import/update this in cryptex
34
+ cryptex(
35
+ type: "import",
36
+ in: "sample.keystore",
37
+ key: "my_awesome_app_production"
38
+ )
39
+
40
+ # export a file from cryptex
41
+ cryptex(
42
+ type: "export",
43
+ out: "releaseKey.keystore",
44
+ key: "my_awesome_app_production"
45
+ )
46
+
47
+ file_output = File.read("../releaseKey.keystore")
48
+ puts "File Content: #{file_output.tr("\n", ' ')}"
49
+
50
+ # delete the file
51
+ cryptex(
52
+ type: "delete",
53
+ key: "my_awesome_app_production"
54
+ )
55
+
56
+ # Nuke's all files
57
+ cryptex(
58
+ type: "nuke"
59
+ )
60
+
61
+
62
+ #ENV SAMPLES
63
+ #import some env into the space of `my_group`
64
+ cryptex(
65
+ type: "import_env",
66
+ hash: {
67
+ "helmut" => "go",
68
+ "some_url" => "http://lets.do.it"
69
+ },
70
+ key: "my_group"
71
+ )
72
+ env_out = cryptex(
73
+ type: "export_env",
74
+ key: "my_group",
75
+ set_env: true #THIS one sets the values found directly into to ENV
76
+ #hash: {"my_key"=>true, "some_url"=>true} # only returned specific keys
77
+ )
78
+
79
+ puts "IN ENV it is:"
80
+ puts ENV['some_url']
81
+ puts "returned: #{env_out.inspect}"
82
+
83
+ end
84
+
85
+
86
+ ```
87
+
88
+ ## Commandline Examples:
89
+
90
+ ```bash
91
+ #init
92
+ cryptex init
93
+
94
+ # import file
95
+ cryptex -s import -i file_to_hide.txt -k file_key
96
+
97
+ # export file
98
+ cryptex -s export -k file_key -o file_to_hide.txt
99
+
100
+ #delete file
101
+ cryptex -s delete -k file_key
102
+
103
+ #nuke repo
104
+ cryptex nuke
105
+
106
+
107
+ ```
108
+
109
+
110
+
111
+ ## Run tests for this plugin
112
+
113
+ To run both the tests, and code style validation, run
114
+
115
+ ```
116
+ rake
117
+ ```
118
+
119
+ To automatically fix many of the styling issues, use
120
+ ```
121
+ rubocop -a
122
+ ```
123
+
124
+ ## Issues and Feedback
125
+
126
+ For any other issues and feedback about this plugin, please submit it to this repository.
127
+
128
+ ## Troubleshooting
129
+
130
+ If you have trouble using plugins, check out the [Plugins Troubleshooting](https://github.com/fastlane/fastlane/blob/master/fastlane/docs/PluginsTroubleshooting.md) doc in the main `fastlane` repo.
131
+
132
+ ## Using `fastlane` Plugins
133
+
134
+ For more information about how the `fastlane` plugin system works, check out the [Plugins documentation](https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Plugins.md).
135
+
136
+ ## About `fastlane`
137
+
138
+ `fastlane` is the easiest way to automate building and releasing your iOS and Android apps. To learn more, check out [fastlane.tools](https://fastlane.tools).
data/bin/cryptex ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ $:.push File.expand_path("../../lib", __FILE__)
3
+
4
+ require 'fastlane'
5
+ require 'fastlane/plugin/cryptex'
6
+
7
+ Fastlane::Cryptex::CommandsGenerator.start
@@ -0,0 +1,25 @@
1
+
2
+ module Fastlane
3
+ module Cryptex
4
+ ROOT = Pathname.new(File.expand_path('lib/fastlane/plugin/cryptex'))
5
+ # Return all .rb files inside the "actions" and "helper" directory
6
+ def self.all_classes
7
+ Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
8
+ end
9
+ end
10
+ end
11
+
12
+ require 'fastlane/plugin/cryptex/options'
13
+ require 'fastlane/plugin/cryptex/change_password'
14
+ require 'fastlane/plugin/cryptex/version'
15
+ require 'fastlane/plugin/cryptex/setup'
16
+ require 'fastlane/plugin/cryptex/git_helper'
17
+ require 'fastlane/plugin/cryptex/encrypt'
18
+ require 'fastlane/plugin/cryptex/runner'
19
+ require 'fastlane/plugin/cryptex/commands_generator'
20
+
21
+ # By default we want to import all available actions and helpers
22
+ # A plugin can contain any number of actions and plugins
23
+ Fastlane::Cryptex.all_classes.each do |current|
24
+ require current
25
+ end
@@ -0,0 +1,29 @@
1
+ module Fastlane
2
+ module Actions
3
+ class CryptexAction < Action
4
+ def self.run(params)
5
+ UI.message("The cryptex plugin is working!")
6
+
7
+ params.load_configuration_file("Cryptexfile")
8
+
9
+ Cryptex::Runner.new.run(params)
10
+ end
11
+
12
+ def self.description
13
+ "Secure Git-Backed Storage"
14
+ end
15
+
16
+ def self.authors
17
+ ["Helmut Januschka"]
18
+ end
19
+
20
+ def self.available_options
21
+ Cryptex::Options.available_options
22
+ end
23
+
24
+ def self.is_supported?(platform)
25
+ true
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,62 @@
1
+ module Fastlane
2
+ module Actions
3
+ class CryptexGenerateKeystoreAction < Action
4
+ def self.run(params)
5
+ require "fileutils"
6
+ cmd = "keytool -genkey -v -keystore #{File.expand_path(params[:destination])} -storepass #{params[:password]} -keypass #{params[:password]} -alias #{params[:alias]} -dname 'CN=#{params[:fullname]},L=#{params[:city]}' -validity 1000"
7
+ FastlaneCore::CommandExecutor.execute(command: cmd,
8
+ print_all: true,
9
+ print_command: true)
10
+
11
+ params[:destination]
12
+ end
13
+
14
+ def self.description
15
+ "Generate a new Android Keystore"
16
+ end
17
+
18
+ def self.authors
19
+ ["Helmut Januschka"]
20
+ end
21
+
22
+ def self.available_options
23
+ [
24
+ FastlaneCore::ConfigItem.new(key: :password,
25
+ env_name: "MATCH_KEYSTORE_PASSWORD",
26
+ description: "Password for the Keystore",
27
+ optional: true,
28
+ is_string: true,
29
+ default_value: ""),
30
+ FastlaneCore::ConfigItem.new(key: :alias,
31
+ env_name: "MATCH_KEYSTORE_ALIAS",
32
+ description: "ALIAS for the Keystore",
33
+ optional: true,
34
+ is_string: true,
35
+ default_value: ""),
36
+ FastlaneCore::ConfigItem.new(key: :destination,
37
+ env_name: "MATCH_KEYSTORE_DESTINATION",
38
+ description: "Where to put decrypted keystore",
39
+ optional: true,
40
+ default_value: ""),
41
+ FastlaneCore::ConfigItem.new(key: :fullname,
42
+ env_name: "MATCH_KEYSTORE_FULLNAME",
43
+ description: "Fullname of keystore owner",
44
+ optional: true,
45
+ is_string: true,
46
+ default_value: ""),
47
+ FastlaneCore::ConfigItem.new(key: :city,
48
+ env_name: "MATCH_KEYSTORE_CITY",
49
+ description: "City of keystore owner",
50
+ optional: true,
51
+ is_string: true,
52
+ default_value: "")
53
+
54
+ ]
55
+ end
56
+
57
+ def self.is_supported?(platform)
58
+ true
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1 @@
1
+ git_url "[[GIT_URL]]"
@@ -0,0 +1,2 @@
1
+ # cryptex
2
+
@@ -0,0 +1,32 @@
1
+ module Fastlane
2
+ module Cryptex
3
+ class ChangePassword
4
+ def self.update(params: nil, from: nil, to: nil)
5
+ to ||= ChangePassword.ask_password(message: "New passphrase for Git Repo: ", confirm: false)
6
+ from ||= ChangePassword.ask_password(message: "Old passphrase for Git Repo: ", confirm: true)
7
+ GitHelper.clear_changes
8
+ workspace = GitHelper.clone(params[:git_url], params[:shallow_clone], manual_password: from, skip_docs: params[:skip_docs], branch: params[:git_branch])
9
+ Encrypt.new.clear_password(params[:git_url])
10
+ Encrypt.new.store_password(params[:git_url], to)
11
+
12
+ message = "[fastlane] Changed passphrase"
13
+ GitHelper.commit_changes(workspace, message, params[:git_url], params[:git_branch])
14
+ end
15
+
16
+ def self.ask_password(message: "Passphrase for Git Repo: ", confirm: true)
17
+ loop do
18
+ password = UI.password(message)
19
+ if confirm
20
+ password2 = UI.password("Type passphrase again: ")
21
+ if password == password2
22
+ return password
23
+ end
24
+ else
25
+ return password
26
+ end
27
+ UI.error("Passhprases differ. Try again")
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,92 @@
1
+ require 'commander'
2
+
3
+ HighLine.track_eof = false
4
+ module Fastlane
5
+ module Cryptex
6
+ class CommandsGenerator
7
+ include Commander::Methods
8
+ UI = FastlaneCore::UI
9
+
10
+ def self.start
11
+ FastlaneCore::UpdateChecker.start_looking_for_update('cryptex')
12
+ self.new.run
13
+ ensure
14
+
15
+ FastlaneCore::UpdateChecker.show_update_status('cryptex', Cryptex::VERSION)
16
+ end
17
+
18
+ def run
19
+ program :version, Cryptex::VERSION
20
+ program :description, "Cryptex"
21
+ program :help, 'Author', 'Helmut Januschka <helmut@januschka.com>'
22
+ program :help, 'Website', 'https://fastlane.tools'
23
+ program :help, 'GitHub', 'https://github.com/hjanuschka/fastlane-plugin-cryptex'
24
+ program :help_formatter, :compact
25
+
26
+ global_option('--verbose') { $verbose = true }
27
+
28
+ FastlaneCore::CommanderGenerator.new.generate(Cryptex::Options.available_options)
29
+
30
+ command :run do |c|
31
+ c.syntax = 'cryptex'
32
+ c.description = Cryptex::DESCRIPTION
33
+ c.action do |args, options|
34
+ params = FastlaneCore::Configuration.create(Cryptex::Options.available_options, options.__hash__)
35
+ params.load_configuration_file("Cryptexfile")
36
+ Cryptex::Runner.new.run(params)
37
+ end
38
+ end
39
+
40
+ command :init do |c|
41
+ c.syntax = 'cryptex init'
42
+ c.description = 'Create the Cryptexfile for you'
43
+ c.action do |args, options|
44
+ containing = (File.directory?("fastlane") ? 'fastlane' : '.')
45
+ path = File.join(containing, "Cryptexfile")
46
+
47
+ if File.exist?(path)
48
+ FastlaneCore::UI.user_error!("You already got a Cryptexfile in this directory")
49
+ return 0
50
+ end
51
+
52
+ Cryptex::Setup.new.run(path)
53
+ end
54
+ end
55
+
56
+ command :change_password do |c|
57
+ c.syntax = 'cryptex change_password'
58
+ c.description = 'Re-encrypt all files with a different password'
59
+ c.action do |args, options|
60
+ puts "CHANGE PASSWORD"
61
+ end
62
+ end
63
+
64
+ command :decrypt do |c|
65
+ c.syntax = "cryptex decrypt"
66
+ c.description = "Decrypts the repository and keeps it on the filesystem"
67
+ c.action do |args, options|
68
+ params = FastlaneCore::Configuration.create(Match::Options.available_options, options.__hash__)
69
+ params.load_configuration_file("Cryptexfile")
70
+ decrypted_repo = Cryptex::GitHelper.clone(params[:git_url], params[:shallow_clone], branch: params[:git_branch])
71
+ UI.success "Repo is at: '#{decrypted_repo}'"
72
+ end
73
+ end
74
+ command "nuke" do |c|
75
+ # We have this empty command here, since otherwise the normal `match` command will be executed
76
+ c.syntax = "cryptex nuke"
77
+ c.description = "Delete all Crypted Files in the repository"
78
+ c.action do |args, options|
79
+ params = FastlaneCore::Configuration.create(Cryptex::Options.available_options, options.__hash__)
80
+ params.load_configuration_file("Cryptexfile")
81
+ params[:type] = "nuke"
82
+ Cryptex::Runner.new.run(params)
83
+ end
84
+ end
85
+
86
+ default_command :run
87
+
88
+ run!
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,95 @@
1
+ module Fastlane
2
+ module Cryptex
3
+ class Encrypt
4
+ require 'security'
5
+ require 'shellwords'
6
+
7
+ def server_name(git_url)
8
+ ["cryptex", git_url].join("_")
9
+ end
10
+
11
+ def password(git_url)
12
+ password = ENV["CRYPTEX_PASSWORD"]
13
+ unless password
14
+ item = Security::InternetPassword.find(server: server_name(git_url))
15
+ password = item.password if item
16
+ end
17
+
18
+ unless password
19
+ UI.important "Enter the passphrase that should be used to encrypt/decrypt your repository"
20
+ UI.important "This passphrase is specific per repository and will be stored in your local keychain"
21
+ UI.important "Make sure to remember the password, as you'll need it when you run cryptex on a different machine"
22
+ password = ChangePassword.ask_password(confirm: true)
23
+ store_password(git_url, password)
24
+ end
25
+
26
+ return password
27
+ end
28
+
29
+ def store_password(git_url, password)
30
+ Security::InternetPassword.add(server_name(git_url), "", password)
31
+ end
32
+
33
+ # removes the password from the keychain again
34
+ def clear_password(git_url)
35
+ Security::InternetPassword.delete(server: server_name(git_url))
36
+ end
37
+
38
+ def encrypt_repo(path: nil, git_url: nil)
39
+ iterate(path) do |current|
40
+ crypt(path: current,
41
+ password: password(git_url),
42
+ encrypt: true)
43
+ UI.success "🔒 Encrypted '#{File.basename(current)}'" if $verbose
44
+ end
45
+ UI.success "🔒 Successfully encrypted certificates repo"
46
+ end
47
+
48
+ def decrypt_repo(path: nil, git_url: nil, manual_password: nil)
49
+ iterate(path) do |current|
50
+ begin
51
+ crypt(path: current,
52
+ password: manual_password || password(git_url),
53
+ encrypt: false)
54
+ rescue
55
+ UI.error "Couldn't decrypt the repo, please make sure you enter the right password!"
56
+ UI.user_error!("Invalid password passed via 'CRYPTEX_PASSWORD'") if ENV["CRYPTEX_PASSWORD"]
57
+ clear_password(git_url)
58
+ decrypt_repo(path: path, git_url: git_url)
59
+ return
60
+ end
61
+ UI.success "🔓 Decrypted '#{File.basename(current)}'" if $verbose
62
+ end
63
+ UI.success "🔓 Successfully decrypted certificates repo"
64
+ end
65
+
66
+ def iterate(source_path)
67
+ Dir[File.join(source_path, "**", "*.{crypt}")].each do |path|
68
+ next if File.directory?(path)
69
+ yield(path)
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def crypt(path: nil, password: nil, encrypt: true)
76
+ if password.to_s.strip.length.zero? && encrypt
77
+ UI.user_error!("No password supplied")
78
+ end
79
+
80
+ tmpfile = File.join(Dir.mktmpdir, "temporary")
81
+ command = ["openssl aes-256-cbc"]
82
+ command << "-k #{password.shellescape}"
83
+ command << "-in #{path.shellescape}"
84
+ command << "-out #{tmpfile.shellescape}"
85
+ command << "-a"
86
+ command << "-d" unless encrypt
87
+ command << "&> /dev/null" unless $verbose # to show show an error message is something goes wrong
88
+ success = system(command.join(' '))
89
+
90
+ UI.crash!("Error decrypting '#{path}'") unless success
91
+ FileUtils.mv(tmpfile, path)
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,129 @@
1
+ module Fastlane
2
+ module Cryptex
3
+ class GitHelper
4
+ def self.clone(git_url, shallow_clone, manual_password: nil, skip_docs: false, branch: "master")
5
+ return @dir if @dir
6
+
7
+ @dir = Dir.mktmpdir
8
+
9
+ command = "git clone '#{git_url}' '#{@dir}'"
10
+ command << " --depth 1" if shallow_clone
11
+
12
+ UI.message "Cloning remote git repo..."
13
+ begin
14
+ FastlaneCore::CommandExecutor.execute(command: "GIT_TERMINAL_PROMPT=0 #{command}",
15
+ print_all: $verbose,
16
+ print_command: $verbose)
17
+ rescue
18
+ UI.error("Error cloning Repo")
19
+ UI.error("Run the following command manually to make sure you're properly authenticated:")
20
+ UI.command(command)
21
+ UI.user_error!("Error cloning cryptex git repo, please make sure you have access to the repository - see instructions above")
22
+ end
23
+
24
+ UI.user_error!("Error cloning repo, make sure you have access to it '#{git_url}'") unless File.directory?(@dir)
25
+
26
+ checkout_branch(branch) unless branch == "master"
27
+
28
+ copy_readme(@dir) unless skip_docs
29
+ Cryptex::Encrypt.new.decrypt_repo(path: @dir, git_url: git_url, manual_password: manual_password)
30
+
31
+ return @dir
32
+ end
33
+
34
+ def self.generate_commit_message(params)
35
+ # 'Automatic commit via fastlane'
36
+ [
37
+ "[fastlane]",
38
+ "Updated"
39
+ ].join(" ")
40
+ end
41
+
42
+ def self.cryptex_version(workspace)
43
+ path = File.join(workspace, "cryptex_version.txt")
44
+ if File.exist?(path)
45
+ Gem::Version.new(File.read(path))
46
+ end
47
+ end
48
+
49
+ def self.commit_changes(path, message, git_url, branch = "master")
50
+ Dir.chdir(path) do
51
+ return if `git status`.include?("nothing to commit")
52
+
53
+ Cryptex::Encrypt.new.encrypt_repo(path: path, git_url: git_url)
54
+ File.write("cryptex_version.txt", Cryptex::VERSION) # unencrypted
55
+
56
+ commands = []
57
+ commands << "git add -A"
58
+ commands << "git commit -m #{message.shellescape}"
59
+ commands << "GIT_TERMINAL_PROMPT=0 git push origin #{branch.shellescape}"
60
+
61
+ UI.message "Pushing changes to remote git repo..."
62
+
63
+ commands.each do |command|
64
+ FastlaneCore::CommandExecutor.execute(command: command,
65
+ print_all: $verbose,
66
+ print_command: $verbose)
67
+ end
68
+ end
69
+ FileUtils.rm_rf(path)
70
+ @dir = nil
71
+ rescue => ex
72
+ UI.error("Couldn't commit or push changes back to git...")
73
+ UI.error(ex)
74
+ end
75
+
76
+ def self.clear_changes
77
+ return unless @dir
78
+
79
+ FileUtils.rm_rf(@dir)
80
+ UI.success "🔒 Successfully encrypted certificates repo" # so the user is happy
81
+ @dir = nil
82
+ end
83
+
84
+ # Create and checkout an specific branch in the git repo
85
+ def self.checkout_branch(branch)
86
+ return unless @dir
87
+
88
+ commands = []
89
+ if branch_exists?(branch)
90
+ # Checkout the branch if it already exists
91
+ commands << "git checkout #{branch.shellescape}"
92
+ else
93
+ # If a new branch is being created, we create it as an 'orphan' to not inherit changes from the master branch.
94
+ commands << "git checkout --orphan #{branch.shellescape}"
95
+ # We also need to reset the working directory to not transfer any uncommitted changes to the new branch.
96
+ commands << "git reset --hard"
97
+ end
98
+
99
+ UI.message "Checking out branch #{branch}..."
100
+
101
+ Dir.chdir(@dir) do
102
+ commands.each do |command|
103
+ FastlaneCore::CommandExecutor.execute(command: command,
104
+ print_all: $verbose,
105
+ print_command: $verbose)
106
+ end
107
+ end
108
+ end
109
+
110
+ # Checks if a specific branch exists in the git repo
111
+ def self.branch_exists?(branch)
112
+ return unless @dir
113
+
114
+ result = Dir.chdir(@dir) do
115
+ FastlaneCore::CommandExecutor.execute(command: "git branch --list origin/#{branch.shellescape} --no-color -r",
116
+ print_all: $verbose,
117
+ print_command: $verbose)
118
+ end
119
+ return !result.empty?
120
+ end
121
+
122
+ # Copies the README.md into the git repo
123
+ def self.copy_readme(directory)
124
+ template = File.read("#{Cryptex::ROOT}/assets/READMETemplate.md")
125
+ File.write(File.join(directory, "README.md"), template)
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,12 @@
1
+ module Fastlane
2
+ module Helper
3
+ class CryptexHelper
4
+ # class methods that you define here become available in your action
5
+ # as `Helper::CryptexHelper.your_method`
6
+ #
7
+ def self.show_message
8
+ UI.message("Hello from the cryptex plugin helper!")
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,85 @@
1
+ require 'fastlane_core'
2
+ require 'credentials_manager'
3
+
4
+ module Fastlane
5
+ module Cryptex
6
+ class Options
7
+ def self.available_options
8
+ [
9
+ FastlaneCore::ConfigItem.new(key: :git_url,
10
+ env_name: "CRYPTEX_GIT_URL",
11
+ description: "URL to the git repo containing all the certificates",
12
+ optional: false,
13
+ short_option: "-r"),
14
+ FastlaneCore::ConfigItem.new(key: :workspace,
15
+ description: nil,
16
+ verify_block: proc do |value|
17
+ unless Helper.test?
18
+ if value.start_with?("/var/folders") or value.include?("tmp/") or value.include?("temp/")
19
+ # that's fine
20
+ else
21
+ UI.user_error!("Specify the `git_url` instead of the `path`")
22
+ end
23
+ end
24
+ end,
25
+ optional: true),
26
+ FastlaneCore::ConfigItem.new(key: :git_branch,
27
+ env_name: "CRYPTEX_GIT_BRANCH",
28
+ description: "Specific git branch to use",
29
+ default_value: 'master'),
30
+ FastlaneCore::ConfigItem.new(key: :key,
31
+ short_option: "-k",
32
+ env_name: "CRYPTEX_FILE_KEY",
33
+ description: "The File KEY",
34
+ default_value: ""),
35
+ FastlaneCore::ConfigItem.new(key: :in,
36
+ short_option: "-i",
37
+ env_name: "CRYPTEX_IN",
38
+ description: "The File KEY",
39
+ default_value: ""),
40
+
41
+ FastlaneCore::ConfigItem.new(key: :hash,
42
+ short_option: "-H",
43
+ env_name: "CRYPTEX_HASH",
44
+ description: "Hash",
45
+ optional: true,
46
+ is_string: false),
47
+ FastlaneCore::ConfigItem.new(key: :set_env,
48
+ short_option: "-e",
49
+ env_name: "CRYPTEX_SET_ENV",
50
+ description: "set found variables as ENV",
51
+ default_value: false,
52
+ is_string: false),
53
+ FastlaneCore::ConfigItem.new(key: :out,
54
+ short_option: "-o",
55
+ env_name: "CRYPTEX_OUT",
56
+ description: "The File KEY",
57
+ default_value: ""),
58
+ FastlaneCore::ConfigItem.new(key: :type,
59
+ short_option: "-s",
60
+ env_name: "CRYPTEX_TYPE",
61
+ description: "Sub-Action Type (export, import, decrypt)",
62
+ default_value: "export"),
63
+ FastlaneCore::ConfigItem.new(key: :verbose,
64
+ env_name: "CRYPTEX_VERBOSE",
65
+ description: "Print out extra information and all commands",
66
+ is_string: false,
67
+ default_value: false,
68
+ verify_block: proc do |value|
69
+ $verbose = true if value
70
+ end),
71
+ FastlaneCore::ConfigItem.new(key: :shallow_clone,
72
+ env_name: "CRYPTEX_SHALLOW_CLONE",
73
+ description: "Make a shallow clone of the repository (truncate the history to 1 revision)",
74
+ is_string: false,
75
+ default_value: false),
76
+ FastlaneCore::ConfigItem.new(key: :skip_docs,
77
+ env_name: "CRYPTEX_SKIP_DOCS",
78
+ description: "Skip generation of a README.md for the created git repository",
79
+ is_string: false,
80
+ default_value: false)
81
+ ]
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,88 @@
1
+ module Fastlane
2
+ module Cryptex
3
+ class Runner
4
+ attr_accessor :git_changed
5
+
6
+ def import_env(params)
7
+ env_world_file = "#{params[:workspace]}/#{params[:key]}_env_world.crypt"
8
+ File.write(env_world_file, params[:hash].to_json)
9
+ @git_changed = true
10
+ end
11
+
12
+ def export_env(params)
13
+ env_world_file = "#{params[:workspace]}/#{params[:key]}_env_world.crypt"
14
+ world_data = File.read(env_world_file)
15
+ world_data_parsed = JSON.parse(world_data)
16
+ ret_json = {}
17
+
18
+ world_data_parsed.keys.each do |el|
19
+ next unless !params[:hash] || (params[:hash] && params[:hash].keys.include?(el))
20
+ ret_json[el] = world_data_parsed[el]
21
+ if params[:set_env]
22
+ ENV[el] = world_data_parsed[el]
23
+ end
24
+ end
25
+ return world_data_parsed
26
+ end
27
+
28
+ def import_file(params)
29
+ File.write("#{params[:workspace]}/#{params[:key]}.crypt", File.read(File.expand_path(params[:in])))
30
+ @git_changed = true
31
+ end
32
+
33
+ def delete_file(params)
34
+ FileUtils.rm_f "#{params[:workspace]}/#{params[:key]}.crypt"
35
+ @git_changed = true
36
+ end
37
+
38
+ def export_file(params)
39
+ File.write(File.expand_path(params[:out]), File.read("#{params[:workspace]}/#{params[:key]}.crypt"))
40
+ @git_changed = true
41
+ end
42
+
43
+ def nuke_all(params)
44
+ Encrypt.new.iterate(params[:workspace]) do |item|
45
+ FileUtils.rm_f item
46
+ end
47
+ @git_changed = true
48
+ end
49
+
50
+ def run(params)
51
+ FastlaneCore::PrintTable.print_values(config: params,
52
+ hide_keys: [],
53
+ title: "Summary for cryptex #{Cryptex::VERSION}")
54
+ @git_changed = false
55
+ params[:workspace] = GitHelper.clone(params[:git_url], params[:shallow_clone], skip_docs: params[:skip_docs], branch: params[:git_branch])
56
+ @params = params
57
+ if params[:type] == "import_env"
58
+ return import_env(params)
59
+ end
60
+ if params[:type] == "export_env"
61
+ return export_env(params)
62
+ end
63
+ if params[:type] == "import"
64
+ import_file(params)
65
+ return
66
+ end
67
+ if params[:type] == "delete"
68
+ delete_file(params)
69
+ return
70
+ end
71
+ if params[:type] == "export"
72
+ export_file(params)
73
+ return
74
+ end
75
+ if params[:type] == "nuke"
76
+ nuke_all(params)
77
+ return
78
+ end
79
+ ensure
80
+ if git_changed
81
+ message = GitHelper.generate_commit_message(params)
82
+ GitHelper.commit_changes(params[:workspace], message, params[:git_url], params[:git_branch])
83
+ end
84
+ GitHelper.clear_changes
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,17 @@
1
+ module Fastlane
2
+ module Cryptex
3
+ class Setup
4
+ def run(path)
5
+ template = File.read("#{Cryptex::ROOT}/assets/CryptexfileTemplate")
6
+
7
+ UI.important "Please create a new, private git repository"
8
+ UI.important "to store the certificates and profiles there"
9
+ url = UI.input("URL of the Git Repo: ")
10
+
11
+ template.gsub!("[[GIT_URL]]", url)
12
+ File.write(path, template)
13
+ UI.success "Successfully created '#{path}'. You can open the file using a code editor."
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ module Fastlane
2
+ module Cryptex
3
+ VERSION = "0.1.0"
4
+ DESCRIPTION = "cryptex"
5
+ end
6
+ end
metadata ADDED
@@ -0,0 +1,173 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fastlane-plugin-cryptex
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Helmut Januschka
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-11-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: commander
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 4.3.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 4.3.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: fastlane
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 1.105.2
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 1.105.2
111
+ - !ruby/object:Gem::Dependency
112
+ name: match
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: 0.8.1
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: 0.8.1
125
+ description:
126
+ email: h.januschka@krone.at
127
+ executables:
128
+ - cryptex
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - LICENSE
133
+ - README.md
134
+ - bin/cryptex
135
+ - lib/fastlane/plugin/cryptex.rb
136
+ - lib/fastlane/plugin/cryptex/actions/cryptex_action.rb
137
+ - lib/fastlane/plugin/cryptex/actions/cryptex_generate_keystore.rb
138
+ - lib/fastlane/plugin/cryptex/assets/CryptexfileTemplate
139
+ - lib/fastlane/plugin/cryptex/assets/READMETemplate.md
140
+ - lib/fastlane/plugin/cryptex/change_password.rb
141
+ - lib/fastlane/plugin/cryptex/commands_generator.rb
142
+ - lib/fastlane/plugin/cryptex/encrypt.rb
143
+ - lib/fastlane/plugin/cryptex/git_helper.rb
144
+ - lib/fastlane/plugin/cryptex/helper/cryptex_helper.rb
145
+ - lib/fastlane/plugin/cryptex/options.rb
146
+ - lib/fastlane/plugin/cryptex/runner.rb
147
+ - lib/fastlane/plugin/cryptex/setup.rb
148
+ - lib/fastlane/plugin/cryptex/version.rb
149
+ homepage:
150
+ licenses:
151
+ - MIT
152
+ metadata: {}
153
+ post_install_message:
154
+ rdoc_options: []
155
+ require_paths:
156
+ - lib
157
+ required_ruby_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ required_rubygems_version: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ requirements: []
168
+ rubyforge_project:
169
+ rubygems_version: 2.4.8
170
+ signing_key:
171
+ specification_version: 4
172
+ summary: fastlane Crypt Store Git repo
173
+ test_files: []