rails-letsencrypt 0.10.1 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9fcc6f31e49bb320d23f8dc89e768de5c88edc1cfcb65540d3ff294337908aa6
4
- data.tar.gz: 88ebaa8808ab982309be5d3a903b39ba731d68a2f0f7d33fee336316ac0b7ade
3
+ metadata.gz: 1831382c1a2c8970e928bb47c8760bdf4e58b11c6d0944465cf781be3d91f8c5
4
+ data.tar.gz: 77a91de46a8a4b0b1b8f49789b1eb390bafb1245347f30a6598f0176398da64d
5
5
  SHA512:
6
- metadata.gz: 37ba93909e4ec5d883c4d84a41a8b64060079b87c491765736c0d325a8d9df7759f5d9fc21945d3769ccd12388a154eb56604c4dc06c89a01cdc3ebd68189ed0
7
- data.tar.gz: 819e3498c99f2037ab520114bc2e1bfa2f6bbce50d05a948dfa3ac1b43fc9cab0630bca1b6d1df294bc89ac4f43b1df18ab417a286f38dec60f2caa5ae66649f
6
+ metadata.gz: bb4e008a900c46946cbe3a2077deb110c13115c0ba1b64246e376d63f54b3913f81bda6fec525ad031c78be67e6bfb58a47d25153ea3b5695a6a19f1ee52fb22
7
+ data.tar.gz: 34740983c6aa421bf5bf7bdc703ddfc77ff5b4ceba1277ef3c9568d11dca3049a278e0d5204d4b34049d8d35d216bd7a6a05d19506ff257328dff9276359ea72
data/README.md CHANGED
@@ -1,11 +1,11 @@
1
- # LetsEncrypt [![Gem Version](https://badge.fury.io/rb/rails-letsencrypt.svg)](https://badge.fury.io/rb/rails-letsencrypt) [![Build Status](https://travis-ci.org/elct9620/rails-letsencrypt.svg?branch=master)](https://travis-ci.org/elct9620/rails-letsencrypt) [![Coverage Status](https://coveralls.io/repos/github/elct9620/rails-letsencrypt/badge.svg?branch=master)](https://coveralls.io/github/elct9620/rails-letsencrypt?branch=master) [![Code Climate](https://codeclimate.com/github/elct9620/rails-letsencrypt/badges/gpa.svg)](https://codeclimate.com/github/elct9620/rails-letsencrypt)
1
+ # LetsEncrypt [![Gem Version](https://badge.fury.io/rb/rails-letsencrypt.svg)](https://badge.fury.io/rb/rails-letsencrypt) [![Code Climate](https://codeclimate.com/github/elct9620/rails-letsencrypt/badges/gpa.svg)](https://codeclimate.com/github/elct9620/rails-letsencrypt)
2
2
 
3
3
  Provide manageable Let's Encrypt Certificate for Rails.
4
4
 
5
5
  ## Requirement
6
6
 
7
- * Rails 5+
8
- * Ruby 2.5+
7
+ * Rails 6.1+
8
+ * Ruby 2.7+
9
9
 
10
10
  ## Installation
11
11
 
@@ -22,7 +22,7 @@ rails generate lets_encrypt:install
22
22
  rake db:migrate
23
23
  ```
24
24
 
25
- Setup private key for Let's Encrypt API
25
+ Setup private key for Let's Encrypt API, and create an account at letsencrypt.org associated with that key
26
26
 
27
27
  ```bash
28
28
  rails generate lets_encrypt:register
@@ -140,6 +140,16 @@ If you are using Sidekiq or others, you can enqueue renew task daily.
140
140
  LetsEncrypt::RenewCertificatesJob.perform_later
