eventmachine-email_server 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a217dda0576da20c2bace6cd1320f6bc6662a052
4
- data.tar.gz: cf0f814c5b56a830300d89daeff7e43a457017bd
3
+ metadata.gz: 21e73cc7eef3bcb21a34c103138939f1f9f216cf
4
+ data.tar.gz: 03f42527251cde1a286b920f1ee50c84a1318596
5
5
  SHA512:
6
- metadata.gz: 03eb0a117e26b162c41b5a9068687d4224ca7fe39b97378004aab43f81aeb2551b3ee49bd97f346491470fc5c6ef27b0d8133052e5c28e3fa1c8a5a1208eb0a4
7
- data.tar.gz: 6c091d1cc691535298fd2f296ac493a46cd3dacbd968a95080ea34ed25aeecb5ecc6804dc2ac836bd39c17524243ce55154dd5899a1cfb57122c9231388f9573
6
+ metadata.gz: 59518897af038bd1fb86ff14cda06f4ec6cd3c4363b2730af532611d8aab3c16123be073973aa08a253dd7c271112efcb613e70aeabed5bd5112f07ce6d86725
7
+ data.tar.gz: 40f009d49032f6bba06e0a7b4ba215530c788687f648e49e4e1d89f1075a9d60649ef56d62b35262f09852850dab56c46d6ef5a7284c44948ef8873bf9bbf6ec
@@ -19,7 +19,6 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_runtime_dependency "eventmachine", ">= 0.12.10"
22
- spec.add_runtime_dependency "sqlite3", ">= 1.3.6"
23
22
  spec.add_runtime_dependency "ratelimit-bucketbased", ">= 0.0.1"
24
23
  spec.add_runtime_dependency "eventmachine-dnsbl", ">= 0.0.2"
25
24
  spec.add_runtime_dependency "spf", ">= 0.0.44"
@@ -2,7 +2,6 @@ require "eventmachine/email_server/version"
2
2
  require 'eventmachine/email_server/base'
3
3
  require 'eventmachine/email_server/memory'
4
4
  require 'eventmachine/email_server/null'
5
- require 'eventmachine/email_server/sqlite3'
6
5
  require 'eventmachine/email_server/classifier'
7
6
  require 'eventmachine/email_server/pop3_server'
8
7
  require 'eventmachine/email_server/smtp_server'
@@ -188,9 +188,7 @@ module EventMachine
188
188
  def stat
189
189
  msgs = bytes = 0
190
190
  @emails.each do |e|
191
- p e
192
- p e.body.length
193
- next if e.marked
191
+ next if e.marked == 'true'
194
192
  msgs += 1
195
193
  bytes += e.body.length
196
194
  end
@@ -213,7 +211,7 @@ module EventMachine
213
211
 
214
212
  def retr(msgid)
215
213
  msgid = msgid.to_i
216
- return false if msgid > @emails.length or @emails[msgid-1].marked
214
+ return false if msgid > @emails.length or @emails[msgid-1].marked == 'true'
217
215
  @emails[msgid-1].body
218
216
  end
219
217
 
@@ -86,7 +86,7 @@ module EventMachine
86
86
  @spf_ok = true
87
87
  @reject_ok = true
88
88
  @classifier_ok = true
89
- @pending_checks = Array.new
89
+ @pending_checks = [:content]
90
90
  end
91
91
 
92
92
  def post_init
@@ -97,11 +97,7 @@ module EventMachine
97
97
  def receive_data(data)
98
98
  puts ">> #{data}" if @debug
99
99
  data.split(/\n/).each do |line|
100
- ok, op = process_line(line+"\n")
101
- if op
102
- puts "<< #{op}" if @debug
103
- send_data(op+"\r\n")
104
- end
100
+ process_line(line+"\n")
105
101
  end
106
102
  end
107
103
 
@@ -226,11 +222,16 @@ module EventMachine
226
222
  end
227
223
  if @ptr_ok and @rate_ok and @gray_ok and @reject_ok and @dnsbl_ok and @spf_ok and @classifier_ok
228
224
  ans = "250 OK"
225
+ save
229
226
  else
230
227
  ans = "451 Requested action aborted: local error in processing"
231
228
  end
