heroku_ssl 0.6.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +45 -0
- data/Rakefile +36 -0
- data/app/assets/config/heroku_ssl_manifest.js +2 -0
- data/app/assets/javascripts/heroku_ssl/application.js +13 -0
- data/app/assets/javascripts/heroku_ssl/heroku_ssl.js +2 -0
- data/app/assets/stylesheets/heroku_ssl/application.css +15 -0
- data/app/assets/stylesheets/heroku_ssl/heroku_ssl.css +4 -0
- data/app/controllers/heroku_ssl/application_controller.rb +5 -0
- data/app/controllers/heroku_ssl/heroku_ssl_controller.rb +12 -0
- data/app/helpers/heroku_ssl/application_helper.rb +4 -0
- data/app/helpers/heroku_ssl/heroku_ssl_helper.rb +4 -0
- data/app/jobs/heroku_ssl/application_job.rb +4 -0
- data/app/mailers/heroku_ssl/application_mailer.rb +6 -0
- data/app/models/heroku_ssl/application_record.rb +5 -0
- data/app/views/layouts/heroku_ssl/application.html.erb +14 -0
- data/config/routes.rb +5 -0
- data/lib/heroku_ssl/engine.rb +5 -0
- data/lib/heroku_ssl/ssl.rb +187 -0
- data/lib/heroku_ssl/version.rb +3 -0
- data/lib/heroku_ssl.rb +6 -0
- data/lib/tasks/heroku_ssl_tasks.rake +162 -0
- metadata +108 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 00f612a6491420af98a63a207d0d1d17a6a20bbf
|
4
|
+
data.tar.gz: 327c380d45de0e67ff691fa886bb5abd8d0ccd12
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ca5e94d5682c154c1961976f27c47d9a47eb5cb17a1674a6d3c7305e29f32a800d97da5eec682b34a3d58cefb5afa65a4892b9ce666583c63318757260639fa3
|
7
|
+
data.tar.gz: 68eff01513b554ef21f7f3af737d19f0dda30666577fb9c74221221adcecb97ed2bd2cfc60696afe1a9c11af9228fa5a965230f989f481902952383700d1b9b1
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2016 Kai Marshland
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# Heroku SSL
|
2
|
+
With the advent of free SSL from [Let's Encrypt](https://letsencrypt.org/), SSL should be as easy as clicking a button.
|
3
|
+
|
4
|
+
## Usage on Heroku
|
5
|
+
Add this gem to your gemfile, then deploy it to heroku.
|
6
|
+
Then, you can simply run `rake ssl:update_heroku_certs`
|
7
|
+
|
8
|
+
This should prompt you for everything you need to update your shiny new SSL certificate!
|
9
|
+
The only thing left to do will be to [configure your DNS correctly](https://devcenter.heroku.com/articles/ssl-endpoint#dns-and-domain-configuration).
|
10
|
+
You'll also want to make sure that the domain had been added to heroku with `heroku domains:add [your domain]`
|
11
|
+
|
12
|
+
## Usage outside of Heroku
|
13
|
+
Although designed for Heroku, it can generate certificates on other providers.
|
14
|
+
To do so, on your server, run `rake ssl:generate_certs`.
|
15
|
+
This will print a JSON encoded set of PEM keys to the console.
|
16
|
+
You can download these (you will likely want to use `privkey` and `fullchain` as your public and private keys respectively)
|
17
|
+
and add them to your own servers and configure the DNS yourself.
|
18
|
+
|
19
|
+
## Installation
|
20
|
+
Add this line to your application's Gemfile:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
gem 'heroku-ssl'
|
24
|
+
```
|
25
|
+
|
26
|
+
Or, to test the bleeding edge version:
|
27
|
+
```ruby
|
28
|
+
gem 'heroku_ssl', git: 'https://github.com/KMarshland/heroku-ssl.git'
|
29
|
+
```
|
30
|
+
|
31
|
+
And then execute:
|
32
|
+
```bash
|
33
|
+
$ bundle install
|
34
|
+
```
|
35
|
+
|
36
|
+
It also requires one of the following:
|
37
|
+
- The global variable `$redis` is set
|
38
|
+
- The environment variable `REDIS_URL` is set
|
39
|
+
- The environment variable `HEROKU_REDIS_URL` is set
|
40
|
+
|
41
|
+
## Contributing
|
42
|
+
Submit a pull request!
|
43
|
+
|
44
|
+
## License
|
45
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'HerokuSsl'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
load 'rails/tasks/statistics.rake'
|
22
|
+
|
23
|
+
|
24
|
+
require 'bundler/gem_tasks'
|
25
|
+
|
26
|
+
require 'rake/testtask'
|
27
|
+
|
28
|
+
Rake::TestTask.new(:test) do |t|
|
29
|
+
t.libs << 'lib'
|
30
|
+
t.libs << 'test'
|
31
|
+
t.pattern = 'test/**/*_test.rb'
|
32
|
+
t.verbose = false
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
task default: :test
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require_dependency "heroku_ssl/application_controller"
|
2
|
+
|
3
|
+
module HerokuSsl
|
4
|
+
class HerokuSslController < ApplicationController
|
5
|
+
|
6
|
+
def challenge
|
7
|
+
response = HerokuSsl::redis_instance.get("ssl-challenge-#{params[:challenge]}")
|
8
|
+
render text: response
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Heroku ssl</title>
|
5
|
+
<%= stylesheet_link_tag "heroku_ssl/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "heroku_ssl/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'acme-client'
|
3
|
+
|
4
|
+
module HerokuSsl
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def endpoint
|
8
|
+
# Use 'https://acme-staging.api.letsencrypt.org/' for development
|
9
|
+
|
10
|
+
'https://acme-v01.api.letsencrypt.org/'
|
11
|
+
end
|
12
|
+
|
13
|
+
def redis_instance
|
14
|
+
|
15
|
+
return $redis if $redis.present?
|
16
|
+
return $heroku_ssl_redis if $heroku_ssl_redis.present?
|
17
|
+
|
18
|
+
redis_url = ENV['REDIS_URL'] || ENV['HEROKU_REDIS_URL'] || 'redis://127.0.0.1:6379/0'
|
19
|
+
$heroku_ssl_redis = Redis.new(:url => redis_url)
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
# Where the certificates are stored
|
24
|
+
def cert_directory
|
25
|
+
Rails.root.join('certs')
|
26
|
+
end
|
27
|
+
|
28
|
+
def write(filename, content)
|
29
|
+
FileUtils.mkdir_p cert_directory
|
30
|
+
|
31
|
+
File.write(cert_directory.join(filename), content)
|
32
|
+
end
|
33
|
+
|
34
|
+
def read(filename)
|
35
|
+
FileUtils.mkdir_p cert_directory
|
36
|
+
|
37
|
+
return nil unless File.exists? cert_directory.join(filename)
|
38
|
+
|
39
|
+
File.read cert_directory.join(filename)
|
40
|
+
end
|
41
|
+
|
42
|
+
def gen_unless_exists(filename)
|
43
|
+
existing = read filename
|
44
|
+
return existing if existing.present?
|
45
|
+
|
46
|
+
created = yield filename
|
47
|
+
write filename, created
|
48
|
+
|
49
|
+
created
|
50
|
+
end
|
51
|
+
|
52
|
+
#forcibly regenerates the account private key
|
53
|
+
def regenerate_private_key
|
54
|
+
@private_key = OpenSSL::PKey::RSA.new(4096)
|
55
|
+
write('account.pem', @private_key.export)
|
56
|
+
|
57
|
+
@private_key
|
58
|
+
end
|
59
|
+
|
60
|
+
#returns any existing account private key; only generates a new one if none exist
|
61
|
+
def private_key
|
62
|
+
return @private_key if @private_key.present?
|
63
|
+
|
64
|
+
pem = read "#{Rails.env}/account.pem"
|
65
|
+
if pem.present?
|
66
|
+
@private_key = OpenSSL::PKey::RSA.new(pem)
|
67
|
+
else
|
68
|
+
regenerate_private_key
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def client
|
74
|
+
@client ||= Acme::Client.new(
|
75
|
+
private_key: private_key,
|
76
|
+
endpoint: endpoint,
|
77
|
+
connection_options: {
|
78
|
+
request: {
|
79
|
+
open_timeout: 5,
|
80
|
+
timeout: 5
|
81
|
+
}
|
82
|
+
}
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
86
|
+
#adds a contact for a domain
|
87
|
+
def register(email)
|
88
|
+
# If the private key is not known to the server, we need to register it for the first time.
|
89
|
+
registration = client.register(contact: "mailto:#{email}")
|
90
|
+
|
91
|
+
# You may need to agree to the terms of service (that's up the to the server to require it or not but boulder does by default)
|
92
|
+
registration.agree_terms
|
93
|
+
rescue Acme::Client::Error::Malformed => e
|
94
|
+
if e.message == 'Registration key is already in use'
|
95
|
+
puts 'Already registered'
|
96
|
+
else
|
97
|
+
raise e
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def authorize(domain)
|
102
|
+
if domain.is_a? Array
|
103
|
+
domain.each do |dom|
|
104
|
+
authorize dom
|
105
|
+
end
|
106
|
+
|
107
|
+
return
|
108
|
+
end
|
109
|
+
|
110
|
+
authorization = client.authorize(domain: domain)
|
111
|
+
|
112
|
+
return if authorization.status == 'valid'
|
113
|
+
|
114
|
+
# This example is using the http-01 challenge type. Other challenges are dns-01 or tls-sni-01.
|
115
|
+
challenge = authorization.http01
|
116
|
+
|
117
|
+
redis_instance.set("ssl-challenge-#{challenge.filename.split('/').last}", challenge.file_content)
|
118
|
+
redis_instance.expire("ssl-challenge-#{challenge.filename.split('/').last}", 5.minutes)
|
119
|
+
|
120
|
+
challenge.request_verification
|
121
|
+
|
122
|
+
# Wait a bit for the server to make the request, or just blink. It should be fast.
|
123
|
+
sleep(1)
|
124
|
+
|
125
|
+
status = nil
|
126
|
+
begin
|
127
|
+
# May sometimes give an error, for mysterious reasons
|
128
|
+
status = challenge.authorization.verify_status
|
129
|
+
rescue
|
130
|
+
end
|
131
|
+
|
132
|
+
#alternate method to read authorization status
|
133
|
+
status = client.authorize(domain: domain).status if status == 'pending' || status.blank?
|
134
|
+
|
135
|
+
unless status == 'valid'
|
136
|
+
puts challenge.error
|
137
|
+
raise "Did not verify client. Status is still #{status}"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def try_authorize(domain, retries=1)
|
142
|
+
begin
|
143
|
+
authorize domain
|
144
|
+
return true
|
145
|
+
rescue RuntimeError => e
|
146
|
+
puts e.message
|
147
|
+
|
148
|
+
if retries > 0
|
149
|
+
puts 'Retrying domain authorization...'
|
150
|
+
return try_authorize domain, retries-1
|
151
|
+
else
|
152
|
+
return false
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def request_certificate(domain)
|
158
|
+
unless try_authorize domain
|
159
|
+
puts 'Domain authorization failed. Aborting operation'
|
160
|
+
return
|
161
|
+
end
|
162
|
+
|
163
|
+
csr = Acme::Client::CertificateRequest.new(names: [*domain])
|
164
|
+
|
165
|
+
# We can now request a certificate. You can pass anything that returns
|
166
|
+
# a valid DER encoded CSR when calling to_der on it. For example an
|
167
|
+
# OpenSSL::X509::Request should work too.
|
168
|
+
certificate = client.new_certificate(csr)
|
169
|
+
|
170
|
+
{
|
171
|
+
privkey: certificate.request.private_key.to_pem,
|
172
|
+
cert: certificate.to_pem,
|
173
|
+
chain: certificate.chain_to_pem,
|
174
|
+
fullchain: certificate.fullchain_to_pem
|
175
|
+
}
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
def create_dh_params
|
180
|
+
gen_unless_exists 'dhparam.pem' do |filename|
|
181
|
+
`openssl dhparam -out #{filename} 4096`
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
data/lib/heroku_ssl.rb
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
|
2
|
+
namespace :heroku_ssl do
|
3
|
+
|
4
|
+
task :update_certs do
|
5
|
+
STDOUT.puts 'Once your app has been deployed to Heroku, hit enter.'
|
6
|
+
|
7
|
+
STDIN.gets
|
8
|
+
|
9
|
+
email = get_email
|
10
|
+
domains = get_domains
|
11
|
+
app = get_app
|
12
|
+
|
13
|
+
puts "Attempting to generate ssl certificates for #{app} (registering #{domains} to #{email})"
|
14
|
+
|
15
|
+
#generate the certs on the server
|
16
|
+
output = `unset RUBYOPT; heroku run rake heroku_ssl:generate_certs #{email} #{domains} --app #{app}`
|
17
|
+
|
18
|
+
#read out the certs to temporary files
|
19
|
+
if output.include? '~~ GENERATED CERTIFICATES START ~~'
|
20
|
+
puts 'Successfully generated certificates! Attempting to update Heroku DNS'
|
21
|
+
|
22
|
+
output = output.split('~~ GENERATED CERTIFICATES START ~~').last
|
23
|
+
.split('~~ GENERATED CERTIFICATES END ~~').first
|
24
|
+
output = JSON(output)
|
25
|
+
|
26
|
+
File.open('fullchain.pem', 'wb') do |file|
|
27
|
+
file.write output['fullchain']
|
28
|
+
end
|
29
|
+
|
30
|
+
File.open('privkey.pem', 'wb') do |file|
|
31
|
+
file.write output['privkey']
|
32
|
+
end
|
33
|
+
|
34
|
+
# update heroku certs
|
35
|
+
# RUBYOPT breaks the heroku command for some reason, so you have to unset it
|
36
|
+
`unset RUBYOPT; heroku certs:update fullchain.pem privkey.pem --app #{get_app} --confirm #{get_app}`
|
37
|
+
|
38
|
+
# clean up
|
39
|
+
File.delete('fullchain.pem', 'privkey.pem')
|
40
|
+
|
41
|
+
puts 'Successfully updated Heroku SSL certificates! Now you just need to make sure your DNS is configured to point as follows: '
|
42
|
+
puts `unset RUBYOPT; heroku domains`.split("\n")[4..-1].join("\n")
|
43
|
+
else
|
44
|
+
puts 'Full log: '
|
45
|
+
puts output
|
46
|
+
puts ''
|
47
|
+
|
48
|
+
puts 'Could not generate certificates. Please try again later or try running `heroku run rake heroku_ssl:generate_certs` directly'
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
task :generate_certs do
|
54
|
+
email = (ARGV[1] || '').strip
|
55
|
+
email = get_email if email.blank?
|
56
|
+
|
57
|
+
puts "Registering #{email}"
|
58
|
+
HerokuSsl::register email
|
59
|
+
|
60
|
+
domain = ARGV[2..-1]
|
61
|
+
domain = get_domains if domain.blank?
|
62
|
+
|
63
|
+
puts "Authorizing and generating certificates for #{domain}"
|
64
|
+
|
65
|
+
certs = HerokuSsl::request_certificate domain
|
66
|
+
|
67
|
+
if certs.present?
|
68
|
+
STDOUT.puts '~~ GENERATED CERTIFICATES START ~~'
|
69
|
+
STDOUT.puts JSON(certs)
|
70
|
+
STDOUT.puts '~~ GENERATED CERTIFICATES END ~~'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_email
|
75
|
+
return @email if @email.present?
|
76
|
+
|
77
|
+
@email = `git config user.email`
|
78
|
+
@email.strip! if @email.present?
|
79
|
+
|
80
|
+
default_prompt = ''
|
81
|
+
default_prompt = " [#{@email}]" if @email.present?
|
82
|
+
|
83
|
+
new_email = nil
|
84
|
+
while new_email.blank?
|
85
|
+
STDOUT.puts "Enter your email#{default_prompt}: "
|
86
|
+
new_email = STDIN.gets
|
87
|
+
|
88
|
+
if new_email.blank?
|
89
|
+
new_email = @email
|
90
|
+
else
|
91
|
+
new_email.strip!
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
@email = new_email
|
96
|
+
end
|
97
|
+
|
98
|
+
def get_domains
|
99
|
+
return @domain if @domain.present?
|
100
|
+
|
101
|
+
domains = `unset RUBYOPT; heroku domains`.split("\n").select(&:present?)[5..-1]
|
102
|
+
domains.map! do |domain|
|
103
|
+
domain.split(/\s+/).first
|
104
|
+
end
|
105
|
+
@domain = domains.join ' '
|
106
|
+
|
107
|
+
default_prompt = ''
|
108
|
+
default_prompt = " [#{@domain}]" if @domain.present?
|
109
|
+
|
110
|
+
new_domain = nil
|
111
|
+
while new_domain.blank?
|
112
|
+
STDOUT.puts "Enter the domain to register#{default_prompt}: "
|
113
|
+
new_domain = STDIN.gets
|
114
|
+
|
115
|
+
if new_domain.blank?
|
116
|
+
new_domain = @domain
|
117
|
+
else
|
118
|
+
new_domain.strip!
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
@domain = new_domain
|
123
|
+
end
|
124
|
+
|
125
|
+
def get_app
|
126
|
+
return @app if @app.present?
|
127
|
+
|
128
|
+
@apps = @apps || `unset RUBYOPT; heroku apps`.split("\n")
|
129
|
+
remotes = `git remote -v`.split("\n").map do |r|
|
130
|
+
r.split("\t").last
|
131
|
+
end
|
132
|
+
|
133
|
+
@apps.each do |app|
|
134
|
+
remotes.each do |remote|
|
135
|
+
if remote.include? app
|
136
|
+
@app = app
|
137
|
+
break
|
138
|
+
end
|
139
|
+
end
|
140
|
+
break if @app.present?
|
141
|
+
end
|
142
|
+
|
143
|
+
default_prompt = ''
|
144
|
+
default_prompt = " [#{@app}]" if @app.present?
|
145
|
+
|
146
|
+
new_app = nil
|
147
|
+
while new_app.blank?
|
148
|
+
STDOUT.puts "Enter the heroku app#{default_prompt}: "
|
149
|
+
new_app = STDIN.gets
|
150
|
+
|
151
|
+
if new_app.blank?
|
152
|
+
new_app = @app
|
153
|
+
else
|
154
|
+
new_app.strip!
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
@app = new_app
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: heroku_ssl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.6.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kai Marshland
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-11-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: acme-client
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.4.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.4.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: redis
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
description: Designed for Heroku, but can be adapted for other hosts as well
|
56
|
+
email:
|
57
|
+
- kaimarshland@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- MIT-LICENSE
|
63
|
+
- README.md
|
64
|
+
- Rakefile
|
65
|
+
- app/assets/config/heroku_ssl_manifest.js
|
66
|
+
- app/assets/javascripts/heroku_ssl/application.js
|
67
|
+
- app/assets/javascripts/heroku_ssl/heroku_ssl.js
|
68
|
+
- app/assets/stylesheets/heroku_ssl/application.css
|
69
|
+
- app/assets/stylesheets/heroku_ssl/heroku_ssl.css
|
70
|
+
- app/controllers/heroku_ssl/application_controller.rb
|
71
|
+
- app/controllers/heroku_ssl/heroku_ssl_controller.rb
|
72
|
+
- app/helpers/heroku_ssl/application_helper.rb
|
73
|
+
- app/helpers/heroku_ssl/heroku_ssl_helper.rb
|
74
|
+
- app/jobs/heroku_ssl/application_job.rb
|
75
|
+
- app/mailers/heroku_ssl/application_mailer.rb
|
76
|
+
- app/models/heroku_ssl/application_record.rb
|
77
|
+
- app/views/layouts/heroku_ssl/application.html.erb
|
78
|
+
- config/routes.rb
|
79
|
+
- lib/heroku_ssl.rb
|
80
|
+
- lib/heroku_ssl/engine.rb
|
81
|
+
- lib/heroku_ssl/ssl.rb
|
82
|
+
- lib/heroku_ssl/version.rb
|
83
|
+
- lib/tasks/heroku_ssl_tasks.rake
|
84
|
+
homepage: https://github.com/KMarshland/heroku-ssl
|
85
|
+
licenses:
|
86
|
+
- MIT
|
87
|
+
metadata: {}
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 2.5.1
|
105
|
+
signing_key:
|
106
|
+
specification_version: 4
|
107
|
+
summary: Quickly and easily add SSL to a Rails App with Let's Encrypt
|
108
|
+
test_files: []
|