مراية لـ
https://github.com/postalserver/postal.git
تم المزامنة 2025-12-01 05:43:04 +00:00
Merge pull request #2801 from postalserver/smtp-tests
Tests for the SMTP Server
هذا الالتزام موجود في:
@@ -25,7 +25,7 @@ module Postal
|
||||
@attributes[name.to_s]
|
||||
end
|
||||
|
||||
def respond_to_missing?(name)
|
||||
def respond_to_missing?(name, include_private = false)
|
||||
@attributes.key?(name.to_s)
|
||||
end
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ module Postal
|
||||
end
|
||||
end
|
||||
|
||||
def respond_to_missing?(name)
|
||||
def respond_to_missing?(name, include_private = false)
|
||||
name = name.to_s.sub(/=\z/, "")
|
||||
@attributes.key?(name.to_s)
|
||||
end
|
||||
|
||||
@@ -11,23 +11,28 @@ module Postal
|
||||
def up
|
||||
end
|
||||
|
||||
def self.run(database, start_from = database.schema_version)
|
||||
def self.run(database, start_from: database.schema_version, silent: false)
|
||||
files = Dir[Rails.root.join("lib", "postal", "message_db", "migrations", "*.rb")]
|
||||
files = files.map do |f|
|
||||
id, name = f.split("/").last.split("_", 2)
|
||||
[id.to_i, name]
|
||||
end.sort_by(&:first)
|
||||
|
||||
latest_version = files.last.first
|
||||
if latest_version > start_from
|
||||
puts "\e[32mMigrating #{database.database_name} from version #{start_from} => #{files.last.first}\e[0m"
|
||||
else
|
||||
puts "Nothing to do."
|
||||
if latest_version <= start_from
|
||||
puts "Nothing to do" unless silent
|
||||
return false
|
||||
end
|
||||
|
||||
unless silent
|
||||
puts "\e[32mMigrating #{database.database_name} from version #{start_from} => #{files.last.first}\e[0m"
|
||||
end
|
||||
|
||||
files.each do |version, file|
|
||||
klass_name = file.gsub(/\.rb\z/, "").camelize
|
||||
next if start_from >= version
|
||||
|
||||
puts "\e[45m++ Migrating #{klass_name} (#{version})\e[0m"
|
||||
puts "\e[45m++ Migrating #{klass_name} (#{version})\e[0m" unless silent
|
||||
require "postal/message_db/migrations/#{version.to_s.rjust(2, '0')}_#{file}"
|
||||
klass = Postal::MessageDB::Migrations.const_get(klass_name)
|
||||
instance = klass.new(database)
|
||||
|
||||
@@ -14,14 +14,14 @@ module Postal
|
||||
def provision
|
||||
drop
|
||||
create
|
||||
migrate
|
||||
migrate(silent: true)
|
||||
end
|
||||
|
||||
#
|
||||
# Migrate this database
|
||||
#
|
||||
def migrate(start_from = @database.schema_version)
|
||||
Postal::MessageDB::Migration.run(@database, start_from)
|
||||
def migrate(start_from: @database.schema_version, silent: false)
|
||||
Postal::MessageDB::Migration.run(@database, start_from: start_from, silent: silent)
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
@@ -11,6 +11,12 @@ module Postal
|
||||
LOG_REDACTION_STRING = "[redacted]"
|
||||
|
||||
attr_reader :logging_enabled
|
||||
attr_reader :credential
|
||||
attr_reader :ip_address
|
||||
attr_reader :recipients
|
||||
attr_reader :headers
|
||||
attr_reader :state
|
||||
attr_reader :helo_name
|
||||
|
||||
def initialize(ip_address)
|
||||
@logging_enabled = true
|
||||
@@ -55,19 +61,6 @@ module Postal
|
||||
end
|
||||
end
|
||||
|
||||
def sanitize_input_for_log(data)
|
||||
if @password_expected_next
|
||||
@password_expected_next = false
|
||||
if data =~ /\A[a-z0-9]{3,}=*\z/i
|
||||
return LOG_REDACTION_STRING
|
||||
end
|
||||
end
|
||||
|
||||
data = data.dup
|
||||
data.gsub!(/(.*AUTH \w+) (.*)\z/i) { "#{::Regexp.last_match(1)} #{LOG_REDACTION_STRING}" }
|
||||
data
|
||||
end
|
||||
|
||||
def finished?
|
||||
@finished || false
|
||||
end
|
||||
@@ -137,7 +130,11 @@ module Postal
|
||||
@helo_name = data.strip.split(" ", 2)[1]
|
||||
transaction_reset
|
||||
@state = :welcomed
|
||||
["250-My capabilities are", Postal.config.smtp_server.tls_enabled? && !@tls ? "250-STARTTLS" : nil, "250 AUTH CRAM-MD5 PLAIN LOGIN"]
|
||||
[
|
||||
"250-My capabilities are",
|
||||
Postal.config.smtp_server.tls_enabled? && !@tls ? "250-STARTTLS" : nil,
|
||||
"250 AUTH CRAM-MD5 PLAIN LOGIN"
|
||||
].compact
|
||||
end
|
||||
|
||||
def helo(data)
|
||||
@@ -194,7 +191,7 @@ module Postal
|
||||
"334 UGFzc3dvcmQ6" # "Password:"
|
||||
end
|
||||
|
||||
data = data.gsub!(/AUTH LOGIN ?/i, "")
|
||||
data = data.gsub(/AUTH LOGIN ?/i, "")
|
||||
if data.strip == ""
|
||||
@proc = username_handler
|
||||
"334 VXNlcm5hbWU6" # "Username:"
|
||||
@@ -226,6 +223,7 @@ module Postal
|
||||
log "\e[33m WARN: AUTH failure for #{@ip_address}\e[0m"
|
||||
next "535 Denied"
|
||||
end
|
||||
|
||||
grant = nil
|
||||
server.credentials.where(type: "SMTP").each do |credential|
|
||||
correct_response = OpenSSL::HMAC.hexdigest(CRAM_MD5_DIGEST, credential.key, challenge)
|
||||
@@ -236,10 +234,12 @@ module Postal
|
||||
grant = "235 Granted for #{credential.server.organization.permalink}/#{credential.server.permalink}"
|
||||
break
|
||||
end
|
||||
|
||||
if grant.nil?
|
||||
log "\e[33m WARN: AUTH failure for #{@ip_address}\e[0m"
|
||||
next "535 Denied"
|
||||
end
|
||||
|
||||
grant
|
||||
end
|
||||
|
||||
@@ -458,6 +458,7 @@ module Postal
|
||||
msg.mail_from = @mail_from
|
||||
msg.raw_message = @data
|
||||
msg.received_with_ssl = @tls
|
||||
msg.bounce = 1
|
||||
end
|
||||
else
|
||||
# There's no return path route, we just need to insert the mesage
|
||||
@@ -489,6 +490,19 @@ module Postal
|
||||
states.include?(@state)
|
||||
end
|
||||
|
||||
def sanitize_input_for_log(data)
|
||||
if @password_expected_next
|
||||
@password_expected_next = false
|
||||
if data =~ /\A[a-z0-9]{3,}=*\z/i
|
||||
return LOG_REDACTION_STRING
|
||||
end
|
||||
end
|
||||
|
||||
data = data.dup
|
||||
data.gsub!(/(.*AUTH \w+) (.*)\z/i) { "#{::Regexp.last_match(1)} #{LOG_REDACTION_STRING}" }
|
||||
data
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,48 +1,57 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# NOTE: only doing this in development as some production environments (Heroku)
|
||||
# NOTE: are sensitive to local FS writes, and besides -- it's just not proper
|
||||
# NOTE: to have a dev-mode tool do its thing in production.
|
||||
if Rails.env.development?
|
||||
require 'annotate'
|
||||
task :set_annotation_options do
|
||||
# You can override any of these by setting an environment variable of the
|
||||
# same name.
|
||||
Annotate.set_defaults(
|
||||
"routes" => "false",
|
||||
"position_in_routes" => "before",
|
||||
"position_in_class" => "before",
|
||||
"position_in_test" => "before",
|
||||
"position_in_fixture" => "before",
|
||||
"position_in_factory" => "before",
|
||||
"position_in_serializer" => "before",
|
||||
"show_foreign_keys" => "true",
|
||||
"show_indexes" => "true",
|
||||
"simple_indexes" => "false",
|
||||
"model_dir" => "app/models",
|
||||
"root_dir" => "",
|
||||
"include_version" => "false",
|
||||
"require" => "",
|
||||
"exclude_tests" => "false",
|
||||
"exclude_fixtures" => "false",
|
||||
"exclude_factories" => "false",
|
||||
"exclude_serializers" => "false",
|
||||
"exclude_scaffolds" => "true",
|
||||
"exclude_controllers" => "true",
|
||||
"exclude_helpers" => "true",
|
||||
"ignore_model_sub_dir" => "false",
|
||||
"ignore_columns" => nil,
|
||||
"ignore_routes" => nil,
|
||||
"ignore_unknown_models" => "false",
|
||||
"hide_limit_column_types" => "integer,boolean",
|
||||
"skip_on_db_migrate" => "false",
|
||||
"format_bare" => "true",
|
||||
"format_rdoc" => "false",
|
||||
"format_markdown" => "false",
|
||||
"sort" => "false",
|
||||
"force" => "false",
|
||||
"trace" => "false",
|
||||
"wrapper_open" => nil,
|
||||
"wrapper_close" => nil
|
||||
'active_admin' => 'false',
|
||||
'additional_file_patterns' => [],
|
||||
'routes' => 'false',
|
||||
'models' => 'true',
|
||||
'position_in_routes' => 'before',
|
||||
'position_in_class' => 'before',
|
||||
'position_in_test' => 'before',
|
||||
'position_in_fixture' => 'before',
|
||||
'position_in_factory' => 'before',
|
||||
'position_in_serializer' => 'before',
|
||||
'show_foreign_keys' => 'true',
|
||||
'show_complete_foreign_keys' => 'false',
|
||||
'show_indexes' => 'true',
|
||||
'simple_indexes' => 'false',
|
||||
'model_dir' => 'app/models',
|
||||
'root_dir' => '',
|
||||
'include_version' => 'false',
|
||||
'require' => '',
|
||||
'exclude_tests' => 'false',
|
||||
'exclude_fixtures' => 'false',
|
||||
'exclude_factories' => 'false',
|
||||
'exclude_serializers' => 'false',
|
||||
'exclude_scaffolds' => 'true',
|
||||
'exclude_controllers' => 'true',
|
||||
'exclude_helpers' => 'true',
|
||||
'exclude_sti_subclasses' => 'false',
|
||||
'ignore_model_sub_dir' => 'false',
|
||||
'ignore_columns' => nil,
|
||||
'ignore_routes' => nil,
|
||||
'ignore_unknown_models' => 'false',
|
||||
'hide_limit_column_types' => 'integer,bigint,boolean',
|
||||
'hide_default_column_types' => 'json,jsonb,hstore',
|
||||
'skip_on_db_migrate' => 'false',
|
||||
'format_bare' => 'true',
|
||||
'format_rdoc' => 'false',
|
||||
'format_yard' => 'false',
|
||||
'format_markdown' => 'false',
|
||||
'sort' => 'false',
|
||||
'force' => 'false',
|
||||
'frozen' => 'false',
|
||||
'classified_sort' => 'true',
|
||||
'trace' => 'false',
|
||||
'wrapper_open' => nil,
|
||||
'wrapper_close' => nil,
|
||||
'with_comment' => 'true'
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
المرجع في مشكلة جديدة
حظر مستخدم