rails-letsencrypt 0.3.0 → 0.4.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
  SHA1:
3
- metadata.gz: 4f2c887b3a1d6aa85e7e816b9e38825f3731b7f6
4
- data.tar.gz: 4e8c531be29e92c9bde71803ccca868a6ac649a3
3
+ metadata.gz: d6408387e993ede69529209f7e73797ba2b5d99a
4
+ data.tar.gz: 65192f2f42d4de422b3a2e17001e588512353397
5
5
  SHA512:
6
- metadata.gz: 5149e9b89f63bf63933f2e68a1f31029ef2b9b393a02dd232d91d4a1dce95ac1b4dd10ee9155b287a4628de5868b2abddcfde408ddfd8150ba3bc69e3e843dd4
7
- data.tar.gz: cde51125e065b0042cbf8c4b5c80f494309f574ee696adedfe53a47eb89c45d5633c3950106708c55eb43ef21bbc07f6ecaae2b94092f00098f712787150b1fb
6
+ metadata.gz: '09a814690b7c1d5f5dedd65a873ad9f5db9141f3d37f778fbed0498cee7652538231d337f8cb1158d40804149fac0abd0eec508fb074488327760656a7148012'
7
+ data.tar.gz: e051f1c768b3eb6b7a1baa3eb1bbfa24c0ba1cd8fa20ce10f65637f38e8b550586c5df9eaace83c589f3cba35526a7e92324da61741ec37e19af89526eb0cb8e
data/README.md CHANGED
@@ -11,11 +11,19 @@ gem 'rails-letsencrypt'
11
11
  ```
12
12
 
13
13
  Run install migrations
14
+
14
15
  ```bash
15
- rake letsencrypt:install:migrations
16
+ rails generate lets_encrypt:install
16
17
  rake db:migrate
17
18
  ```
18
19
 
20
+ Setup private key for Let's Encrypt API
21
+
22
+ ```bash
23
+ rails generate lets_encrypt:register
24
+ ```
25
+
26
+
19
27
  Add `acme-challenge` mounts in `config/routes.rb`
20
28
  ```ruby
21
29
  mount LetsEncrypt::Engine => '/.well-known'
@@ -25,6 +33,22 @@ mount LetsEncrypt::Engine => '/.well-known'
25
33
 
26
34
  The SSL certificate setup is depend on web server, this gem can work with `ngx_mruby` or `kong`.
27
35
 
36
+ ### Tasks
37
+
38
+ To renew certificate, you can can run `renew` task to renew coming expires certificates.
39
+
40
+ ```bash
41
+ rake letsencrypt:renew
42
+ ```
43
+
44
+ ### Jobs
45
+
46
+ If you are using Sidekiq or others, you can enqueue renew task daily.
47
+
48
+ ```
49
+ LetsEncrypt::RenewCertificate.queue(:default)
50
+ ```
51
+
28
52
  ### ngx_mruby
29
53
 