232
- puts "<< #{ans}" if @debug
233
- send_data(ans+"\r\n")
229
+ send(ans)
230
+ end
231
+
232
+ def send(msg)
233
+ puts "<< #{msg}" if @debug
234
+ send_data("#{msg}\r\n")
234
235
  end
235
236
 
236
237
  def process_line(line)
@@ -238,13 +239,12 @@ module EventMachine
238
239
  @data_mode = false
239
240
  check_reject
240
241
  check_classifier
242
+ @pending_checks -= [:content]
241
243
  if @pending_checks.length == 0
242
244
  send_answer
243
245
  end
244
- return true, nil
245
246
  elsif @data_mode
246
247
  @email_body += line
247
- return true, nil
248
248
  elsif (line =~ /^(HELO|EHLO) (.*)/)
249
249
  helo = $2.chomp
250
250
  port, ip = Socket.unpack_sockaddr_in(get_peername)
@@ -252,32 +252,35 @@ module EventMachine
252
252
  check_dnsbl(ip)
253
253
  check_gray(ip)
254
254
  check_ratelimit(ip)
255
- return true, "250 hello #{ip} (#{helo})"
255
+ send("250 hello #{ip} (#{helo})")
256
256
  elsif (line =~ /^QUIT/)
257
- return false, "221 bye bye"
257
+ send("221 #{@hostname} ESMTP server closing connection")
258
+ self.close_connection
258
259
  elsif (line =~ /^MAIL FROM\:/)
259
260
  @mail_from = (/^MAIL FROM\:<(.+)>.*$/).match(line)[1]
260
261
  if @@spf_check
261
262
  port, ip = Socket.unpack_sockaddr_in(get_peername)
262
263
  check_spf(helo, ip, @mail_from)
263
264
  end
264
- return true, "250 OK"
265
+ send("250 OK")
265
266
  elsif (line =~ /^RCPT TO\:/)
266
267
  rcpt_to = (/^RCPT TO\:<(.+)>.*$/).match(line)[1]
267
268
  if @userstore.user_by_emailaddress(rcpt_to.strip)
268
269
  @rcpt_to = rcpt_to
269
- return true, "250 OK"
270
- end
271
- return false, "550 No such user here"
270
+ send("250 OK")
271
+ else
272
+ send("550 No such user here")
273
+ end
272
274
  elsif (line =~ /^DATA/)
273
275
  if @rcpt_to
274
276
  @data_mode = true
275
277
  @email_body = ''
276
- return true, "354 Enter message, ending with \".\" on a line by itself"
277
- end
278
- return true, "500 ERROR"
278
+ send("354 Enter message, ending with \".\" on a line by itself")
279
+ else
280
+ send("500 ERROR")
281
+ end
279
282
  else
280
- return true, "500 ERROR"
283
+ send("500 ERROR")
281
284
  end
282
285
  end
283
286
 
@@ -1,5 +1,5 @@
1
1
  module EventMachine
2
2
  module EmailServer
3
- VERSION = "0.0.4"
3
+ VERSION = "0.0.5"
4
4
  end
5
5
  end
@@ -12,138 +12,159 @@ require 'net/pop'
12
12
  require 'net/smtp'
13
13
  require 'ratelimit/bucketbased'
14
14
 
15
- module EventMachine
16
- module DNS
17
- class Socket < EventMachine::Connection
18
- def send_packet(pkt)
19
- send_datagram(pkt, nameserver, 53)
20
- end
21
- end
15
+ $dns_port = 53
16
+
17
+ class EventMachine::DNS::Socket < EventMachine::Connection
18
+ def send_packet(pkt)
19
+ send_datagram(pkt, nameserver, $dns_port)
22
20
  end
23
21
  end
24
22
 
23
+ class EmailTemplate < Struct.new(:from, :to, :msg); end
24
+
25
25
  class TestEmailServer < Minitest::Test
26
26
  def setup
27
27
  @test_vector = Proc.new { |test_name|
28
+ puts "***** #{test_name} *****"
28
29
  (test_name.to_s =~ /test/)
29
30
  }
