Skip to content

Commit

Permalink
feat: add smtp verify check before launch servie
Browse files Browse the repository at this point in the history
  • Loading branch information
icyleaf committed Sep 26, 2024
1 parent cb6e7f2 commit 8cd2b89
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 3 deletions.
2 changes: 2 additions & 0 deletions app/models/setting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ class Setting < RailsSettings::Base
readonly: true, display: true
field :mailer_default_reply_to, default: ENV['ACTION_MAILER_DEFAULT_TO'], type: :string,
readonly: true, display: true
field :mailer_method, type: :string, display: false, readonly: true,
default: Rails.configuration.action_mailer.delivery_method
field :mailer_options, type: :hash, display: true, readonly: true,
default: Rails.configuration.action_mailer.smtp_settings, validates: { json: { format: :hash } }
end
Expand Down
5 changes: 4 additions & 1 deletion app/views/admin/settings/_setting.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ ruby:
data-action="admin-smtp-verify#run"
] = t('admin.settings.index.smtp_verify')
== render 'switch_icon', value: value
= display_value
- if key == 'mailer_options' && Rails.env.development?
= Setting.mailer_method
- else
= display_value
- else
pre.mb-2
== render 'switch_icon', value: value
Expand Down
17 changes: 16 additions & 1 deletion config/environments/development.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,22 @@
# If using a Heroku, Vagrant or generic remote development environment,
# use letter_opener_web, accessible at /letter_opener.
# Otherwise, use letter_opener, which launches a browser window to view sent mail.
config.action_mailer.delivery_method = %w[HEROKU_APP_ID VAGRANT REMOTE_DEV].select { |k| ENV[k].present? }.empty? ? :letter_opener_web : :letter_opener
if ActiveModel::Type::Boolean.new.cast(ENV['ENABLE_DEVELOPMENT_MAILER_TEST'])
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: ENV['SMTP_ADDRESS'],
port: ENV['SMTP_PORT'].to_i,
domain: ENV['SMTP_DOMAIN'] || ENV['ZEALOT_DOMAIN'],
user_name: ENV['SMTP_USERNAME'].presence,
password: ENV['SMTP_PASSWORD'].presence,
authentication: ENV['SMTP_AUTH_METHOD'] == 'none' ? nil : ENV['SMTP_AUTH_METHOD'].presence || 'plain',
enable_starttls: ActiveModel::Type::Boolean.new.cast(ENV['SMTP_ENABLE_STARTTLS_AUTO']) ?
:auto : ActiveModel::Type::Boolean.new.cast(ENV['SMTP_ENABLE_STARTTLS']),
openssl_verify_mode: ENV['SMTP_OPENSSL_VERIFY_MODE'],
}
else
config.action_mailer.delivery_method = %w[HEROKU_APP_ID VAGRANT REMOTE_DEV].select { |k| ENV[k].present? }.empty? ? :letter_opener_web : :letter_opener
end

# # Use an evented file watcher to asynchronously detect changes in source code,
# # routes, locales, etc. This feature depends on the listen gem.
Expand Down
21 changes: 20 additions & 1 deletion lib/tasks/zealot/zealot.rake
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require_relative '../../zealot/smtp_validator'

namespace :zealot do
desc 'Zealot | Upgrade zealot or setting up database'
task upgrade: :environment do
Expand All @@ -9,14 +11,31 @@ namespace :zealot do

desc 'Zealot | Precheck service healthly'
task precheck: :environment do
# nothing to do
Rake::Task['zealot:check:smtp'].invoke
end

desc 'Zealot | Remove all data and init demo data and user'
task reset: :environment do
ResetForDemoModeJob.perform_now
end

namespace :check do
task smtp: :environment do
puts "SMTP testing ..."

smtp_validator = Zealot::SMTPValidator.new
if smtp_validator.configured?
success = smtp_validator.verify
unless success
fail smtp_validator.error_message
exit!
end
else
puts "smtp is not configure, skip"
end
end
end

namespace :db do
task upgrade: :environment do
db_version = begin
Expand Down
53 changes: 53 additions & 0 deletions lib/zealot/smtp_validator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# frozen_string_literal: true
require 'pp'

class Zealot::SMTPValidator
def initialize
if enabled?
@address = Setting.mailer_options[:address]
@port = Setting.mailer_options[:port]
@starttls = Setting.mailer_options[:enable_starttls]
@username = Setting.mailer_options[:user_name]
@password = Setting.mailer_options[:password]
end
end

def configured?
return false unless enabled?

@address.presence && @port.presence && @port.presence && @password.presence
end

def verify
Net::SMTP.start(@address, @port) do|smtp|
smtp.enable_starttls if @starttls
smtp.authenticate(@username, @password, auth_method).success?
end

true
rescue StandardError => e
@error = e
false
end

def error_message
case @error
when Net::SMTPAuthenticationError
'Username and Password not accepted, check your SMTP username and password.'
else
'Unkown error, check your SMTP settings.'
end
end

private

def enabled?
!Rails.env.development? ||
(Rails.env.development? && ActiveModel::Type::Boolean.new.cast(ENV['ENABLE_DEVELOPMENT_MAILER_TEST']))
end

def auth_method
value = Setting.mailer_options[:auth_method].presence || 'plain'
value == 'none' ? nil : value.to_sym
end
end

0 comments on commit 8cd2b89

Please sign in to comment.