Class: SesProxy::SmtpServer

Inherits:
EM::P::SmtpServer
  • Object
show all
Defined in:
lib/ses_proxy/smtp_server.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.running?Boolean

Returns:

  • (Boolean)


180
181
182
# File 'lib/ses_proxy/smtp_server.rb', line 180

def self.running?
  !!@server
end

.start(host, port) ⇒ Object



167
168
169
170
171
# File 'lib/ses_proxy/smtp_server.rb', line 167

def self.start(host, port)
  trap(:QUIT) { stop }
  @host = host
  @server = EM.start_server host, port, self
end

.stopObject



173
174
175
176
177
178
# File 'lib/ses_proxy/smtp_server.rb', line 173

def self.stop
  if @server
   EM.stop_server @server
   @server = nil
  end
end

Instance Method Details

#get_server_domainObject



21
22
23
# File 'lib/ses_proxy/smtp_server.rb', line 21

def get_server_domain
  @host || "mock.smtp.server.local"
end

#get_server_greetingObject



25
26
27
# File 'lib/ses_proxy/smtp_server.rb', line 25

def get_server_greeting
  "smtp ses greetings"
end

#messageObject



65
66
67
# File 'lib/ses_proxy/smtp_server.rb', line 65

def message
  @message || ""
end

#receive_data_chunk(data) ⇒ Object



52
53
54
55
# File 'lib/ses_proxy/smtp_server.rb', line 52

def receive_data_chunk(data)
  @message = "#{@message}\n#{data.join("\n")}"
  true
end

#receive_ehlo_domain(domain) ⇒ Object



162
163
164
165
# File 'lib/ses_proxy/smtp_server.rb', line 162

def receive_ehlo_domain(domain)
  @ehlo_domain = domain
  true
end

#receive_messageObject



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/ses_proxy/smtp_server.rb', line 77

def receive_message
  return false unless verified
  mail = Mail.read_from_string(message)
  bounced = Bounce.where({:email=>{"$in"=>recipients}}).map(&:email)
  #TODO: Define policy for retry when bounce is not permanent

  #Remove bounced addresses
  actual_recipients = mail.to_addrs - bounced
  actual_cc_addrs = mail.cc_addrs - bounced
  actual_bcc_addrs = recipients - (mail.to_addrs + mail.cc_addrs) - bounced

  #Remove blacklisted domains
  if SesProxy::Conf.get[:blacklisted_domains] and SesProxy::Conf.get[:blacklisted_domains].any?
    bld = SesProxy::Conf.get[:blacklisted_domains]
    actual_recipients.collect!{|address| address unless bld.include?(address.split('@').last)}.compact!
    actual_cc_addrs.collect!{|address| address unless bld.include?(address.split('@').last)}.compact!
    actual_bcc_addrs.collect!{|address| address unless bld.include?(address.split('@').last)}.compact!
  end

  #Remove blacklisted regexp
  if SesProxy::Conf.get[:blacklisted_regexp] and SesProxy::Conf.get[:blacklisted_regexp].any?
    blr = SesProxy::Conf.get[:blacklisted_regexp]
    actual_recipients.collect!{|address| address unless blr.map{|regexp| Regexp.new(regexp).match(address)}.compact.any? }.compact!
    actual_cc_addrs.collect!{|address| address unless blr.map{|regexp| Regexp.new(regexp).match(address)}.compact.any? }.compact!
    actual_bcc_addrs.collect!{|address| address unless blr.map{|regexp| Regexp.new(regexp).match(address)}.compact.any? }.compact!
  end

  original_number = recipients.size
  filtered_number = actual_recipients.size+actual_cc_addrs.size+actual_bcc_addrs.size
  record = RecipientsNumber.new({
    :original=>original_number,
    :filtered=>filtered_number,
    :created_at => Time.now,
    :updated_at => Time.now
  })
  record.save!
  if actual_recipients.any?
    mail.to = actual_recipients.uniq.join(",")
    mail.cc = actual_cc_addrs.uniq.join(",")
    mail.bcc = actual_bcc_addrs.uniq.join(",")
    unless SesProxy::Conf.get[:collect_sent_mails].eql? false
      record = Email.new({
        :sender => sender,
        :recipients => actual_recipients.uniq.join(","),
        :subject => mail.subject,
        :body => mail.body.decoded,
        :system => mail['X-Sender-System']||"Unknown",
        :created_at => Time.now,
        :updated_at => Time.now
      })
      record.save!
    end
    begin
      if SesProxy::Conf.get[:aws][:ses] and SesProxy::Conf.get[:aws][:ses][:username] and SesProxy::Conf.get[:aws][:ses][:password]
        mail.deliver!
      else
        ses.send_raw_email(mail.to_s)
      end
    rescue Exception => e
      print "Error! "
      puts e.message
      return false
    end
  else
    puts "No valid recipients! #{mail.to_addrs}"
  end
  if not original_number.eql? filtered_number
    unless SesProxy::Conf.get[:collect_bounced_mails].eql? false
      mail.to = (recipients&bounced).uniq.join(",")
      mail.cc = (mail.cc_addrs&bounced).uniq.join(",")
      mail.bcc = (mail.bcc_addrs&bounced).uniq.join(",")
      record = BouncedEmail.new({
        :sender => sender,
        :recipients => (recipients&bounced).uniq.join(","),
        :subject => mail.subject,
        :body => mail.body.decoded,
        :system => mail['X-Sender-System']||"Unknown",
        :created_at => Time.now,
        :updated_at => Time.now
      })
      record.save!
    end
  end
end

#receive_plain_auth(user, password) ⇒ Object



29
30
31
# File 'lib/ses_proxy/smtp_server.rb', line 29

def receive_plain_auth(user, password)
  @verified = SesProxy::Conf.get[:smtp_auth][:user].eql?(user) and SesProxy::Conf.get[:smtp_auth][:password].eql?(password)
end

#receive_recipient(recipient) ⇒ Object



47
48
49
50
# File 'lib/ses_proxy/smtp_server.rb', line 47

def receive_recipient(recipient)
  recipients << recipient.gsub(/[<>]/,'')
  true
end

#receive_sender(sender) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/ses_proxy/smtp_server.rb', line 33

def receive_sender(sender)
  sender = sender.gsub(/[<>]/,'')
  @sender = sender
  domains = ses.identities.domains.map(&:identity)
  email_addresses = ses.identities.email_addresses.map(&:identity)
  identity = nil
  if email_addresses.include?(sender)
    identity = ses.identities[sender]
  elsif domains.include?(sender.split('@').last)
    identity = ses.identities[sender.split('@').last]
  end
  identity&&identity.verified?
end

#recipientsObject



57
58
59
# File 'lib/ses_proxy/smtp_server.rb', line 57

def recipients
  @recipients ||= []
end

#senderObject



61
62
63
# File 'lib/ses_proxy/smtp_server.rb', line 61

def sender
  @sender || ""
end

#sesObject



73
74
75
# File 'lib/ses_proxy/smtp_server.rb', line 73

def ses
  @ses ||= AWS::SimpleEmailService.new(SesProxy::Conf.get[:aws])
end

#verifiedObject



69
70
71
# File 'lib/ses_proxy/smtp_server.rb', line 69

def verified
  @verified || false
end