31
+ @spam_email = EmailTemplate.new("friend@example.org", "chris@example.org", "From: friend@example.org
32
+ To: chris@example.org
33
+ Subject: What to do when you're not doing.
34
+
35
+ Could I interest you in some cialis?
36
+ ")
37
+ @ham_email = EmailTemplate.new("friend@example.org", "chris@example.org", "From: friend@example.org
38
+ To: chris@example.org
39
+ Subject: Good show
40
+
41
+ Have you seen the latest Peppa Pig?
42
+ ")
43
+ @default_email = EmailTemplate.new("friend@example.org", "chris@example.org", "From: friend@example.org
44
+ To: chris@example.org
45
+ Subject: Can't remember last night
46
+
47
+ Looks like we had fun!
48
+ ")
49
+ @pool = EM::Pool.new
50
+ SMTPServer.reset
30
51
  remove_scraps
31
52
  end
32
-
53
+
33
54
  def remove_scraps
34
55
  ["test.sqlite3", "email_server.sqlite3"].each do |f|
35
56
  if File.exist?("test/#{f}")
36
57
  File.unlink("test/#{f}")
37
58
  end
38
59
  end
39
- end
40
-
60
+ end
61
+
41
62
  def teardown
42
63
  remove_scraps
43
64
  end
44
-
65
+
45
66
  def setup_user(userstore)
46
67
  userstore << User.new(1, "chris", "chris", "chris@example.org")
47
68
  end
48
-
69
+
49
70
  def start_servers(userstore, emailstore)
50
71
  pop3 = EventMachine::start_server "0.0.0.0", 2110, POP3Server, "example.org", userstore, emailstore
51
72
  smtp = EventMachine::start_server "0.0.0.0", 2025, SMTPServer, "example.org", userstore, emailstore
52
- end
53
-
54
- def send_email(expected_status="250")
55
- from = "friend@example.org"
56
- to = "chris@example.org"
57
- msg = "From: friend@example.org
58
- To: chris@example.org
59
- Subject: Can't remember last night
73
+ end
60
74
 
61
- Looks like we had fun!
62
- "
63
- Thread.new do
64
- smtp = Net::SMTP.start('localhost', 2025)
65
- ret = smtp.send_message msg, from, to
66
- assert_equal(expected_status, ret.status)
75
+
76
+ def send_email(email=@default_email, &callback)
77
+ smtp_dispatcher = EventMachine::ThreadedResource.new do
78
+ smtp = Net::SMTP.new('localhost', 2025)
67
79
  end
68
- end
69
-
70
- def send_spam(expected_status="451")
71
- from = "friend@example.org"
72
- to = "chris@example.org"
73
- msg = "From: friend@example.org
74
- To: chris@example.org
75
- Subject: What to do when you're not doing.
76
80
 
77
- Could I interest you in some cialis?
78
- "
79
- Thread.new do
80
- smtp = Net::SMTP.start('localhost', 2025)
81
- ret = smtp.send_message msg, from, to
82
- assert_equal(expected_status, ret.status)
81
+ @pool.add smtp_dispatcher
82
+
83
+ @pool.perform do |dispatcher|
84
+ completion = dispatcher.dispatch do |smtp|
85
+ ret = nil
86
+ smtp.start do |s|
87
+ begin
88
+ ret = s.send_message email.msg, email.from, email.to
89
+ rescue => e
90
+ ret = "451"
91
+ end
92
+ begin
93
+ smtp.quit
94
+ rescue => e
95
+ end
96
+ end
97
+ if ret.respond_to? :status
98
+ ret = ret.status
99
+ end
100
+ ret
101
+ end
102
+
103
+ completion.callback do |result|
104
+ callback.call(result)
105
+ end
106
+
107
+ completion
83
108
  end
84
- end
85
-
86
- def send_ham(expected_status="250")
87
- from = "friend@example.org"
88
- to = "chris@example.org"
89
- msg = "From: friend@example.org
90
- To: chris@example.org
91
- Subject: Good show
109
+ end
92
110
 
93
- Have you seen the latest Peppa Pig?
94
- "
95
- Thread.new do
96
- smtp = Net::SMTP.start('localhost', 2025)
97
- ret = smtp.send_message msg, from, to
98
- assert_equal(expected_status, ret.status)
111
+ def pop_email(&callback)
112
+
113
+ pop3_dispatcher = EventMachine::ThreadedResource.new do
99
114
  end
100
- end
101
-
102
- def pop_some_email
103
- Thread.new do
104
- pop = Net::POP3.APOP(true).new('localhost',2110)
105
- pop.start("chris","chris")
106
- refute(pop.mails.empty?)
107
- pop.each_mail do |m|
108
- assert_equal("From: friend@example.org
109
- To: chris@example.org
110
- Subject: Can't remember last night
111
115
 
112
- Looks like we had fun!
113
- ", m.mail)
114
- m.delete
116
+ @pool.add pop3_dispatcher
117
+
118
+ @pool.perform do |dispatcher|
119
+ completion = dispatcher.dispatch do |pop|
120
+ pop = Net::POP3.APOP(true).new('localhost',2110)
121
+ pop.start("chris","chris")
122
+ answers = Array.new
123
+ answers << pop.mails.empty?
124
+ if not pop.mails.empty?
125
+ pop.each_mail do |m|
126
+ answers << m.mail
127
+ m.delete
128
+ end
129
+ end
130
+ pop.finish
131
+ answers
115
132
  end
116
- end
117
- end
118
133
 
119
- def pop_no_email
120
- Thread.new do
121
- pop = Net::POP3.APOP(true).new('localhost',2110)
122
- pop.start("chris","chris")
123
- assert(pop.mails.empty?)
134
+ completion.callback do |answers|
135
+ callback.call(answers)
136
+ end
137
+
138
+ completion
124
139
  end
125
- end
140
+ end
126
141
 
127
142
  def run_test(userstore, emailstore)
128
143
  EM.run {
129
144
  start_servers(userstore, emailstore)
130
- timer = EventMachine::Timer.new(0.1) do
131
- send_email
132
- end
133
- timer2 = EventMachine::Timer.new(0.2) do
134
- pop_some_email
135
- end
136
-
137
- timer3 = EventMachine::Timer.new(0.3) do
138
- pop_no_email
139
- end
140
-
141
- timer4 = EventMachine::Timer.new(0.4) do
145
+ EM::Timer.new(10) do
146
+ fail "Test timed out"
142
147
  EM.stop
143
148
  end
144
- }
149
+ EM::Timer.new(0.1) do
150
+ pop_email do |answers|
151
+ assert_equal(true, answers[0])
152
+ send_email do |result|
153
+ assert_equal("250", result)
154
+ pop_email do |answers|
155
+ assert_equal(false, answers[0])
156
+ assert_equal(@default_email.msg.gsub(/[\r\n]+/,"\n"), answers[1].gsub(/[\r\n]+/,"\n"))
157
+ pop_email do |answers|
158
+ assert_equal(true, answers[0])
159
+ EM.stop
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
165
+ }
145
166
  end
146
-
167
+
147
168
  def test_memory_store
148
169
  return unless @test_vector.call(__method__)
149
170
  userstore = MemoryUserStore.new
@@ -152,18 +173,8 @@ Looks like we had fun!
152
173
  run_test(userstore, emailstore)
153
174
  end
154
175
 
155
- def test_sqlite3_store
156
- return unless @test_vector.call(__method__)
157
- s = SQLite3::Database.new("test/test.sqlite3")
158
- userstore = Sqlite3UserStore.new(s)
159
- emailstore = Sqlite3EmailStore.new(s)
160
- setup_user(userstore)
161
- run_test(userstore, emailstore)
162
- end
163
-
164
176
  def test_graylisting
165
177
  return unless @test_vector.call(__method__)
166
- SMTPServer.reset
167
178
  SMTPServer.graylist(Hash.new)
168
179
  userstore = MemoryUserStore.new
169
180
  emailstore = MemoryEmailStore.new
@@ -171,20 +182,23 @@ Looks like we had fun!
171
182
 
172
183
  EM.run {
173
184
  smtp = EventMachine::start_server "0.0.0.0", 2025, SMTPServer, "example.org", userstore, emailstore
174
-
175
- timer = EventMachine::Timer.new(0.1) do
176
- send_email("451")
177
- end
178
- timer2 = EventMachine::Timer.new(0.2) do
179
- send_email
180
- end
181
- timer3 = EventMachine::Timer.new(0.3) do
185
+ EM::Timer.new(10) do
186
+ fail "Test timed out"
182
187
  EM.stop
183
188
  end
184
-
189
+
190
+ timer = EventMachine::Timer.new(0.1) do
191
+ send_email do |result|
192
+ assert_equal("451", result)
193
+ send_email do |result|
194
+ assert_equal("250", result)
195
+ EM.stop
196
+ end
197
+ end
198
+ end
185
199
  }
186
200
  end
187
-
201
+
188
202
  def test_ratelimit
189
203
  return unless @test_vector.call(__method__)
190
204
  config = {
@@ -192,7 +206,6 @@ Looks like we had fun!
192
206
  }
193
207
  storage = RateLimit::Memory.new
194
208
  rl = RateLimit::BucketBased.new(storage, config, 'default')
195
- SMTPServer.reset
196
209
  SMTPServer.ratelimiter(rl)
197
210
  userstore = MemoryUserStore.new
198
211
  emailstore = MemoryEmailStore.new
@@ -200,21 +213,26 @@ Looks like we had fun!
200
213
 
201
214
  EM.run {
202
215
  smtp = EventMachine::start_server "0.0.0.0", 2025, SMTPServer, "example.org", userstore, emailstore
203
-
216
+
217
+ EM::Timer.new(10) do
218
+ fail "Test timed out"
219
+ EM.stop
220
+ end
204
221
  timer = EventMachine::Timer.new(0.1) do
205
- Thread.new do
206
- 2.times do
207
- send_email
222
+ send_email do |result|
223
+ assert_equal("250", result)
224
+ send_email do |result|
225
+ assert_equal("250", result)
226
+ send_email do |result|
227
+ assert_equal("451", result)
228
+ EM.stop
229
+ end
208
230
  end
209
- send_email("451")
210
231
  end
211
232
  end
212
- timer2 = EventMachine::Timer.new(0.3) do
213
- EM.stop
214
- end
215
233
  }
216
234
  end
217
-
235
+
218
236
  def test_reject_list
219
237
  return unless @test_vector.call(__method__)
220
238
  userstore = MemoryUserStore.new
@@ -223,25 +241,29 @@ Looks like we had fun!
223
241
 
224
242
  EM.run {
225
243
  smtp = EventMachine::start_server "0.0.0.0", 2025, SMTPServer, "example.org", userstore, emailstore
226
-
244
+
245
+ EM::Timer.new(10) do
246
+ fail "Test timed out"
247
+ EM.stop
248
+ end
227
249
  timer = EventMachine::Timer.new(0.1) do
228
- Thread.new do
229
- send_email
250
+ send_email do |result|
251
+ assert_equal("250", result)
230
252
  SMTPServer.reject_filters << /remember/
253
+ send_email do |result|
254
+ assert_equal("451", result)
255
+ EM.stop
256
+ end
231
257
  end
232
258
  end
233
- timer2 = EventMachine::Timer.new(0.2) do
234
- send_email("451")
235
- end
236
- timer3 = EventMachine::Timer.new(0.3) do
237
- EM.stop
238
- end
239
-
240
259
  }
241
260
  end
242
-
261
+
243
262
  def test_dnsbl
244
263
  return unless @test_vector.call(__method__)
264
+
265
+ $dns_port = 2053
266
+
245
267
  #Monkeypatching for testing
246
268
  memzone = EventMachine::DNSBL::Zone::MemoryZone.new
247
269
  EM::DNS::Resolver.nameservers = ["127.0.0.1"]
@@ -252,9 +274,8 @@ Looks like we had fun!
252
274
  "127.0.0.2" => "Blacklisted as an example"
253
275
  }
254
276
  })
