eventmachine-email_server 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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