141
141
  ```
142
142
 
143
+ ### Subscribe
144
+
145
+ When the certificate is trying to issue a new one, you can subscribe it for logging or error handling.
146
+
147
+ ```ruby
148
+ ActiveSupport::Notifications.subscribe('letsencrypt.issue') do |name, start, finish, id, payload|
149
+ Rails.logger.info("Certificate for #{payload[:domain]} is issued")
150
+ end
151
+ ```
152
+
143
153
  ### ngx_mruby
144
154
 
145
155
  The setup is following this [Article](http://hb.matsumoto-r.jp/entry/2017/03/23/173236)
@@ -7,7 +7,8 @@ module LetsEncrypt
7
7
  class VerificationsController < ApplicationController
8
8
  def show
9
9
  return render_verification_string if certificate.present?
10
- render plain: 'Verification not found', status: 404
10
+
11
+ render plain: 'Verification not found', status: :not_found
11
12
  end
12
13
 
13
14
  protected
@@ -8,6 +8,7 @@ module LetsEncrypt
8
8
  def perform
9
9
  LetsEncrypt.certificate_model.renewable.each do |certificate|
10
10
  next if certificate.renew
11
+
11
12
  certificate.update(renew_after: 1.day.from_now)
12
13
  end
13
14
  end
@@ -9,9 +9,7 @@ module LetsEncrypt
9
9
  def issue
10
10
  logger.info "Getting certificate for #{domain}"
11
11
  create_certificate
12
- # rubocop:disable Metrics/LineLength
13
12
  logger.info "Certificate issued for #{domain} (expires on #{expires_at}, will renew after #{renew_after})"
14
- # rubocop:enable Metrics/LineLength
15
13
  true
16
14
  end
17
15
 
@@ -30,12 +28,16 @@ module LetsEncrypt
30
28
  order.finalize(csr: csr)
31
29
  sleep 1 while order.status == 'processing'
32
30
  fullchain = order.certificate.split("\n\n")
31
+ assign_new_certificate(fullchain)
32
+ save!
33
+ end
34
+
35
+ def assign_new_certificate(fullchain)
33
36
  cert = OpenSSL::X509::Certificate.new(fullchain.shift)
34
37
  self.certificate = cert.to_pem
35
38
  self.intermediaries = fullchain.join("\n\n")
36
39
  self.expires_at = cert.not_after
37
40
  self.renew_after = (expires_at - 1.month) + rand(10).days
38
- save!
39
41
  end
40
42
  end
41
43
  end
@@ -52,16 +52,16 @@ module LetsEncrypt
52
52
  true
53
53
  end
54
54
 
55
- def retry_on_verify_error(e)
55
+ def retry_on_verify_error(error)
56
56
  @retries ||= 0
57
- if e.is_a?(Acme::Client::Error::BadNonce) && @retries < 5
57
+ if error.is_a?(Acme::Client::Error::BadNonce) && @retries < 5
58
58
  @retries += 1
59
59
  logger.info "#{domain}: Bad nounce encountered. Retrying (#{@retries} of 5 attempts)"
60
60
  sleep 1
61
61
  verify
62
62
  else
63
63
  logger.info "#{domain}: Error: #{e.class} (#{e.message})"
64
- return false
64
+ false
65
65
  end
66
66
  end
67
67
  end
@@ -22,7 +22,7 @@ module LetsEncrypt
22
22
  # index_letsencrypt_certificates_on_domain (domain)
23
23
  # index_letsencrypt_certificates_on_renew_after (renew_after)
24
24
  #
25
- class Certificate < ActiveRecord::Base
25
+ class Certificate < ApplicationRecord
26
26
  include CertificateVerifiable
27
27
  include CertificateIssuable
28
28
 
@@ -33,8 +33,8 @@ module LetsEncrypt
33
33
  scope :expired, -> { where('expires_at <= ?', Time.zone.now) }
34
34
 
35
35
  before_create -> { self.key = OpenSSL::PKey::RSA.new(4096).to_s }
36
- after_save -> { save_to_redis }, if: -> { LetsEncrypt.config.use_redis? && active? }
37
36
  after_destroy -> { delete_from_redis }, if: -> { LetsEncrypt.config.use_redis? && active? }
37
+ after_save -> { save_to_redis }, if: -> { LetsEncrypt.config.use_redis? && active? }
38
38
 
39
39
  # Returns false if certificate is not issued.
40
40
  #
@@ -51,7 +51,9 @@ module LetsEncrypt
51
51
 
52
52
  # Returns true if success get a new certificate
53
53
  def get
54
- verify && issue
54
+ ActiveSupport::Notifications.instrument('letsencrypt.issue', domain: domain) do
55
+ verify && issue
56
+ end
55
57
  end
56
58
 
57
59
  alias renew get
@@ -10,7 +10,7 @@ module LetsEncrypt
10
10
  class InstallGenerator < ::Rails::Generators::Base
11
11
  include ::Rails::Generators::Migration
12
12
 
13
- source_root File.expand_path('../templates', __FILE__)
13
+ source_root File.expand_path('templates', __dir__)
14
14
 
15
15
  def self.next_migration_number(path)
16
16
  ActiveRecord::Generators::Base.next_migration_number(path)
@@ -26,26 +26,24 @@ module LetsEncrypt
26
26
  end
27
27
 
28
28
  def generate_key
29
- # rubocop:disable Metrics/LineLength
30
29
  key_path = ask("Where you to save private key [#{LetsEncrypt.private_key_path}]:", path: true)
31
- # rubocop:enable Metrics/LineLength
32
30
  key_path = LetsEncrypt.private_key_path if key_path.blank?
33
31
 
34
32
  return unless file_collision(key_path)
35
- FileUtils.rm(key_path) if File.exist?(key_path)
33
+
34
+ FileUtils.rm_f(key_path)
36
35
  LetsEncrypt.config.use_env_key = false
37
36
  LetsEncrypt.config.private_key_path = key_path
38
37
 
39
38
  LetsEncrypt.load_private_key
40
39
 
41
- # rubocop:disable Metrics/LineLength
42
40
  say "Your privated key is saved in #{key_path}, make sure setup configure for your rails.", :yellow
43
- # rubocop:enable Metrics/LineLength
44
41
  end
45
42
 
46
43
  def register_email
47
44
  email = ask('What email you want to register:')
48
45
  return say('Email is inavlid!', :red) if email.blank?
46
+
49
47
  LetsEncrypt.register(email)
50
48
  say 'Register successed, don\'t forget backup your private key', :green
51
49
  end
@@ -15,10 +15,10 @@ module LetsEncrypt
15
15
  @tags = @tags.uniq
16
16
  end
17
17
 
18
- def tag(logger)
18
+ def tag(logger, &block)
19
19
  if logger.respond_to?(:tagged)
20
20
  current_tags = tags - logger.formatter.current_tags
21
- logger.tagged(*current_tags) { yield }
21
+ logger.tagged(*current_tags, &block)
22
22
  else
23
23
  yield
24
24
  end
@@ -11,6 +11,7 @@ module LetsEncrypt
11
11
  # Save certificate into redis.
12
12
  def save(cert)
13
13
  return unless cert.key.present? && cert.bundle.present?
14
+
14
15
  LetsEncrypt.logger.info "Save #{cert.domain}'s certificate (bundle) to redis"
15
16
  connection.set "#{cert.domain}.key", cert.key
16
17
  connection.set "#{cert.domain}.crt", cert.bundle
@@ -19,6 +20,7 @@ module LetsEncrypt
19
20
  # Delete certificate from redis.
20
21
  def delete(cert)
21
22
  return unless cert.key.present? && cert.certificate.present?
23
+
22
24
  LetsEncrypt.logger.info "Delete #{cert.domain}'s certificate from redis"
23
25
  connection.del "#{cert.domain}.key"
24
26
  connection.del "#{cert.domain}.crt"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LetsEncrypt
4
- VERSION = '0.10.1'
4
+ VERSION = '0.11.0'
5
5
  end
data/lib/letsencrypt.rb CHANGED
@@ -32,14 +32,15 @@ module LetsEncrypt
32
32
  end
33
33
 
34
34
  def load_private_key
35
- return ENV['LETSENCRYPT_PRIVATE_KEY'] if config.use_env_key
35
+ return ENV.fetch('LETSENCRYPT_PRIVATE_KEY', nil) if config.use_env_key
36
36
  return File.open(private_key_path) if File.exist?(private_key_path)
37
+
37
38
  generate_private_key
38
39
  end
39
40
 
40
41
  # Get current using Let's Encrypt endpoint
41
42
  def directory
42
- @endpoint ||= config.use_staging? ? ENDPOINT_STAGING : ENDPOINT
43
+ @directory ||= config.use_staging? ? ENDPOINT_STAGING : ENDPOINT
43
44
  end
44
45
 
45
46
  # Register a Let's Encrypt account
@@ -56,12 +57,12 @@ module LetsEncrypt
56
57
  end
57
58
 
58
59
  def private_key_path
59
- config.private_key_path || Rails.root.join('config', 'letsencrypt.key')
60
+ config.private_key_path || Rails.root.join('config/letsencrypt.key')
60
61
  end
61
62
 
62
63
  def generate_private_key
63
64
  key = OpenSSL::PKey::RSA.new(4096)
64
- File.open(private_key_path, 'w') { |f| f.write(key.to_s) }
65
+ File.write(private_key_path, key.to_s)
65
66
  logger.info "Created new private key for Let's Encrypt"
66
67
  key
67
68
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  namespace :letsencrypt do
4
- desc "Renew certificates that already expired or expiring soon"
4
+ desc 'Renew certificates that already expired or expiring soon'
5
5
  task renew: :environment do
6
6
  count = 0
7
7
  failed = 0
metadata CHANGED
@@ -1,121 +1,135 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-letsencrypt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.1
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - 蒼時弦也
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-27 00:00:00.000000000 Z
11
+ date: 2023-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: acme-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.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: 2.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: actionmailer
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - ">="
18
32
  - !ruby/object:Gem::Version
19
- version: '5.0'
33
+ version: '6.1'
20
34
  type: :runtime
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
38
  - - ">="
25
39
  - !ruby/object:Gem::Version
26
- version: '5.0'
40
+ version: '6.1'
27
41
  - !ruby/object:Gem::Dependency
28
- name: acme-client
42
+ name: actionpack
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - "~>"
45
+ - - ">="
32
46
  - !ruby/object:Gem::Version
33
- version: 2.0.0
47
+ version: '6.1'
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - "~>"
52
+ - - ">="
39
53
  - !ruby/object:Gem::Version
40
- version: 2.0.0
54
+ version: '6.1'
41
55
  - !ruby/object:Gem::Dependency
42
- name: redis
56
+ name: actionview
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - ">="
46
60
  - !ruby/object:Gem::Version
47
- version: '0'
61
+ version: '6.1'
48
62
  type: :runtime
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - ">="
53
67
  - !ruby/object:Gem::Version
54
- version: '0'
68
+ version: '6.1'
55
69
  - !ruby/object:Gem::Dependency
56
- name: appraisal
70
+ name: activemodel
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - ">="
60
74
  - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
75
+ version: '6.1'
76
+ type: :runtime
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - ">="
67
81
  - !ruby/object:Gem::Version
68
- version: '0'
82
+ version: '6.1'
69
83
  - !ruby/object:Gem::Dependency
70
- name: rspec-rails
84
+ name: activerecord
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - ">="
74
88
  - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
89
+ version: '6.1'
90
+ type: :runtime
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - ">="
81
95
  - !ruby/object:Gem::Version
82
- version: '0'
96
+ version: '6.1'
83
97
  - !ruby/object:Gem::Dependency
84
- name: simplecov
98
+ name: activesupport
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - "~>"
101
+ - - ">="
88
102
  - !ruby/object:Gem::Version
89
- version: 0.16.1
90
- type: :development
103
+ version: '6.1'
104
+ type: :runtime
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - "~>"
108
+ - - ">="
95
109
  - !ruby/object:Gem::Version
96
- version: 0.16.1
110
+ version: '6.1'
97
111
  - !ruby/object:Gem::Dependency
98
- name: coveralls
112
+ name: railties
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
- - - "~>"
115
+ - - ">="
102
116
  - !ruby/object:Gem::Version
103
- version: 0.8.23
104
- type: :development
117
+ version: '6.1'
118
+ type: :runtime
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
- - - "~>"
122
+ - - ">="
109
123
  - !ruby/object:Gem::Version
110
- version: 0.8.23
124
+ version: '6.1'
111
125
  - !ruby/object:Gem::Dependency
112
- name: codeclimate-test-reporter
126
+ name: redis
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - ">="
116
130
  - !ruby/object:Gem::Version
117
131
  version: '0'
118
- type: :development
132
+ type: :runtime
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
@@ -155,7 +169,8 @@ files:
155
169
  homepage: https://github.com/elct9620/rails-letsencrypt
156
170
  licenses:
157
171
  - MIT
158
- metadata: {}
172
+ metadata:
173
+ rubygems_mfa_required: 'true'
159
174
  post_install_message:
160
175
  rdoc_options: []
161
176
  require_paths:
@@ -164,14 +179,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
164
179
  requirements:
165
180
  - - ">="
166
181
  - !ruby/object:Gem::Version
167
- version: '0'
182
+ version: 2.7.0
168
183
  required_rubygems_version: !ruby/object:Gem::Requirement
169
184
  requirements:
170
185
  - - ">="
171
186
  - !ruby/object:Gem::Version
172
187
  version: '0'
173
188
  requirements: []
174
- rubygems_version: 3.1.6
189
+ rubygems_version: 3.4.10
175
190
  signing_key:
176
191
  specification_version: 4
177
192
  summary: The Let's Encrypt certificate manager for rails