255
- SMTPServer.reset
256
277
  SMTPServer.dnsbl_check(true)
257
-
278
+
258
279
  userstore = MemoryUserStore.new
259
280
  emailstore = MemoryEmailStore.new
260
281
  setup_user(userstore)
@@ -262,106 +283,110 @@ Looks like we had fun!
262
283
  EM.run {
263
284
  EM::open_datagram_socket "0.0.0.0", 2053, EventMachine::DNSBL::Server, memzone
264
285
  smtp = EventMachine::start_server "0.0.0.0", 2025, SMTPServer, "example.org", userstore, emailstore
265
- timer = EventMachine::Timer.new(0.1) do
266
- send_email
286
+ EM::Timer.new(10) do
287
+ fail "Test timed out"
288
+ EM.stop
267
289
  end
268
-
269
- timer2 = EventMachine::Timer.new(1.2) do
270
- memzone.add_dnsblresource(
271
- EventMachine::DNSBL::Zone::DNSBLResourceRecord.new(
272
- "example.com",
273
- /\d+\.0\.0\.127$/,
274
- 300,
275
- Resolv::DNS::Resource::IN::A.new("127.0.0.4"),
276
- Time.now.to_i + 3600
290
+ timer = EventMachine::Timer.new(0.1) do
291
+ send_email do |result|
292
+ assert_equal("250", result)
293
+ memzone.add_dnsblresource(
294
+ EventMachine::DNSBL::Zone::DNSBLResourceRecord.new(
295
+ "example.com",
296
+ /\d+\.0\.0\.127$/,
297
+ 300,
298
+ Resolv::DNS::Resource::IN::A.new("127.0.0.4"),
299
+ Time.now.to_i + 3600
300
+ )
277
301
  )
278
- )
279
- Thread.new do
280
- send_email("451")
302
+ send_email do |result|
303
+ assert_equal("451", result)
304
+ EM.stop
305
+ end
281
306
  end
282
307
  end
283
-
284
- timer3 = EventMachine::Timer.new(3.0) do
285
- EM.stop
286
- end
287
-
288
308
  }
289
309
  end
290
-
310
+
291
311
  def test_spf
292
312
  return unless @test_vector.call(__method__)
293
313
  userstore = MemoryUserStore.new
294
314
  emailstore = MemoryEmailStore.new
295
315
  setup_user(userstore)
296
-
297
- SMTPServer.reset
316
+ $dns_port = 53
317
+
298
318
  SMTPServer.spf_check(true)
299
319
  EM.run {
300
320
  smtp = EventMachine::start_server "0.0.0.0", 2025, SMTPServer, "example.org", userstore, emailstore
301
- timer = EventMachine::Timer.new(0.1) do
302
- send_email("451")
303
- end
304
- timer2 = EventMachine::Timer.new(1) do
321
+ EM::Timer.new(10) do
322
+ fail "Test timed out"
305
323
  EM.stop
306
324
  end
325
+ timer = EventMachine::Timer.new(0.1) do
326
+ send_email do |result|
327
+ assert_equal("451", result)
328
+ EM.stop
329
+ end
330
+ end
307
331
  }
308
-
309
332
  end
310
-
333
+
311
334
  def test_classifier
312
335
  return unless @test_vector.call(__method__)
313
336
  userstore = MemoryUserStore.new
314
337
  emailstore = MemoryEmailStore.new
315
338
  setup_user(userstore)
316
- SMTPServer.reset
317
339
  classifier = EventMachine::EmailServer::Classifier.new("test/test.classifier", [:spam, :ham], [:spam])
318
340
  classifier.train(:spam, "Amazing pillz viagra cialis levitra staxyn")
319
341
  classifier.train(:ham, "Big pigs make great bacon")
320
342
  SMTPServer.classifier(classifier)
321
343
  EM.run {
322
344
  smtp = EventMachine::start_server "0.0.0.0", 2025, SMTPServer, "example.org", userstore, emailstore
323
- timer = EventMachine::Timer.new(0.1) do
324
- send_spam("451")
325
- send_ham("250")
326
- end
327
- timer2 = EventMachine::Timer.new(1) do
345
+ EM::Timer.new(10) do
346
+ fail "Test timed out"
328
347
  EM.stop
329
348
  end
349
+ timer = EventMachine::Timer.new(0.1) do
350
+ send_email(@spam_email) do |result|
351
+ assert_equal("451", result)
352
+ send_email(@ham_email) do |result|
353
+ assert_equal("250", result)
354
+ EM.stop
355
+ end
356
+ end
357
+ end
330
358
  }
331
359
  end
332
-
360
+
333
361
  def test_example
334
362
  return unless @test_vector.call(__method__)
335
363
  #require 'eventmachine/email_server'
336
364
  #include EventMachine::EmailServer
337
365
  #require 'ratelimit/bucketbased'
338
366
  #require 'dnsbl/client'
339
-
340
- #require 'sqlite3'
341
- s = SQLite3::Database.new("email_server.sqlite3")
342
- userstore = Sqlite3UserStore.new(s)
343
- emailstore = Sqlite3EmailStore.new(s)
367
+
368
+ userstore = MemoryUserStore.new()
369
+ emailstore = MemoryEmailStore.new()
344
370
  userstore << User.new(1, "chris", "chris", "chris@example.org")
345
-
371
+
346
372
  config = {
347
373
  'default' => RateLimit::Config.new('default', 2, 2, -2, 1, 1, 1),
348
374
  }
349
375
  storage = RateLimit::Memory.new
350
376
  rl = RateLimit::BucketBased.new(storage, config, 'default')
351
-
377
+
352
378
  classifier = EventMachine::EmailServer::Classifier.new("test/test.classifier", [:spam, :ham], [:spam])
353
379
  classifier.train(:spam, "Amazing pillz viagra cialis levitra staxyn")
354
380
  classifier.train(:ham, "Big pigs make great bacon")
355
-
356
- SMTPServer.reset
381
+
357
382
  SMTPServer.reverse_ptr_check(true)
358
383
  SMTPServer.graylist(Hash.new)
359
384
  SMTPServer.ratelimiter(rl)
360
- SMTPServer.dnsbl_check(true)
385
+ SMTPServer.dnsbl_check(true)
361
386
  SMTPServer.spf_check(true)
362
387
  SMTPServer.reject_filters << /viagra/i
363
388
  SMTPServer.classifier(classifier)
364
-
389
+
365
390
  EM.run {
366
391
  pop3 = EventMachine::start_server "0.0.0.0", 2110, POP3Server, "example.org", userstore, emailstore
367
392
  smtp = EventMachine::start_server "0.0.0.0", 2025, SMTPServer, "example.org", userstore, emailstore
@@ -370,5 +395,5 @@ Looks like we had fun!
370
395
  end
371
396
  }
372
397
  end
373
-
398
+
374
399
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eventmachine-email_server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - chrislee35
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-09 00:00:00.000000000 Z
11
+ date: 2015-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: eventmachine
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.12.10
27
- - !ruby/object:Gem::Dependency
28
- name: sqlite3
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 1.3.6
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: 1.3.6
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: ratelimit-bucketbased
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -191,7 +177,6 @@ files:
191
177
  - LICENSE.txt
192
178
  - README.md
193
179
  - Rakefile
194
- - email_server.sqlite3
195
180
  - eventmachine-email_server.gemspec
196
181
  - lib/eventmachine/email_server.rb
197
182
  - lib/eventmachine/email_server/base.rb
@@ -201,7 +186,6 @@ files:
201
186
  - lib/eventmachine/email_server/null.rb
202
187
  - lib/eventmachine/email_server/pop3_server.rb
203
188
  - lib/eventmachine/email_server/smtp_server.rb
204
- - lib/eventmachine/email_server/sqlite3.rb
205
189
  - lib/eventmachine/email_server/version.rb
206
190
  - test/helper.rb
207
191
  - test/test_email_server.rb
data/email_server.sqlite3 DELETED
Binary file
@@ -1,153 +0,0 @@
1
- require_relative 'base'
2
- require 'sqlite3'
3
-
4
- module EventMachine
5
- module EmailServer
6
- class Sqlite3UserStore < AbstractUserStore
7
- def initialize(sqlite3, tablename = "users")
8
- @class = User
9
- @fields = @class.members.map {|x| x.to_s}.join(", ")
10
- @tablename = tablename
11
- if sqlite3.class == SQLite3::Database
12
- @db = sqlite3
13
- else
14
- @db = SQLite3::Database.new(sqlite3)
15
- end
16
- if @db.table_info(tablename).length == 0
17
- @db.execute("CREATE TABLE #{@tablename} (#{@fields})")
18
- end
19
- end
20
-
21
- def add_user(user)
22
- if user.id
23
- u = user_by_id(user.id)
24
- end
25
- if u
26
- @db.execute("UPDATE #{@tablename} SET username=?, password=?, address=? WHERE id=?",
27
- user.username,
28
- user.password,
29
- user.address,
30
- user.id)
31
- else
32
- @db.execute("INSERT INTO #{@tablename} (id,username,password,address) VALUES (?,?,?,?)",
33
- user.id,
34
- user.username,
35
- user.password,
36
- user.address)
37
- end
38
- end
39
-
40
- def delete_user(user)
41
- if user.id
42
- @db.execute("DELETE FROM #{@tablename} WHERE id = ?", user.id)
43
- end
44
- end
45
-
46
- def user_by_field(field, value)
47
- rs = @db.execute("SELECT #{@fields} FROM #{@tablename} WHERE #{field}='#{value}'")
48
- return nil unless rs
49
- rs.each do |row|
50
- return User.new(*row)
51
- end
52
- return nil
53
- end
54
-
55
- def user_by_username(username)
56
- user_by_field("username", username)
57
- end
58
-
59
- def user_by_emailaddress(address)
60
- user_by_field("address", address)
61
- end
62
-
63
- def user_by_id(id)
64
- user_by_field("id", id)
65
- end
66
- end
67
-
68
- class Sqlite3EmailStore < AbstractEmailStore
69
- def initialize(sqlite3, tablename = "emails")
70
- @class = Email
71
- @fields = "'"+@class.members.map {|x| x.to_s}.join("', '")+"'"
72
- @tablename = tablename
73
- if sqlite3.class == SQLite3::Database
74
- @db = sqlite3
75
- else
76
- @db = SQLite3::Database.new(sqlite3)
77
- end
78
- if @db.table_info(tablename).length == 0
79
- fields = @fields.gsub(/'id'/, 'id integer primary key autoincrement')
80
- @db.execute("CREATE TABLE #{@tablename} (#{fields})")
81
- end
82
- end
83
-
84
- def emails_by_field(field, value)
85
- rs = @db.execute("SELECT #{@fields} FROM #{@tablename} WHERE ?=?", field, value)
86
- return nil unless rs
87
- emails = Array.new
88
- rs.each do |row|
89
- emails << Email.new(*row)
90
- end
91
- emails
92
- end
93
-
94
- def emails_by_userid(uid)
95
- emails_by_field("uid", uid)
96
- end
97
-
98
- def quote( string )
99
- string.gsub( /'/, "''" )
100
- end
101
- private :quote
102
-
103
- def save_email(email)
104
- if email.id
105
- # I'm being too crafty here.. this is bad style
106
- args = (@class.members - [:id]).map{|f| email.send(f)}
107
- args << email.send(:id)
108
- @db.execute("UPDATE #{@tablename} SET " +
109
- (@class.members - [:id]).map { |field| "#{field} = ?"}.join(", ") +
110
- " WHERE id = ?", *args)
111
- else
112
- email.id = "NULL"
113
- args = (@class.members).map{|f| email.send(f)}
114
- qs = args.map{|x| "'#{quote(x.to_s)}'"}.join(",").gsub(/'NULL'/, "NULL")
115
- @db.execute("INSERT INTO #{@tablename} (#{@fields}) VALUES (#{qs})")
116
- rs = @db.execute("SELECT last_insert_rowid()")
117
- rs.each do |row|
118
- email.id = *row
119
- end
120
- end
121
- email.id
122
- end
123
-
124
- def delete_email(email)
125
- if email.id
126
- @db.execute("DROP FROM #{@tablename} WHERE id = ?", email.id)
127
- end
128
- end
129
-
130
- def delete_by_field(field, value)
131
- @db.execute("DROP FROM #{@tablename} WHERE #{field} = ?", value)
132
- end
133
-
134
- def delete_id(id)
135
- delete_by_field("id", id)
136
- end
137
-
138
- def delete_user(uid)
139
- delete_by_field("uid", uid)
140
- end
141
-
142
- def count
143
- sql = "SELECT COUNT(*) FROM #{@tablename}"
144
- rs = @db.execute(sql)
145
- c = 0
146
- rs.each do |row|
147
- c = row[0]
148
- end
149
- c
150
- end
151
- end
152
- end
153
- end