added services
This commit is contained in:
0
services/lib/assets/.keep
Normal file
0
services/lib/assets/.keep
Normal file
63
services/lib/bettermail/consumer.rb
Normal file
63
services/lib/bettermail/consumer.rb
Normal file
@ -0,0 +1,63 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'mail'
|
||||
require 'bunny'
|
||||
|
||||
# in module for neatness
|
||||
module Bettermail
|
||||
# The General purpose consumer
|
||||
class Consumer
|
||||
def initialize
|
||||
end
|
||||
|
||||
def default_smtp_settings
|
||||
{
|
||||
address: ENV['DEFAULT_SMTP_HOST'],
|
||||
port: ENV['DEFAULT_SMTP_PORT'],
|
||||
user_name: ENV['DEFAULT_SMTP_UID'],
|
||||
password: ENV['DEFAULT_SMTP_PWD'],
|
||||
enable_starttls_auto: true,
|
||||
authentication: 'plain',
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
|
||||
def start
|
||||
begin
|
||||
puts ' [*] Waiting for messages. To exit press CTRL+C'
|
||||
new_mail_queue = bunny_channel.queue(ENV['RABBIT_MAIL_QUEUE'])
|
||||
new_mail_queue.subscribe(block: true) do |_delivery_info, _properties, body|
|
||||
instructions = JSON.parse(body)
|
||||
recipient = Recipient.create_or_find_by(id: instructions["recipient"])
|
||||
email = ReceivedMail.find_by(message_id: instructions["message"])
|
||||
recipient.emails.create(received_mail: email, delivery_status: 'queued')
|
||||
end
|
||||
sns_queue = bunny_channel.queue(ENV['RABBIT_SNS_QUEUE'])
|
||||
sns_queue.subscribe(block: true) do |_delivery_info, _properties, body|
|
||||
puts " [x] Received #{_delivery_info}"
|
||||
end
|
||||
rescue Interrupt => _
|
||||
stop
|
||||
end
|
||||
end
|
||||
|
||||
def send_mail(mail)
|
||||
mail.delivery_method :smtp, default_smtp_settings
|
||||
mail.deliver!
|
||||
end
|
||||
|
||||
def stop
|
||||
@bunny_conn&.close
|
||||
end
|
||||
|
||||
def bunny_channel
|
||||
if @bunny_channel.nil?
|
||||
@bunny_conn = Bunny.new
|
||||
@bunny_conn.start
|
||||
@bunny_channel = @bunny_conn.create_channel
|
||||
end
|
||||
@bunny_channel
|
||||
end
|
||||
end
|
||||
end
|
79
services/lib/bettermail/proxy.rb
Normal file
79
services/lib/bettermail/proxy.rb
Normal file
@ -0,0 +1,79 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'midi-smtp-server'
|
||||
require 'mail'
|
||||
require 'bunny'
|
||||
require 'securerandom'
|
||||
|
||||
# in module for neatness
|
||||
module Bettermail
|
||||
# The SMTPProxy
|
||||
class Proxy < MidiSmtpServer::Smtpd
|
||||
|
||||
def stop(wait_seconds_before_close: nil, gracefully: nil)
|
||||
super()
|
||||
@bunny_conn&.close
|
||||
end
|
||||
|
||||
def bunny
|
||||
if @bunny.nil?
|
||||
@bunny_conn = Bunny.new
|
||||
@bunny_conn.start
|
||||
ch = @bunny_conn.create_channel
|
||||
ch.direct(ENV['RABBIT_CHANNEL'])
|
||||
ch.queue(ENV['RABBIT_MAIL_QUEUE'])
|
||||
@bunny = ch.default_exchange
|
||||
end
|
||||
@bunny
|
||||
end
|
||||
|
||||
# update local welcome and helo response
|
||||
def on_connect_event(ctx)
|
||||
ctx[:server][:local_response] = 'Client connected'
|
||||
ctx[:server][:helo_response] = 'Welcome to the BetterMail proxy - an SMTP drop in replacement'
|
||||
end
|
||||
|
||||
def on_message_data_headers_event(ctx)
|
||||
# check and append all headers
|
||||
ctx[:message][:data] << "X-bettermail: Received by proxy at #{Time.now}" << ctx[:message][:crlf]
|
||||
end
|
||||
|
||||
# check the authentication
|
||||
# if any value returned, that will be used for ongoing processing
|
||||
# otherwise the original value will be used for authorization_id
|
||||
def on_auth_event(ctx, authorization_id, authentication_id, authentication)
|
||||
# to proceed this test use commands ...
|
||||
# auth plain
|
||||
# > AGFkbWluaXN0cmF0b3IAcGFzc3dvcmQ=
|
||||
# auth login
|
||||
# > YWRtaW5pc3RyYXRvcg==
|
||||
# > cGFzc3dvcmQ=
|
||||
# if authorization_id == '' && authentication_id == 'administrator' && authentication == 'password'
|
||||
# # yes
|
||||
# return 'supervisor'
|
||||
# end
|
||||
# # otherwise exit with authentication exception
|
||||
# raise MidiSmtpServer::Smtpd535Exception
|
||||
logger.debug("Authenticated id: #{authentication_id} with authentication: #{authentication} from: #{ctx[:server][:remote_ip]}:#{ctx[:server][:remote_port]}")
|
||||
authentication_id
|
||||
end
|
||||
|
||||
def save_mail(ctx, sender)
|
||||
mail = Mail.read_from_string(ctx[:message][:data])
|
||||
sender = Sender.create_or_find_by(id: sender)
|
||||
message_id = "#{SecureRandom.uuid}@bettermail.wizewerx.tech"
|
||||
saved_mail = sender.sent_mails.create(message_id: message_id, body: mail.to_s)
|
||||
message_id
|
||||
end
|
||||
|
||||
def on_mail_from_event(ctx, mail_from_data)
|
||||
# tag the message here OR write it once to the database
|
||||
ctx[:message][:message_id] = save_mail(ctx, mail_from_data)
|
||||
end
|
||||
|
||||
# simple rewrite and return value
|
||||
def on_rcpt_to_event(ctx, data)
|
||||
bunny.publish({message: ctx[:message][:message_id], recipient: data}.to_json, :headers => { }, :routing_key => ENV["RABBIT_MAIL_QUEUE"])
|
||||
end
|
||||
end
|
||||
end
|
0
services/lib/tasks/.keep
Normal file
0
services/lib/tasks/.keep
Normal file
46
services/lib/tasks/consumer.rake
Normal file
46
services/lib/tasks/consumer.rake
Normal file
@ -0,0 +1,46 @@
|
||||
namespace :consumer do
|
||||
task start: :environment do
|
||||
service_name = 'BetterMail::Consumer'
|
||||
# Create a new server instance for listening at localhost interfaces 127.0.0.1:2525
|
||||
# and accepting a maximum of 4 simultaneous connections per default
|
||||
service = Bettermail::Consumer.new
|
||||
|
||||
# save flag for Ctrl-C pressed
|
||||
flag_status_ctrl_c_pressed = false
|
||||
|
||||
# try to gracefully shutdown on Ctrl-C
|
||||
trap('INT') do
|
||||
# print an empty line right after ^C
|
||||
puts
|
||||
# notify flag about Ctrl-C was pressed
|
||||
flag_status_ctrl_c_pressed = true
|
||||
# signal exit to app
|
||||
exit 0
|
||||
end
|
||||
|
||||
# Output for debug
|
||||
puts("Starting #{service_name}")
|
||||
|
||||
# setup exit code
|
||||
at_exit do
|
||||
# check to shutdown connection
|
||||
if service
|
||||
# Output for debug
|
||||
puts('Ctrl-C interrupted, exit now...') if flag_status_ctrl_c_pressed
|
||||
# info about shutdown
|
||||
puts("Shutdown #{service_name}...")
|
||||
# stop all threads and connections gracefully
|
||||
service.stop
|
||||
end
|
||||
|
||||
# Output for debug
|
||||
puts "#{service_name} stopped!"
|
||||
end
|
||||
|
||||
# Start the server
|
||||
service.start
|
||||
|
||||
# Run on server forever
|
||||
service.join
|
||||
end
|
||||
end
|
58
services/lib/tasks/proxy.rake
Normal file
58
services/lib/tasks/proxy.rake
Normal file
@ -0,0 +1,58 @@
|
||||
namespace :proxy do
|
||||
task start: :environment do
|
||||
# Create a new server instance for listening at localhost interfaces 127.0.0.1:2525
|
||||
# and accepting a maximum of 4 simultaneous connections per default
|
||||
service = Bettermail::Proxy.new(
|
||||
ports: ENV['PROXY_PORTS'],
|
||||
hosts: ENV['PROXY_HOSTS'],
|
||||
max_processings: 10,
|
||||
auth_mode: :AUTH_REQUIRED,
|
||||
tls_mode: :TLS_REQUIRED,
|
||||
tls_cert_path: './ssl/cert.pem',
|
||||
tls_key_path: './ssl/key.pem'
|
||||
)
|
||||
|
||||
service_name = 'BetterMail::SMTPProxy'
|
||||
# Create a new server instance for listening at localhost interfaces 127.0.0.1:2525
|
||||
# and accepting a maximum of 4 simultaneous connections per default
|
||||
|
||||
# save flag for Ctrl-C pressed
|
||||
flag_status_ctrl_c_pressed = false
|
||||
|
||||
# try to gracefully shutdown on Ctrl-C
|
||||
trap('INT') do
|
||||
# print an empty line right after ^C
|
||||
puts
|
||||
# notify flag about Ctrl-C was pressed
|
||||
flag_status_ctrl_c_pressed = true
|
||||
# signal exit to app
|
||||
exit(0)
|
||||
end
|
||||
|
||||
# Output for debug
|
||||
puts("Starting #{service_name}")
|
||||
|
||||
# setup exit code
|
||||
at_exit do
|
||||
# check to shutdown connection
|
||||
if service
|
||||
# Output for debug
|
||||
puts('Ctrl-C interrupted, exit now...') if flag_status_ctrl_c_pressed
|
||||
# info about shutdown
|
||||
puts("Shutdown #{service_name}...")
|
||||
# stop all threads and connections gracefully
|
||||
service.stop
|
||||
end
|
||||
|
||||
# Output for debug
|
||||
puts "#{service_name} stopped!"
|
||||
end
|
||||
|
||||
# Start the server
|
||||
service.start
|
||||
|
||||
# Run on server forever
|
||||
service.join
|
||||
end
|
||||
end
|
||||
|
Reference in New Issue
Block a user