30
54
  The setup is following this [Article](http://hb.matsumoto-r.jp/entry/2017/03/23/173236)
data/Rakefile CHANGED
@@ -8,14 +8,10 @@ require 'rdoc/task'
8
8
 
9
9
  RDoc::Task.new(:rdoc) do |rdoc|
10
10
  rdoc.rdoc_dir = 'rdoc'
11
- rdoc.title = 'LetsEncrypt'
11
+ rdoc.title = 'rails-letsencrypt'
12
12
  rdoc.options << '--line-numbers'
13
13
  rdoc.rdoc_files.include('README.md')
14
14
  rdoc.rdoc_files.include('lib/**/*.rb')
15
15
  end
16
16
 
17
- # TODO: Add rails 5 support tasks => load 'rails/tasks/statistics.rake'
18
-
19
17
  require 'bundler/gem_tasks'
20
-
21
- task default: :install
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module LetsEncrypt
4
+ # :nodoc:
2
5
  class ApplicationController < ActionController::Base
3
6
  protect_from_forgery with: :exception
4
7
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_dependency 'lets_encrypt/application_controller'
2
4
 
3
5
  module LetsEncrypt
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LetsEncrypt
4
+ # :nodoc:
5
+ class RenewCertificatesJob < ApplicationJob
6
+ queue_as :default
7
+
8
+ def perform
9
+ LetsEncrypt::Certificate.renewable.each do |certificate|
10
+ next if certificate.renew
11
+ certificate.update(renew_after: 1.day.from_now)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module LetsEncrypt
2
4
  # :nodoc:
3
5
  class Certificate < ActiveRecord::Base
@@ -6,17 +8,39 @@ module LetsEncrypt
6
8
 
7
9
  validates :domain, presence: true, uniqueness: true
8
10
 
11
+ scope :active, -> { where('certificate IS NOT NULL AND expires_at > ?', Time.zone.now) }
12
+ scope :renewable, -> { where('renew_after IS NULL OR renew_after <= ?', Time.zone.now) }
13
+ scope :expired, -> { where('expires_at <= ?', Time.zone.now) }
14
+
9
15
  before_create -> { self.key = OpenSSL::PKey::RSA.new(4096).to_s }
10
16
  after_save -> { save_to_redis }, if: -> { LetsEncrypt.config.use_redis? }
11
17
 
18
+ def active?
19
+ certificate.present?
20
+ end
21
+
22
+ def expired?
23
+ Time.zone.now >= expires_at
24
+ end
25
+
12
26
  def get
13
27
  verify && issue
14
28
  end
15
29
 
30
+ alias renew get
31
+
16
32
  def bundle
17
33
  [intermediaries, certificate].join("\n")
18
34
  end
19
35
 
36
+ def certificate_object
37
+ @certificate_object ||= OpenSSL::X509::Certificate.new(certificate)
38
+ end
39
+
40
+ def key_object
41
+ @key_object ||= OpenSSL::PKey::RSA.new(key)
42
+ end
43
+
20
44
  def save_to_redis
21
45
  LetsEncrypt::Redis.save(self)
22
46
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require 'rails/generators/migration'
5
+ require 'rails/generators/active_record'
6
+
7
+ module LetsEncrypt
8
+ module Generators
9
+ # :nodoc:
10
+ class InstallGenerator < ::Rails::Generators::Base
11
+ include ::Rails::Generators::Migration
12
+
13
+ source_root File.expand_path('../templates', __FILE__)
14
+
15
+ def self.next_migration_number(path)
16
+ ActiveRecord::Generators::Base.next_migration_number(path)
17
+ end
18
+
19
+ def copy_migrations
20
+ migration_template 'migration.rb',
21
+ 'db/migrate/create_letsencrypt_certificates.rb'
22
+ end
23
+
24
+ def rails5?
25
+ Rails::VERSION::MAJOR == 5
26
+ end
27
+
28
+ def migration_version
29
+ "[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" if rails5?
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require 'rails/generators/migration'
5
+ require 'rails/generators/active_record'
6
+
7
+ module LetsEncrypt
8
+ module Generators
9
+ # :nodoc:
10
+ class RegisterGenerator < ::Rails::Generators::Base
11
+ def register
12
+ say 'Starting register Let\'s Encrypt account', :green
13
+
14
+ setup_environment
15
+ generate_key
16
+ register_email
17
+ rescue Acme::Client::Error => e
18
+ say(e.message, :red)
19
+ end
20
+
21
+ private
22
+
23
+ def setup_environment
24
+ production = yes?('Do you want to use in production environment? [y/N]:')
25
+ LetsEncrypt.config.use_staging = !production
26
+ end
27
+
28
+ def generate_key
29
+ # rubocop:disable Metric/LineLength
30
+ key_path = ask("Where you to save private key [#{LetsEncrypt.private_key_path}]:", path: true)
31
+ # rubocop:enable Metrics/LineLength
32
+ key_path = LetsEncrypt.private_key_path if key_path.blank?
33
+
34
+ return unless file_collision(key_path)
35
+ FileUtils.rm(key_path)
36
+ LetsEncrypt.config.use_env_key = false
37
+ LetsEncrypt.config.private_key_path = key_path
38
+
39
+ LetsEncrypt.load_private_key
40
+
41
+ # rubocop:disable Metrics/LineLength
42
+ say "Your privated key is saved in #{key_path}, make sure setup configure for your rails.", :yellow
43
+ # rubocop:enable Metrics/LineLength
44
+ end
45
+
46
+ def register_email
47
+ email = ask('What email you want to register:')
48
+ return say('Email is inavlid!', :red) if email.blank?
49
+ LetsEncrypt.register(email)
50
+ say 'Register successed, don\'t forget backup your private key', :green
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nodoc:
4
+ class CreateLetsencryptCertificates < ActiveRecord::Migration<%= migration_version %>
5
+ def change
6
+ create_table :letsencrypt_certificates do |t|
7
+ t.string :domain
8
+ t.text :certificate, limit: 65535
9
+ t.text :intermediaries, limit: 65535
10
+ t.text :key, limit: 65535
11
+ t.datetime :expires_at
12
+ t.datetime :renew_after
13
+ t.string :verification_path
14
+ t.string :verification_string
15
+
16
+ t.index :domain
17
+ t.index :renew_after
18
+ t.timestamps
19
+ end
20
+ end
21
+ end
data/lib/letsencrypt.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'openssl'
2
2
  require 'acme-client'
3
3
  require 'redis'
4
+ require 'letsEncrypt/railtie'
4
5
  require 'letsencrypt/engine'
5
6
  require 'letsencrypt/configuration'
6
7
  require 'letsencrypt/logger_proxy'
@@ -30,7 +31,7 @@ module LetsEncrypt
30
31
  end
31
32
 
32
33
  def endpoint
33
- @endpoint ||= Rails.env.production? ? ENDPOINT : ENDPOINT_STAGING
34
+ @endpoint ||= config.use_staging? ? ENDPOINT_STAGING : ENDPOINT
34
35
  end
35
36
 
36
37
  def register(email)
@@ -42,7 +43,6 @@ module LetsEncrypt
42
43
  end
43
44
 
44
45
  def private_key_path
45
- # TODO: Add options for specify path
46
46
  config.private_key_path || Rails.root.join('config', 'letsencrypt.key')
47
47
  end
48
48
 
@@ -57,8 +57,15 @@ module LetsEncrypt
57
57
  @logger ||= LoggerProxy.new(Rails.logger, tags: ['LetsEncrypt'])
58
58
  end
59
59
 
60
- def config
60
+ def config(&block)
61
61
  @config ||= Configuration.new
62
+ instance_exec(@config, &block) if block_given?
63
+ @config
64
+ end
65
+
66
+ # @api private
67
+ def table_name_prefix
68
+ 'letsencrypt_'
62
69
  end
63
70
  end
64
71
  end
@@ -1,8 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module LetsEncrypt
2
4
  # :nodoc:
3
5
  class Configuration
4
6
  include ActiveSupport::Configurable
5
7
 
8
+ config_accessor :use_staging do
9
+ !Rails.env.production?
10
+ end
6
11
  config_accessor :private_key_path
7
12
  config_accessor :use_env_key do
8
13
  false
@@ -14,5 +19,9 @@ module LetsEncrypt
14
19
  def use_redis?
15
20
  save_to_redis == true
16
21
  end
22
+
23
+ def use_staging?
24
+ use_staging
25
+ end
17
26
  end
18
27
  end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LetsEncrypt
4
+ class Railtie < ::Rails::Railtie
5
+ end
6
+ end
@@ -1,3 +1,3 @@
1
1
  module LetsEncrypt
2
- VERSION = '0.3.0'
2
+ VERSION = '0.4.0'
3
3
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :letsencrypt do
4
+ desc 'Renew the certificates will epxired'
5
+ task renew: :environment do
6
+ count = 0
7
+ failed = 0
8
+ LetsEncrypt::Certificate.renewable do |certificate|
9
+ count += 1
10
+ next if certificate.renew
11
+ failed += 1
12
+ log "Could not renew domain: #{certificate.domain}"
13
+ end
14
+
15
+ puts "Total #{count} domains should renew, and #{failed} domains cannot be renewed."
16
+ end
17
+ end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-letsencrypt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - 蒼時弦也
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-10 00:00:00.000000000 Z
11
+ date: 2017-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.0'
19
+ version: '4.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '4.0'
26
+ version: '4.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: acme-client
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -79,20 +79,23 @@ files:
79
79
  - app/controllers/lets_encrypt/application_controller.rb
80
80
  - app/controllers/lets_encrypt/verifications_controller.rb
81
81
  - app/jobs/lets_encrypt/application_job.rb
82
+ - app/jobs/lets_encrypt/renew_certificates_job.rb
82
83
  - app/models/concerns/lets_encrypt/certificate_issuable.rb
83
84
  - app/models/concerns/lets_encrypt/certificate_verifiable.rb
84
- - app/models/lets_encrypt/application_record.rb
85
85
  - app/models/lets_encrypt/certificate.rb
86
86
  - config/routes.rb
87
- - db/migrate/20170510075353_create_lets_encrypt_certificates.rb
87
+ - lib/generators/lets_encrypt/install_generator.rb
88
+ - lib/generators/lets_encrypt/register_generator.rb
89
+ - lib/generators/lets_encrypt/templates/migration.rb
88
90
  - lib/letsencrypt.rb
89
91
  - lib/letsencrypt/configuration.rb
90
92
  - lib/letsencrypt/engine.rb
91
93
  - lib/letsencrypt/logger_proxy.rb
94
+ - lib/letsencrypt/railtie.rb
92
95
  - lib/letsencrypt/redis.rb
93
96
  - lib/letsencrypt/version.rb
94
97
  - lib/rails-letsencrypt.rb
95
- - lib/tasks/lets_encrypt_tasks.rake
98
+ - lib/tasks/letsencrypt_tasks.rake
96
99
  homepage: https://github.com/elct9620/rails-letsencrypt
97
100
  licenses:
98
101
  - MIT
@@ -1,5 +0,0 @@
1
- module LetsEncrypt
2
- class ApplicationRecord < ActiveRecord::Base
3
- self.abstract_class = true
4
- end
5
- end
@@ -1,17 +0,0 @@
1
- class CreateLetsEncryptCertificates < ActiveRecord::Migration
2
- def change
3
- create_table :lets_encrypt_certificates do |t|
4
- t.string :domain
5
- t.text :certificate, limit: 65535
6
- t.text :intermediaries, limit: 65535
7
- t.text :key, limit: 65535
8
- t.datetime :expires_at
9
- t.datetime :renew_after
10
- t.string :verification_path
11
- t.string :verification_string
12
-
13
- t.index :domain
14
- t.timestamps
15
- end
16
- end
17
- end
@@ -1,4 +0,0 @@
1
- # desc "Explaining what the task does"
2
- # task :lets_encrypt do
3
- # # Task goes here
4
- # end