encryptbot 0.1.7 → 0.1.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c11220ad68f23896f0b736d977e06a569ca4552746d99793f59efda46bc88a6
4
- data.tar.gz: 0172a1b4a558e2ca2d59b48a99f79c543ad6ef7ad42758ff4bbccca4c72e71be
3
+ metadata.gz: 9e7e74780b62f252a70d355c14303aae026fecf987687b9029e363d1f956278a
4
+ data.tar.gz: 15c849942b0be5615dfcd12ba47b77d457a8b6a116ebe2f4ca8ca4cfb5612930
5
5
  SHA512:
6
- metadata.gz: cf7fd9ebd8e1710fbe9c1a56f1dc560b2d9603b53e9e0a403aedbd094dc37d8e69e415e4b3b58116f28e5a12dc0b0d2651fafd9a3b12ec4346ff8eceeb2598c1
7
- data.tar.gz: facab7606bf80df0bdf6ad391c68787bc3e030181cc984b67c50d039cb23ab8cbf406f5f3efaf09025263a872adf1bf7178eba3f8eb9af10a0542ce865117c9c
6
+ metadata.gz: b1c8059dcabce152577657c3125678e604caaebd5fd04d4b1b7b82f7be0ab38c274180facf8b7b0f442ed9a6afcd11378bedcb0bfb360daa1adacb23935032fc
7
+ data.tar.gz: 816ec380875e437679a8f82831ace056ea77d8dddd7c72e26ae255065db9e24b51ea9d4880a7e1101c33d9219dcf66f813d67714262621395554e4b46dc95bb8
data/Gemfile.lock CHANGED
@@ -1,12 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- encryptbot (0.1.7)
4
+ encryptbot (0.1.8)
5
5
  acme-client
6
6
  aws-sdk-route53
7
7
  faraday
8
8
  platform-api
9
- slack-notifier
10
9
 
11
10
  GEM
12
11
  remote: https://rubygems.org/
@@ -14,21 +13,24 @@ GEM
14
13
  acme-client (2.0.6)
15
14
  faraday (>= 0.17, < 2.0.0)
16
15
  aws-eventstream (1.0.3)
17
- aws-partitions (1.281.0)
18
- aws-sdk-core (3.90.1)
16
+ aws-partitions (1.292.0)
17
+ aws-sdk-core (3.92.0)
19
18
  aws-eventstream (~> 1.0, >= 1.0.2)
20
19
  aws-partitions (~> 1, >= 1.239.0)
21
20
  aws-sigv4 (~> 1.1)
22
21
  jmespath (~> 1.0)
23
- aws-sdk-route53 (1.30.0)
22
+ aws-sdk-route53 (1.32.0)
24
23
  aws-sdk-core (~> 3, >= 3.71.0)
25
24
  aws-sigv4 (~> 1.1)
26
25
  aws-sigv4 (1.1.1)
27
26
  aws-eventstream (~> 1.0, >= 1.0.2)
28
27
  erubis (2.7.0)
29
- excon (0.72.0)
30
- faraday (1.0.0)
28
+ excon (0.79.0)
29
+ faraday (1.3.0)
30
+ faraday-net_http (~> 1.0)
31
31
  multipart-post (>= 1.2, < 3)
32
+ ruby2_keywords
33
+ faraday-net_http (1.0.1)
32
34
  heroics (0.0.25)
33
35
  erubis (~> 2.0)
34
36
  excon
@@ -36,13 +38,13 @@ GEM
36
38
  multi_json (>= 1.9.2)
37
39
  jmespath (1.4.0)
38
40
  moneta (1.0.0)
39
- multi_json (1.14.1)
41
+ multi_json (1.15.0)
40
42
  multipart-post (2.1.1)
41
43
  platform-api (2.2.0)
42
44
  heroics (~> 0.0.25)
43
45
  moneta (~> 1.0.0)
44
46
  rake (13.0.1)
45
- slack-notifier (2.3.2)
47
+ ruby2_keywords (0.0.4)
46
48
 
47
49
  PLATFORMS
48
50
  ruby
data/README.md CHANGED
@@ -5,9 +5,8 @@ Encryptbot creates and renews your Let's Encrypt SSL certificate on Heroku allow
5
5
  The gem will:
6
6
 
7
7
  - Create Let's Encrypt
8
- - Add Let's Encrypt DNS Challenge TXT records to your DNS provider (Cloudflare and Dyn supported)
8
+ - Add Let's Encrypt DNS Challenge TXT records to DNS provider Route 53
9
9
  - Add certificate to your Heroku SNI endpoint
10
- - Send Slack notifications if the process fails.
11
10
 
