diff --git a/app/mailers/notifications_mailer.rb b/app/mailers/notifications_mailer.rb
index 814d526..31a4677 100644
--- a/app/mailers/notifications_mailer.rb
+++ b/app/mailers/notifications_mailer.rb
@@ -19,4 +19,16 @@ class NotificationsMailer < ApplicationMailer
subject = t(".subject", domain: @check.domain)
mail subject: subject
end
+
+ def ssl_expires_soon
+ @expire_in_days = Integer(@check.domain_expires_at.to_date - Date.today)
+
+ subject = t(".subject", domain: @check.domain, count: @expire_in_days)
+ mail subject: subject
+ end
+
+ def ssl_recurrent_failures
+ subject = t(".subject", domain: @check.domain)
+ mail subject: subject
+ end
end
diff --git a/app/services/notifier/channels/base.rb b/app/services/notifier/channels/base.rb
index b63a52d..a3e9586 100644
--- a/app/services/notifier/channels/base.rb
+++ b/app/services/notifier/channels/base.rb
@@ -11,6 +11,10 @@ module Notifier
domain_notify_expires_soon(notification)
when [:domain, :recurrent_failures]
domain_notify_recurrent_failures(notification)
+ when [:ssl, :expires_soon]
+ ssl_notify_expires_soon(notification)
+ when [:ssl, :recurrent_failures]
+ ssl_notify_recurrent_failures(notification)
else
fail ArgumentError,
"Invalid notification reason `#{reason}` for check kind `#{notification.check.kind}`."
@@ -25,15 +29,16 @@ module Notifier
"#{self.class.name} channel did not implemented method #{__callee__}"
end
- # domain notifications
- def domain_notify_expires_soon(_notification)
- fail NotImplementedError,
- "Channel #{self.class.name} does not implement #{__callee__}"
- end
-
- def domain_notify_recurrent_failures(_notification)
- fail NotImplementedError,
- "Channel #{self.class.name} does not implement #{__callee__}"
+ %i[
+ domain_notify_expires_soon
+ domain_notify_recurrent_failures
+ ssl_notify_expires_soon
+ ssl_notify_recurrent_failures
+ ].each do |method|
+ define_method(method) do
+ fail NotImplementedError,
+ "Channel #{self.class.name} does not implement method #{method}."
+ end
end
# :nocov:
end
diff --git a/app/services/notifier/channels/email.rb b/app/services/notifier/channels/email.rb
index 17bbdab..9243b7d 100644
--- a/app/services/notifier/channels/email.rb
+++ b/app/services/notifier/channels/email.rb
@@ -16,6 +16,14 @@ module Notifier
def domain_notify_recurrent_failures(notification)
NotificationsMailer.with(notification: notification).domain_recurrent_failures.deliver_now
end
+
+ def ssl_notify_expires_soon(notification)
+ NotificationsMailer.with(notification: notification).ssl_expires_soon.deliver_now
+ end
+
+ def ssl_notify_recurrent_failures(notification)
+ NotificationsMailer.with(notification: notification).ssl_recurrent_failures.deliver_now
+ end
end
end
end
diff --git a/app/views/notifications_mailer/ssl_expires_soon.en.html.erb b/app/views/notifications_mailer/ssl_expires_soon.en.html.erb
new file mode 100644
index 0000000..401df10
--- /dev/null
+++ b/app/views/notifications_mailer/ssl_expires_soon.en.html.erb
@@ -0,0 +1,12 @@
+
+ Hi,
+
+
+ the SSL certificate for <%= @check.domain %> will expire
+ <%= format_utc(@check.domain_expires_at) %>.
+
+
+
+<%= render "check_comment_vendor" %>
+
+<%= render "footer_expires_soon", interval: @notification.interval, check: @check %>
diff --git a/app/views/notifications_mailer/ssl_expires_soon.en.text.erb b/app/views/notifications_mailer/ssl_expires_soon.en.text.erb
new file mode 100644
index 0000000..a1d1c56
--- /dev/null
+++ b/app/views/notifications_mailer/ssl_expires_soon.en.text.erb
@@ -0,0 +1,9 @@
+Hi,
+
+the SSL certificate for <%= @check.domain %> will expire <%= format_utc(@check.domain_expires_at) %>.
+
+
+<%= render "check_comment_vendor" %>
+
+
+<%= render "footer_expires_soon", interval: @notification.interval, check: @check %>
diff --git a/app/views/notifications_mailer/ssl_expires_soon.fr.html.erb b/app/views/notifications_mailer/ssl_expires_soon.fr.html.erb
new file mode 100644
index 0000000..dfc1c3f
--- /dev/null
+++ b/app/views/notifications_mailer/ssl_expires_soon.fr.html.erb
@@ -0,0 +1,12 @@
+
+ Salut,
+
+
+ le certificat SSL pour <%= @check.domain %> va expirer le
+ <%= format_utc(@check.domain_expires_at) %>.
+
+
+
+<%= render "check_comment_vendor" %>
+
+<%= render "footer_expires_soon", interval: @notification.interval, check: @check %>
diff --git a/app/views/notifications_mailer/ssl_expires_soon.fr.text.erb b/app/views/notifications_mailer/ssl_expires_soon.fr.text.erb
new file mode 100644
index 0000000..0664fb5
--- /dev/null
+++ b/app/views/notifications_mailer/ssl_expires_soon.fr.text.erb
@@ -0,0 +1,9 @@
+Salut,
+
+le certificat SSL pour <%= @check.domain %> va expirer le <%= format_utc(@check.domain_expires_at) %>.
+
+
+<%= render "check_comment_vendor" %>
+
+
+<%= render "footer_expires_soon", interval: @notification.interval, check: @check %>
diff --git a/app/views/notifications_mailer/ssl_recurrent_failures.en.html.erb b/app/views/notifications_mailer/ssl_recurrent_failures.en.html.erb
new file mode 100644
index 0000000..602c32d
--- /dev/null
+++ b/app/views/notifications_mailer/ssl_recurrent_failures.en.html.erb
@@ -0,0 +1,31 @@
+
+ Hi,
+
+
+
+ We had recurrent failures while checking the SSL certificate for
+ <%= @check.domain %>. As of today, we can no longer verify the certificate
+ expiry date.
+
+
+
+ <%- if @check.domain_expires_at.present? %>
+ Our last known expiry date is <%= format_utc(@check.domain_expires_at) %>.
+
+ <%- end %>
+
+ <%- if @check.last_success_at.present? %>
+ Our last successful check occured <%= format_utc(@check.last_success_at) %>.
+ <%- end %>
+
+
+
+ If there is no more SSL endpoint for this domain, please disable
+ or delete the check by following this link:
+ <%= link_to nil, edit_check_url(@check) %>
+
+
+<%= render "check_comment_vendor" %>
+
+
+<%= render "footer_recurrent_failures", interval: @notification.interval, check: @check %>
diff --git a/app/views/notifications_mailer/ssl_recurrent_failures.en.text.erb b/app/views/notifications_mailer/ssl_recurrent_failures.en.text.erb
new file mode 100644
index 0000000..2bb6dd3
--- /dev/null
+++ b/app/views/notifications_mailer/ssl_recurrent_failures.en.text.erb
@@ -0,0 +1,22 @@
+Hi,
+
+We had recurrent failures while checking the SSL certificate for
+<%= @check.domain %>. As of today, we can no longer verify the certificate
+expiry date.
+
+<%- if @check.domain_expires_at.present? %>
+The last known expiry date is <%= format_utc(@check.domain_expires_at) %>.
+<%- end %>
+
+<%- if @check.last_success_at.present? %>
+The last successful check occured <%= format_utc(@check.last_success_at) %>.
+<%- end %>
+
+If there is no more SSL endpoint for this domain, please disable
+or delete the check by following this link:
+
+<%= edit_check_url(@check) %>
+
+<%= render "check_comment_vendor" %>
+
+<%= render "footer_recurrent_failures", interval: @notification.interval, check: @check %>
diff --git a/app/views/notifications_mailer/ssl_recurrent_failures.fr.html.erb b/app/views/notifications_mailer/ssl_recurrent_failures.fr.html.erb
new file mode 100644
index 0000000..ea05abc
--- /dev/null
+++ b/app/views/notifications_mailer/ssl_recurrent_failures.fr.html.erb
@@ -0,0 +1,35 @@
+
+ Salut,
+
+
+
+ Nous avons rencontré de multiples erreurs
+ pendant l'exécution des vérifications du certificat SSL
+ du site <%= @check.domain %>.
+ Nous ne pouvons plus vérifier la date d'expiration du certificat
+ en nous connectant au site.
+
+
+
+ <%- if @check.domain_expires_at.present? %>
+ La dernière date d'expiration connue est le <%= format_utc(@check.domain_expires_at) %>.
+
+ <% end %>
+
+ <%- if @check.last_success_at.present? %>
+ Notre dernière vérification réussie a eu lieu le <%= format_utc(@check.last_success_at) %>.
+ <% end %>
+
+
+
+ S'il n'y a plus de terminaison SSL pour ce site ou s'il n'existe plus,
+ merci de désactiver la vérification associée, avec ce lien :
+
+
+ <%= link_to nil, edit_check_url(@check) %>
+
+
+<%= render "check_comment_vendor" %>
+
+
+<%= render "footer_recurrent_failures", interval: @notification.interval, check: @check %>
diff --git a/app/views/notifications_mailer/ssl_recurrent_failures.fr.text.erb b/app/views/notifications_mailer/ssl_recurrent_failures.fr.text.erb
new file mode 100644
index 0000000..fe15787
--- /dev/null
+++ b/app/views/notifications_mailer/ssl_recurrent_failures.fr.text.erb
@@ -0,0 +1,22 @@
+Salut,
+
+Nous avons rencontré de multiples erreurs pendant l'exécution des vérifications
+du certificat SSL pour le site <%= @check.domain %>.
+Nous ne pouvons plus vérifier la date d'expiration du certificat
+en nous connectant au site.
+
+<%- if @check.domain_expires_at.present? %>
+La dernière date d'expiration connue est le <%= format_utc(@check.domain_expires_at) %>.
+<% end %>
+
+<%- if @check.last_success_at.present? %>
+Notre dernière vérification réussie a eu lieu le <%= format_utc(@check.last_success_at) %>.
+<% end %>
+
+S'il n'y a plus de terminaison SSL pour ce site ou s'il n'existe plus,
+merci de désactiver la vérification associée, avec ce lien :
+<%= edit_check_url(@check) %>
+
+<%= render "check_comment_vendor" %>
+
+<%= render "footer_recurrent_failures", interval: @notification.interval, check: @check %>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index d93597e..9a34ad9 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -38,6 +38,15 @@ en:
domain_recurrent_failures:
subject: "Recurrent failures in %{domain} domain expiry check"
+ ssl_expires_soon:
+ subject:
+ zero: "SSL certificate for %{domain} expires TODAY!"
+ one: "SSL certificate for %{domain} expires TOMORROW!"
+ other: "SSL certificate for %{domain} expires in %{count} days"
+
+ ssl_recurrent_failures:
+ subject: "Recurrent failures in %{domain} SSL certificate expiry check"
+
shared:
locales:
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 4e4b71c..ed5926f 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -12,6 +12,14 @@ fr:
check:
past: "ne peut être dans le futur"
+ time:
+ am: am
+ formats:
+ default: "%a %d %b %Y %H:%M:%S %z"
+ long: "%A %d %B %Y %H:%M"
+ short: "%d %b %H:%M"
+ pm: pm
+
devise:
registrations:
new:
@@ -36,7 +44,16 @@ fr:
other: "Le domaine %{domain} expire dans %{count} jours"
domain_recurrent_failures:
- subject: "Multiples erreur dans la vérification d'expiration du domaine %{domain}"
+ subject: "Erreurs dans la vérification d'expiration du domaine %{domain}"
+
+ ssl_expires_soon:
+ subject:
+ zero: "Le certificat SSL pour %{domain} expire AUJOURD'HUI !"
+ one: "Le certificat SSL pour %{domain} expire DEMAIN !"
+ other: "Le certificat SSL pour %{domain} expire dans %{count} jours"
+
+ ssl_recurrent_failures:
+ subject: "Erreurs dans la vérification d'expiration du certificat SSL %{domain}"
shared:
diff --git a/db/seeds.rb b/db/seeds.rb
index c89deb6..2bf199b 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -1,3 +1,4 @@
+CheckLog.destroy_all
Notification.destroy_all
Check.destroy_all
User.destroy_all
@@ -33,6 +34,31 @@ check_chexpire_org_error = Check.create!(
last_success_at: 4.days.ago,
)
+ssl_check_chexpire_org = Check.create!(
+ user: user1,
+ kind: :ssl,
+ domain: "www.chexpire.org",
+ domain_expires_at: 1.week.from_now,
+ domain_updated_at: 6.months.ago,
+ domain_created_at: Time.new(2016, 8, 4, 12, 15, 1),
+ comment: "The date are fake, this is a seed !",
+ vendor: "Some random registrar",
+)
+
+ssl_check_chexpire_org_error = Check.create!(
+ user: user1,
+ kind: :ssl,
+ domain: "chexpire.org",
+ domain_expires_at: 1.week.from_now,
+ domain_updated_at: 6.months.ago,
+ domain_created_at: Time.new(2016, 8, 4, 12, 15, 1),
+ comment: "The date are fake, this is a seed !",
+ vendor: "Some random registrar",
+ last_run_at: 20.minutes.ago,
+ last_success_at: 4.days.ago,
+)
+
+
Notification.create!(
check: check_chexpire_org,
interval: 15,
@@ -49,6 +75,22 @@ Notification.create!(
status: :pending,
)
+Notification.create!(
+ check: ssl_check_chexpire_org,
+ interval: 15,
+ channel: :email,
+ recipient: "colin@example.org",
+ status: :pending,
+)
+
+Notification.create!(
+ check: ssl_check_chexpire_org_error,
+ interval: 15,
+ channel: :email,
+ recipient: "colin@example.org",
+ status: :pending,
+)
+
puts "\e[0;32mDone 👌\e[0m"
puts " "
puts "--------------------"
diff --git a/test/mailers/notifications_mailer_test.rb b/test/mailers/notifications_mailer_test.rb
index ddae512..c261131 100644
--- a/test/mailers/notifications_mailer_test.rb
+++ b/test/mailers/notifications_mailer_test.rb
@@ -1,6 +1,6 @@
require "test_helper"
-class NotificationsMailerTest < ActionMailer::TestCase
+class NotificationsMailerTest < ActionMailer::TestCase # rubocop:disable Metrics/ClassLength
test "domain_expires_soon" do
check = create(:check, domain_expires_at: Time.new(2018, 6, 10, 12, 0, 5, "+02:00"))
notification = build(:notification, interval: 10, check: check, recipient: "colin@example.org")
@@ -17,7 +17,7 @@ class NotificationsMailerTest < ActionMailer::TestCase
assert_equal ["colin@example.org"], mail.to
assert_equal [Rails.configuration.chexpire.fetch("mailer_default_from")], mail.from
- parts = [mail.text_part.body.to_s, mail.html_part.to_s]
+ parts = [mail.text_part.decode_body, mail.html_part.decode_body]
parts.each do |part|
assert_match "domain.fr", part
@@ -70,7 +70,7 @@ class NotificationsMailerTest < ActionMailer::TestCase
mail = NotificationsMailer.with(notification: notification).domain_expires_soon
- parts = [mail.text_part.body.to_s, mail.html_part.to_s]
+ parts = [mail.text_part.decode_body, mail.html_part.decode_body]
parts.each do |part|
assert_match "My comment", part
@@ -114,7 +114,7 @@ class NotificationsMailerTest < ActionMailer::TestCase
assert_equal ["recipient@domain.fr"], mail.to
assert_equal [Rails.configuration.chexpire.fetch("mailer_default_from")], mail.from
- parts = [mail.text_part.body.to_s, mail.html_part.to_s]
+ parts = [mail.text_part.decode_body, mail.html_part.decode_body]
parts.each do |part|
assert_match "invalid-domain.fr", part
@@ -156,4 +156,128 @@ class NotificationsMailerTest < ActionMailer::TestCase
end
end
end
+
+ test "ssl_expires_soon" do
+ check = create(:check, :ssl, domain_expires_at: Time.new(2018, 6, 10, 12, 0, 5, "+02:00"))
+ notification = build(:notification, interval: 10, check: check, recipient: "colin@example.org")
+
+ Date.stub :today, Date.new(2018, 6, 2) do
+ mail = NotificationsMailer.with(notification: notification).ssl_expires_soon
+
+ assert_emails 1 do
+ mail.deliver_now
+ end
+
+ assert_match "domain.fr", mail.subject
+ assert_match "SSL", mail.subject
+ assert_match "in 8 days", mail.subject
+ assert_equal ["colin@example.org"], mail.to
+ assert_equal [Rails.configuration.chexpire.fetch("mailer_default_from")], mail.from
+
+ parts = [mail.text_part.decode_body, mail.html_part.decode_body]
+
+ parts.each do |part|
+ assert_match "domain.fr", part
+ assert_match "Sun, 10 Jun 2018 10:00:05 +0000", part
+ assert_match "10 days", part
+ assert_match "/checks/#{check.id}/edit", part
+ assert_no_match "comment", part
+ assert_no_match "vendor", part
+ end
+ end
+ end
+
+ test "ssl_expires_soon - FR" do
+ check = create(:check, :ssl, domain_expires_at: Time.new(2018, 6, 10, 12, 0, 5, "+02:00"))
+ notification = build(:notification, interval: 10, check: check, recipient: "colin@example.org")
+
+ I18n.with_locale :fr do
+ Date.stub :today, Date.new(2018, 6, 2) do
+ mail = NotificationsMailer.with(notification: notification).ssl_expires_soon
+
+ assert_emails 1 do
+ mail.deliver_now
+ end
+
+ assert_match "domain.fr", mail.subject
+ assert_match "SSL", mail.subject
+ assert_match "dans 8 jours", mail.subject
+ assert_equal ["colin@example.org"], mail.to
+ assert_equal [Rails.configuration.chexpire.fetch("mailer_default_from")], mail.from
+
+ parts = [mail.text_part.decode_body, mail.html_part.decode_body]
+
+ parts.each do |part|
+ assert_match "domain.fr", part
+ assert_match "dim 10 juin 2018 10:00:05 +0000", part
+ assert_match "10 jours", part
+ assert_match "/checks/#{check.id}/edit", part
+ assert_no_match "commentaire", part
+ assert_no_match "fournisseur", part
+ end
+ end
+ end
+ end
+
+ test "ssl_recurrent_failures" do
+ last_success_at = Time.new(2018, 5, 30, 6, 10, 0, "+00:00")
+ domain_expires_at = Time.new(2018, 10, 10, 7, 20, 0, "+04:00")
+ check = build(:check, :ssl, :last_runs_failed,
+ domain: "invalid-domain.fr",
+ last_success_at: last_success_at,
+ domain_expires_at: domain_expires_at,
+ comment: "My comment")
+ notification = create(:notification, check: check)
+
+ mail = NotificationsMailer.with(notification: notification).ssl_recurrent_failures
+ assert_match "failures", mail.subject
+ assert_match "invalid-domain.fr", mail.subject
+ assert_match "SSL", mail.subject
+
+ assert_equal ["recipient@domain.fr"], mail.to
+ assert_equal [Rails.configuration.chexpire.fetch("mailer_default_from")], mail.from
+
+ parts = [mail.text_part.decode_body, mail.html_part.decode_body]
+
+ parts.each do |part|
+ assert_match "invalid-domain.fr", part
+ assert_match "recurrent failures", part
+ assert_match(/success[a-z ]+ Wed, 30 May 2018 06:10:00 \+0000/, part)
+ assert_match(/expiry[a-z ]+ Wed, 10 Oct 2018 03:20:00 \+0000/, part)
+ assert_match "My comment", part
+ assert_match "/checks/#{check.id}/edit", part
+ end
+ end
+
+ test "ssl_recurrent_failures - FR" do
+ last_success_at = Time.new(2018, 5, 30, 6, 10, 0, "+00:00")
+ domain_expires_at = Time.new(2018, 10, 10, 7, 20, 0, "+04:00")
+ check = build(:check, :ssl, :last_runs_failed,
+ domain: "invalid-domain.fr",
+ last_success_at: last_success_at,
+ domain_expires_at: domain_expires_at,
+ comment: "My comment")
+ notification = create(:notification, check: check)
+
+ I18n.with_locale :fr do
+ mail = NotificationsMailer.with(notification: notification).ssl_recurrent_failures
+ assert_match "Erreurs", mail.subject
+ assert_match "invalid-domain.fr", mail.subject
+ assert_match "SSL", mail.subject
+
+ assert_equal ["recipient@domain.fr"], mail.to
+ assert_equal [Rails.configuration.chexpire.fetch("mailer_default_from")], mail.from
+
+ parts = [mail.text_part.decode_body, mail.html_part.decode_body]
+
+ parts.each do |part|
+ assert_match "invalid-domain.fr", part
+ assert_match "erreurs", part
+ assert_match(/réussie[a-z ]+ mer 30 mai 2018 06:10:00 \+0000/, part)
+ assert_match(/expiration[a-z ]+ mer 10 oct. 2018 03:20:00 \+0000/, part)
+ assert_match "commentaire", part
+ assert_match "/checks/#{check.id}/edit", part
+ end
+ end
+ end
end
diff --git a/test/mailers/previews/notifications_mailer_preview.rb b/test/mailers/previews/notifications_mailer_preview.rb
index f9c2898..01f5085 100644
--- a/test/mailers/previews/notifications_mailer_preview.rb
+++ b/test/mailers/previews/notifications_mailer_preview.rb
@@ -2,12 +2,25 @@
class NotificationsMailerPreview < ActionMailer::Preview
# Preview this email at http://localhost:3000/rails/mailers/notifications_mailer/domain_expires_soon
def domain_expires_soon
- NotificationsMailer.with(notification: Notification.first).domain_expires_soon
+ check = Check.domain.first
+ NotificationsMailer.with(notification: check.notifications.first).domain_expires_soon
end
# Preview this email at http://localhost:3000/rails/mailers/notifications_mailer/domain_recurrent_failures
def domain_recurrent_failures
- check = Check.where("last_run_at != last_success_at").limit(1).first
+ check = Check.domain.where("last_run_at != last_success_at").first
NotificationsMailer.with(notification: check.notifications.first).domain_recurrent_failures
end
+
+ # Preview this email at http://localhost:3000/rails/mailers/notifications_mailer/ssl_expires_soon
+ def ssl_expires_soon
+ check = Check.ssl.first
+ NotificationsMailer.with(notification: check.notifications.first).ssl_expires_soon
+ end
+
+ # Preview this email at http://localhost:3000/rails/mailers/notifications_mailer/ssl_recurrent_failures
+ def ssl_recurrent_failures
+ check = Check.ssl.where("last_run_at != last_success_at").first
+ NotificationsMailer.with(notification: check.notifications.first).ssl_recurrent_failures
+ end
end