12
11
  ## Installation
13
12
 
@@ -34,23 +33,12 @@ Add an initializer file to your rails application and all applicable config sett
34
33
  Encryptbot.configure do |config|
35
34
  config.heroku_app = "heroku_app_name"
36
35
  config.heroku_token = "heroku_api_token"
37
- config.cloudflare_api_key = "cloudflare_api_key"
38
- config.cloudflare_email = "cloudflare_account_email"
39
36
  config.acme_email = "letsencrypt_account_email"
40
- config.dyn_customer_name = "dyn_customer_name"
41
- config.dyn_username = "dyn_username"
42
- config.dyn_password = "dyn_password"
43
- config.slack_webhook = "slack_webhook_url"
44
- config.slack_bot_username = "name_for_slack_bot"
45
37
  config.route53_hosted_zone_id = "Z123456"
46
38
  config.route53_acme_record_name = "_acme-challenge.acme.domain.com"
47
39
  config.route53_access_key_id = "aws_api_key"
48
40
  config.route53_secret_access_key = "aws_api_secret"
49
- config.domains = [
50
- {domain: "*.domain1.com", service: "cloudflare"},
51
- {domain: "*.domain2.com", service: "dyn"},
52
- {domain: "domain3.com", service: "cloudflare"},
53
- ]
41
+ config.domains = ["*.domain1.com", "*.domain2.com"]
54
42
  end
55
43
  ```
56
44
 
data/encryptbot.gemspec CHANGED
@@ -24,7 +24,6 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency "acme-client"
25
25
  spec.add_dependency "platform-api"
26
26
  spec.add_dependency "faraday"
27
- spec.add_dependency "slack-notifier"
28
27
  spec.add_dependency "aws-sdk-route53"
29
28
  spec.add_development_dependency "bundler", "~> 1.16"
30
29
  spec.add_development_dependency "rake", ">= 12.3.3"
data/lib/encryptbot.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  require "encryptbot/configuration"
2
2
  require "encryptbot/cert"
3
3
  require "encryptbot/version"
4
- require "encryptbot/services/cloudflare"
5
- require "encryptbot/services/dyn"
6
4
  require "encryptbot/services/route53"
7
5
 
8
6
  if defined?(Rails)
@@ -2,17 +2,15 @@ require "platform-api"
2
2
  require "acme-client"
3
3
  require "encryptbot/heroku"
4
4
  require "encryptbot/exceptions"
5
- require "encryptbot/slacker"
6
5
  require "resolv"
7
6
 
8
7
  module Encryptbot
9
8
  class Cert
10
9
 
11
- attr_reader :domain_list, :domain_names, :account_email, :test_mode
10
+ attr_reader :domains, :account_email, :test_mode
12
11
 
13
12
  def initialize
14
- @domain_list = Encryptbot.configuration.domains
15
- @domain_names = @domain_list.map{|d| d[:domain] }
13
+ @domains = Encryptbot.configuration.domains
16
14
  @account_email = Encryptbot.configuration.acme_email
17
15
  @test_mode = Encryptbot.configuration.test_mode
18
16
  end
@@ -35,27 +33,22 @@ module Encryptbot
35
33
  )
36
34
 
37
35
  # create order
38
- order = client.new_order(identifiers: @domain_names)
36
+ order = client.new_order(identifiers: @domains)
39
37
 
38
+ puts "Start Authorization"
40
39
  # authorization of domains
41
40
  order.authorizations.each do |authorization|
42
41
  dns_challenge = authorization.dns
43
42
  domain = authorization.domain
43
+ puts "Start Authorization of #{domain}"
44
44
  dns_entry = {
45
45
  name: dns_challenge.record_name,
46
46
  type: dns_challenge.record_type,
47
47
  content: dns_challenge.record_content
48
48
  }
49
- case @domain_list.detect{|t| t[:domain].gsub("*.", "") == domain }[:service]
50
- when "route53"
51
- Encryptbot::Services::Route53.new(domain, dns_entry).add_challenge
52
- when "cloudflare"
53
- Encryptbot::Services::Cloudflare.new(domain, dns_entry).add_challenge
54
- when "dyn"
55
- Encryptbot::Services::Dyn.new(domain, dns_entry).add_challenge
56
- else
57
- raise Encryptbot::Error::UnknownServiceError, "#{domain} service unknown"
58
- end
49
+
50
+ Encryptbot::Services::Route53.new(domain, dns_entry).add_challenge
51
+
59
52
  # check if the DNS service has updated
60
53
  sleep(8)
61
54
 
@@ -73,6 +66,7 @@ module Encryptbot
73
66
  sleep(2)
74
67
  dns_challenge.reload
75
68
  end
69
+ puts "Completed authorization of #{domain}. Status: #{dns_challenge.status}"
76
70
 
77
71
  end # end auth loop
78
72
 
@@ -81,14 +75,17 @@ module Encryptbot
81
75
  end
82
76
 
83
77
  # Generate certificate
78
+ puts "Generate Certificate"
84
79
  csr = Acme::Client::CertificateRequest.new(names: @domain_names)
85
80
  order.finalize(csr: csr)
86
81
  sleep(1) while order.status == "processing"
87
82
 
88
83
  # add certificate to heroku
84
+ puts "Adding Certificate to heroku"
89
85
  certificate = order.certificate
90
86
  private_key = csr.private_key.to_pem
91
87
  Encryptbot::Heroku.new.add_certificate(order.certificate, private_key)
88
+ puts "Completed"
92
89
  end
93
90
 
94
91
  # Check if TXT value has been set correctly
@@ -104,4 +101,4 @@ module Encryptbot
104
101
 
105
102
  end
106
103
 
107
- end
104
+ end
@@ -1,36 +1,25 @@
1
1
  module Encryptbot
2
2
  class Configuration
3
3
  attr_accessor :heroku_app, :heroku_token,
4
- :cloudflare_api_key, :cloudflare_email,
5
- :dyn_customer_name, :dyn_username, :dyn_password,
6
4
  :route53_hosted_zone_id, :route53_acme_record_name,
7
5
  :route53_access_key_id, :route53_secret_access_key,
8
- :acme_email, :domains, :test_mode,
9
- :slack_webhook, :slack_bot_username
6
+ :acme_email, :domains, :test_mode
10
7
 
11
8
  def initialize
12
9
  @heroku_app = nil
13
10
  @heroku_token = nil
14
- @cloudflare_api_key = nil
15
- @cloudflare_email = nil
16
- @dyn_customer_name = nil
17
- @dyn_username = nil
18
- @dyn_password = nil
19
11
  @route53_hosted_zone_id = nil
20
12
  @route53_acme_record_name = nil
21
13
  @route53_access_key_id = nil
22
14
  @route53_secret_access_key = nil
23
15
  @acme_email = nil
24
- @slack_webhook = nil
25
- @slack_bot_username = "encryptbot"
26
16
  @test_mode = false # use lets encrypt staging
27
- @domains = [] #[{domain: "*.domain.com", service: "cloudflare"}, {domain: "*.domain.com", service: "dyn"}]
17
+ @domains = [] #["*.domain1.com","*.domain2.com"]
28
18
  end
29
19
 
30
20
  def valid?
31
- heroku_app && heroku_token && acme_email && domains.any? &&
32
- (cloudflare_api_key || dyn_customer_name || route53_access_key_id)
21
+ heroku_app && heroku_token && acme_email && domains.any? && route53_access_key_id
33
22
  end
34
23
 
35
24
  end
36
- end
25
+ end
@@ -1,12 +1,9 @@
1
- require "encryptbot/slacker"
2
-
3
1
  module Encryptbot
4
2
  module Error
5
3
 
6
4
  class EncryptbotError < StandardError
7
5
 
8
6
  def initialize(msg = "")
9
- Encryptbot::Slacker.post_message("Unable to autorenew SSL certificate. #{self.class.name} #{msg}")
10
7
  super(msg)
11
8
  end
12
9
 
@@ -27,4 +24,4 @@ module Encryptbot
27
24
  # Exception raised as order was failed - this happens when the DNS Challenge failed
28
25
  class InvalidOrderError < EncryptbotError; end
29
26
  end
30
- end
27
+ end
@@ -1,3 +1,3 @@
1
1
  module Encryptbot
2
- VERSION = "0.1.7"
2
+ VERSION = "0.1.8"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: encryptbot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - danlewis
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-08 00:00:00.000000000 Z
11
+ date: 2021-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: acme-client
@@ -52,20 +52,6 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: slack-notifier
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: aws-sdk-route53
71
57
  requirement: !ruby/object:Gem::Requirement
@@ -131,17 +117,14 @@ files:
131
117
  - lib/encryptbot/exceptions.rb
132
118
  - lib/encryptbot/heroku.rb
133
119
  - lib/encryptbot/railtie.rb
134
- - lib/encryptbot/services/cloudflare.rb
135
- - lib/encryptbot/services/dyn.rb
136
120
  - lib/encryptbot/services/route53.rb
137
- - lib/encryptbot/slacker.rb
138
121
  - lib/encryptbot/version.rb
139
122
  - lib/tasks/encryptbot.rake
140
123
  homepage: https://github.com/danlewis/encryptbot
141
124
  licenses:
142
125
  - MIT
143
126
  metadata: {}
144
- post_install_message:
127
+ post_install_message:
145
128
  rdoc_options: []
146
129
  require_paths:
147
130
  - lib
@@ -157,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
140
  version: '0'
158
141
  requirements: []
159
142
  rubygems_version: 3.0.3
160
- signing_key:
143
+ signing_key:
161
144
  specification_version: 4
162
145
  summary: Manage Let's Encrypt wildcard certificates on Heroku
163
146
  test_files: []
@@ -1,111 +0,0 @@
1
- # a=Encryptbot::Services::Cloudflare.new("*.domain.com", {type: "TXT", name: "_acme-challenge.adventist.place", content: "test-3"});a.add_challenge
2
- require "faraday"
3
- require "json"
4
-
5
- module Encryptbot
6
- module Services
7
- class Cloudflare
8
-
9
- attr_accessor :domain, :api_key, :api_email, :zone_id, :dns_entry, :dns_record_id, :dns_record
10
-
11
- def initialize(domain, dns_entry)
12
- @domain = domain.to_s.gsub("*.", "") # cleanup wildcard by removing *. infront
13
- @api_key = Encryptbot.configuration.cloudflare_api_key
14
- @api_email = Encryptbot.configuration.cloudflare_email
15
- @dns_entry = dns_entry # {content: "txt-record-content", type: "TXT", name: "_acme-challenge.domain.com"}
16
- @dns_record = "#{dns_entry[:name]}.#{@domain}"
17
- end
18
-
19
- def add_challenge
20
- begin
21
- get_zone_id
22
- setup_dns_record
23
- rescue => e
24
- raise Encryptbot::Error::CloudflareDNSError, e
25
- end
26
- end
27
-
28
- def get_zone_id
29
- response = get("/zones?name=#{@domain}")
30
- if response["result"].any?
31
- @zone_id = response["result"].first["id"]
32
- end
33
- end
34
-
35
- def setup_dns_record
36
- find_dns_record
37
- return false if @zone_id.nil?
38
-
39
- if @dns_record_id
40
- update_dns_record
41
- else
42
- add_dns_record
43
- end
44
- end
45
-
46
- def find_dns_record
47
- response = get("/zones/#{@zone_id}/dns_records?name=#{@dns_record}&type=#{@dns_entry[:type]}")
48
- if response["result"].any?
49
- @dns_record_id = response["result"].first["id"]
50
- end
51
- end
52
-
53
- def add_dns_record
54
- response = post("/zones/#{@zone_id}/dns_records", {
55
- type: @dns_entry[:type],
56
- name: @dns_record,
57
- content: @dns_entry[:content],
58
- ttl: 120
59
- })
60
- response["success"]
61
- end
62
-
63
- def update_dns_record
64
- response = put("/zones/#{@zone_id}/dns_records/#{@dns_record_id}", {
65
- type: @dns_entry[:type],
66
- name: @dns_record,
67
- content: @dns_entry[:content],
68
- ttl: 120
69
- })
70
- response["success"]
71
- end
72
-
73
- private
74
-
75
- def post(endpoint_path, payload)
76
- response = connection.post "https://api.cloudflare.com/client/v4#{endpoint_path}", payload.to_json
77
- format_response(response)
78
- end
79
-
80
- def put(endpoint_path, payload)
81
- response = connection.put "https://api.cloudflare.com/client/v4#{endpoint_path}", payload.to_json
82
- format_response(response)
83
- end
84
-
85
- def get(endpoint_path)
86
- response = connection.get "https://api.cloudflare.com/client/v4#{endpoint_path}"
87
- format_response(response)
88
- end
89
-
90
- def connection
91
- @connection ||= begin
92
- headers = {
93
- "X-Auth-Key" => @api_key,
94
- "X-Auth-Email" => @api_email,
95
- "Content-Type" => "application/json"
96
- }
97
- Faraday.new(url: "https://api.cloudflare.com", headers: headers)
98
- end
99
- end
100
-
101
- def format_response(response)
102
- if response.success?
103
- JSON.parse(response.body)
104
- else
105
- nil
106
- end
107
- end
108
-
109
- end
110
- end
111
- end
@@ -1,145 +0,0 @@
1
- # a=Encryptbot::Services::Dyn.new("*.domain.com", {type: "TXT", name: "_acme-challenge", content: "test-3"});a.add_challenge
2
- require "faraday"
3
- require "json"
4
-
5
- module Encryptbot
6
- module Services
7
- class Dyn
8
-
9
- attr_accessor :domain, :dns_entry, :full_domain_name, :api_token, :customer_name, :username, :password
10
-
11
- def initialize(domain, dns_entry)
12
- @domain = domain.to_s.gsub("*.", "") # cleanup wildcard by removing *. infront
13
- @dns_entry = dns_entry # {content: "txt-record-content", type: "TXT", name: "_acme-challenge.domain.com"}
14
- @full_domain_name = "#{dns_entry[:name]}.#{@domain}"
15
- @api_token = nil
16
- @customer_name = Encryptbot.configuration.dyn_customer_name
17
- @username = Encryptbot.configuration.dyn_username
18
- @password = Encryptbot.configuration.dyn_password
19
- end
20
-
21
- # sign in
22
- # check for txt record, update if already exists, otherwise create new one
23
- # publish changes
24
- # sign out
25
- def add_challenge
26
- begin
27
- sign_in
28
- success = setup_dns_record
29
- sign_out
30
- success
31
- rescue => e
32
- raise Encryptbot::Error::DynDNSError, e
33
- end
34
-
35
- end
36
-
37
- def sign_in
38
- response = post("/REST/Session/", {
39
- customer_name: customer_name,
40
- user_name: username,
41
- password: password
42
- })
43
- if response && response["status"] == "success"
44
- @api_token = response["data"]["token"]
45
- end
46
- if @api_token.nil?
47
- raise Encryptbot::Error::DynDNSError, "Unable to get Dyn API Token"
48
- end
49
- end
50
-
51
- def sign_out
52
- response = delete("/REST/Session/")
53
- end
54
-
55
- def setup_dns_record
56
- txt_endpoint = find_dns_record
57
-
58
- if txt_endpoint
59
- update_dns_record(txt_endpoint)
60
- else
61
- add_dns_record
62
- end
63
- end
64
-
65
- def find_dns_record
66
- response = get("/REST/TXTRecord/#{domain}/#{full_domain_name}/")
67
- if response && response["status"] == "success"
68
- return response["data"][0]
69
- end
70
- nil
71
- end
72
-
73
- def add_dns_record
74
- response = post("/REST/TXTRecord/#{domain}/#{full_domain_name}/", {
75
- rdata: {
76
- txtdata: dns_entry[:content]
77
- },
78
- ttl: "30"
79
- })
80
- if response && response["status"] == "success"
81
- return publish_changes
82
- end
83
- false
84
- end
85
-
86
- def update_dns_record(txt_endpoint)
87
- response = put(txt_endpoint, {
88
- rdata: {
89
- txtdata: dns_entry[:content]
90
- },
91
- ttl: "30"
92
- })
93
- if response && response["status"] == "success"
94
- return publish_changes
95
- end
96
- false
97
- end
98
-
99
- def publish_changes
100
- response = put("/REST/Zone/#{domain}/", {publish: true})
101
- response && response["status"] == "success"
102
- end
103
-
104
- private
105
-
106
- def post(endpoint_path, payload)
107
- response = connection.post "https://api2.dynect.net#{endpoint_path}", payload.to_json
108
- format_response(response)
109
- end
110
-
111
- def put(endpoint_path, payload)
112
- response = connection.put "https://api2.dynect.net#{endpoint_path}", payload.to_json
113
- format_response(response)
114
- end
115
-
116
- def delete(endpoint_path)
117
- response = connection.delete "https://api2.dynect.net#{endpoint_path}"
118
- format_response(response)
119
- end
120
-
121
- def get(endpoint_path)
122
- response = connection.get "https://api2.dynect.net#{endpoint_path}"
123
- format_response(response)
124
- end
125
-
126
- # Api token if set for requests after sign in completed
127
- def connection
128
- headers = {
129
- "Auth-Token" => api_token.to_s,
130
- "Content-Type" => "application/json"
131
- }
132
- Faraday.new(url: "https://api2.dynect.net", headers: headers)
133
- end
134
-
135
- def format_response(response)
136
- if response.success?
137
- JSON.parse(response.body)
138
- else
139
- nil
140
- end
141
- end
142
-
143
- end
144
- end
145
- end
@@ -1,16 +0,0 @@
1
- require "slack-notifier"
2
-
3
- module Encryptbot
4
- class Slacker
5
-
6
- def self.post_message(message)
7
- unless Encryptbot.configuration.slack_webhook.nil?
8
- notifier.ping message
9
- end
10
- end
11
-
12
- def self.notifier
13
- @notifier ||= Slack::Notifier.new Encryptbot.configuration.slack_webhook, username: Encryptbot.configuration.slack_bot_username
14
- end
15
- end
16
- end