post_office 0.3.0 → 1.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ce85b02dd82bd4acd4fe34c5bf0c56f9b343ad7480a1c2e3ac429146e9b77e44
4
+ data.tar.gz: c032ebc0fedff67be24fb010b77f1f9d7144354329d333c707e2ad5a51b0bfd5
5
+ SHA512:
6
+ metadata.gz: 0a870109cf0a649ab8c0a5f4713532b0060e97a4e9002c6a8a8cf30ebbf6be002cb59418f79a7ef4f5e0c823d5a1d8fe9fa7d7cf8b53476d036e86ffdafdbbdd
7
+ data.tar.gz: 7374e542844b2abfd968e12f9d339a4bc28138a8e4f82bd4407d22797d2f7cb6fc7bd7c11fe1e78c355e8672cb9c3a22f000ce9744b45a4fe260d7825b396461
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2011-2013 LICO Innovations
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,13 +1,6 @@
1
1
  PostOffice mock SMTP/POP3 server
2
2
  ================================
3
3
 
4
- https://github.com/bluerail/post_office
5
-
6
- By Rene van Lieshout <rene@bluerail.nl>
7
-
8
- Description
9
- -----------
10
-
11
4
  PostOffice is a mock SMTP/POP3 server to accept mails sent from your Rails application when it's running in development. The messages can be retrieved using a standard POP3 client, such as mail.app. Just connect to localhost with any username and password.
12
5
 
13
6
  Note: Received messages are **not** sent to their final recipient and will remain available until deleted or when the process is quit.
@@ -21,12 +14,22 @@ Usage
21
14
  -----
22
15
 
23
16
  sudo post_office [options]
24
-
17
+
25
18
  -v, --verbose Output more information
26
19
  -l, --logfile FILE Write log to FILE. Outputs to STDOUT (or /var/log/post_office.log when daemonized) by default.
20
+ -s, --smtp PORT Specify SMTP port to use
21
+ -p, --pop3 PORT Specify POP3 port to use
22
+
27
23
  -h, --help Display this screen
28
24
 
29
- This starts the service and listens on port 25 and 110. Configure your POP3 client with any username and password.
25
+ This starts the service and listens on the specified ports (or 25 for SMTP and 110 for POP3 by default). Configure your POP3 client with any username and password.
26
+
27
+ Config
28
+ ------
29
+
30
+ Post Office will try to find a configuration file (post_office/config.json) in the user dir ($HOME), and then in /etc. It will load the first one it finds.
31
+
32
+ The arguments passed on the command line will always override the ones specified in the config file.
30
33
 
31
34
  Daemon
32
35
  ------
@@ -69,8 +72,30 @@ The Startup Item is stored in */Library/StartupItems/PostOffice*
69
72
  Planned features
70
73
  ----------------
71
74
 
72
- * Ability to use custom ports for SMTP and POP
73
- * Growl notifications
74
75
  * Store mail in tempfiles instead of in-memory array
75
76
 
76
77
  Contributions are welcome! Feel free to fork and send a pull request through Github.
78
+
79
+ ## Changelog
80
+
81
+ ### 1.0.1 (Jan 17, 2022)
82
+
83
+ * [(snoutmate)](https://github.com/snoutmate) [Added SMTP AUTH support](https://github.com/bluerail/post_office/pull/7)
84
+
85
+ ### 1.0.0 (Aug 11, 2016)
86
+
87
+ * [(tijn)](https://github.com/tijn) [load a config file and move default options (to become more DRY)](https://github.com/bluerail/post_office/pull/5)
88
+ * [(gamecreature)](https://github.com/gamecreature) [NOOP smtp command support](https://github.com/bluerail/post_office/pull/4)
89
+ * [(martijn)](https://github.com/martijn) Shorten timestamp in logs
90
+
91
+ ### 0.3.3 (Sep 13, 2011)
92
+
93
+ * [(sgeorgi)](https://github.com/sgeorgi) [Specifying SMTP and POP3 ports on the command line](https://github.com/bluerail/post_office/pull/2)
94
+
95
+ ### 0.3.2 (Sep 13, 2011)
96
+
97
+ Broken build
98
+
99
+ ### 0.3.1 (Aug 16, 2011)
100
+
101
+ * First 'official' release
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 1.0.1
data/bin/post_office CHANGED
@@ -6,29 +6,41 @@ require 'logger'
6
6
  require 'thread'
7
7
  require 'smtp_server.rb'
8
8
  require 'pop_server.rb'
9
+ require 'config_file.rb'
10
+
11
+ options = ConfigFile.detect.read
9
12
 
10
13
  #
11
14
  # Parse command line arguments
12
15
  #
13
- options = {}
14
-
15
16
  optparse = OptionParser.new do |opts|
16
17
  opts.banner = "Usage: #{__FILE__} [options]"
17
18
 
18
- options[:verbose] = false
19
+ options[:verbose] ||= false
19
20
  opts.on( '-v', '--verbose', 'Output more information' ) do
20
21
  options[:verbose] = true
21
22
  end
22
23
 
23
- options[:logfile] = nil
24
+ options[:logfile] ||= nil
24
25
  opts.on( '-l', '--logfile FILE', 'Write log to FILE. Outputs to STDOUT (or /var/log/post_office.log when daemonized) by default.' ) do |file|
25
26
  options[:logfile] = file
26
27
  end
27
-
28
+
29
+ options[:smtp_port] ||= 25
30
+ opts.on( '-s', '--smtp PORT', 'Specify SMTP port to use' ) do |port|
31
+ options[:smtp_port] = port
32
+ end
33
+
34
+ options[:pop3_port] ||= 110
35
+ opts.on( '-p', '--pop3 PORT', 'Specify POP3 port to use' ) do |port|
36
+ options[:pop3_port] = port
37
+ end
38
+
28
39
  options[:startup_item] = nil
29
40
  opts.on('--install-osx-startup-item', 'Installs Post Office as OS X Startup Item') do
30
41
  options[:startup_item] = :install
31
42
  end
43
+
32
44
  opts.on('--remove-osx-startup-item', 'Removes Post Office as OS X Startup Item') do
33
45
  options[:startup_item] = :remove
34
46
  end
@@ -58,15 +70,17 @@ end
58
70
  #
59
71
  $log = Logger.new(options[:logfile] || STDOUT)
60
72
  $log.level = options[:verbose] ? Logger::DEBUG : Logger::INFO
73
+ $log.datetime_format = "%H:%M:%S"
61
74
 
62
75
  begin
63
- smtp_server = Thread.new{ SMTPServer.new }
64
- pop_server = Thread.new{ POPServer.new }
76
+ smtp_server = Thread.new{ SMTPServer.new(options[:smtp_port]) }
77
+ pop_server = Thread.new{ POPServer.new(options[:pop3_port]) }
65
78
 
66
79
  smtp_server.join
67
80
  pop_server.join
68
81
  rescue Interrupt
69
82
  $log.info "Interrupt..."
70
83
  rescue Errno::EACCES
71
- $log.error "I need root access to open ports 25 and 110. Please sudo #{__FILE__}"
84
+ $log.error "I need root access to open ports #{options[:smtp_port]} and / or #{options[:pop3_port]}. Please sudo #{__FILE__}"
72
85
  end
86
+
@@ -0,0 +1,24 @@
1
+ require 'json'
2
+
3
+ class ConfigFile
4
+ USER_CONFIG_DIR = ENV.fetch('XDG_CONFIG_HOME', ENV['HOME'] + '/.config')
5
+ SYSTEM_CONFIG_DIR = '/etc'
6
+ CONFIG_DIRS = [USER_CONFIG_DIR, SYSTEM_CONFIG_DIR]
7
+ attr_reader :filename
8
+
9
+ def initialize(filename)
10
+ @filename = filename
11
+ end
12
+
13
+ def self.detect
14
+ filename =
15
+ CONFIG_DIRS.map { |dir| "#{dir}/post_office/config.json" }
16
+ .detect { |file| File.exist? file }
17
+ new(filename)
18
+ end
19
+
20
+ def read
21
+ return {} if @filename.nil?
22
+ JSON.parse(File.read(@filename), symbolize_names: true)
23
+ end
24
+ end
@@ -26,7 +26,14 @@ class GenericServer
26
26
  @port = options[:port]
27
27
  server = TCPServer.open(@port)
28
28
  $log.info "#{self.class.to_s} listening on port #{@port}"
29
-
29
+
30
+ # Try to increase the buffer to give us some more time to parse incoming data
31
+ begin
32
+ server.setsockopt(Socket::SOL_SOCKET, Socket::SO_RCVBUF, 1024 * 1024)
33
+ rescue
34
+ # then try it using our available buffer
35
+ end
36
+
30
37
  # Accept connections until infinity and beyond
31
38
  loop do
32
39
  Thread.start(server.accept) do |client|
@@ -45,6 +52,7 @@ class GenericServer
45
52
  $log.debug "#{client.object_id}:#{@port} < #{input}"
46
53
 
47
54
  process(client, command, input)
55
+
48
56
  end until client.closed?
49
57
  $log.info "#{self.class.to_s} closed connection #{client.object_id} with #{client_addr.inspect}"
50
58
  rescue => detail
data/lib/pop_server.rb CHANGED
@@ -6,8 +6,8 @@ require 'digest/md5'
6
6
 
7
7
  class POPServer < GenericServer
8
8
  # Create new server listening on port 110
9
- def initialize
10
- super(:port => 110)
9
+ def initialize(port)
10
+ super(:port => port)
11
11
  end
12
12
 
13
13
  # Send a greeting to client
data/lib/smtp_server.rb CHANGED
@@ -7,9 +7,9 @@ class SMTPServer < GenericServer
7
7
  attr_accessor :client_data
8
8
 
9
9
  # Create new server listening on port 25
10
- def initialize
10
+ def initialize(port)
11
11
  self.client_data = Hash.new
12
- super(:port => 25)
12
+ super(:port => port)
13
13
  end
14
14
 
15
15
  # Send a greeting to client
@@ -22,10 +22,12 @@ class SMTPServer < GenericServer
22
22
  case command
23
23
  when 'DATA' then data(client)
24
24
  when 'HELO', 'EHLO' then respond(client, 250)
25
+ when 'NOOP' then respond(client, 250)
25
26
  when 'MAIL' then mail_from(client, full_data)
26
27
  when 'QUIT' then quit(client)
27
28
  when 'RCPT' then rcpt_to(client, full_data)
28
29
  when 'RSET' then rset(client)
30
+ when 'AUTH' then auth(client)
29
31
  else begin
30
32
  if get_client_data(client, :sending_data)
31
33
  append_data(client, full_data)
@@ -65,6 +67,7 @@ class SMTPServer < GenericServer
65
67
  # Markes client sending data
66
68
  def data(client)
67
69
  set_client_data(client, :sending_data, true)
70
+ set_client_data(client, :data, "")
68
71
  respond(client, 354)
69
72
  end
70
73
 
@@ -73,6 +76,11 @@ class SMTPServer < GenericServer
73
76
  self.client_data[client.object_id] = Hash.new
74
77
  end
75
78
 
79
+ # Authenticates client
80
+ def auth(client)
81
+ respond(client, 235)
82
+ end
83
+
76
84
  # Adds full_data to incoming mail message
77
85
  #
78
86
  # We'll store the mail when full_data == "."
@@ -86,7 +94,7 @@ class SMTPServer < GenericServer
86
94
  respond(client, 250)
87
95
  $log.info "Received mail from #{get_client_data(client, :from).to_s} with recipient #{get_client_data(client, :to).to_s}"
88
96
  else
89
- set_client_data(client, :data, get_client_data(client, :data).to_s + full_data)
97
+ self.client_data[client.object_id][:data] << full_data
90
98
  end
91
99
  end
92
100
 
@@ -119,6 +127,7 @@ class SMTPServer < GenericServer
119
127
  214 => "Help message",
120
128
  220 => "Bluerail Post Office Service ready",
121
129
  221 => "Bluerail Post Office Service closing transmission channel",
130
+ 235 => "Authentication successful",
122
131
  421 => "Bluerail Post Office Service not available,",
123
132
  250 => "Requested mail action okay, completed",
124
133
  251 => "User not local; will forward to <forward-path>",
data/post_office.gemspec CHANGED
@@ -2,47 +2,42 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
+ # stub: post_office 1.0.1 ruby lib
5
6
 
6
7
  Gem::Specification.new do |s|
7
- s.name = %q{post_office}
8
- s.version = "0.2.1"
8
+ s.name = "post_office".freeze
9
+ s.version = "1.0.1"
9
10
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Rene van Lieshout"]
12
- s.date = %q{2011-04-19}
13
- s.description = %q{A mock SMTP/POP3 server to aid in the development of applications with mail functionality.}
14
- s.email = %q{rene@bluerail.nl}
15
- s.executables = ["post_office", "post_officed"]
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib".freeze]
13
+ s.authors = ["Rene van Lieshout".freeze]
14
+ s.date = "2022-01-17"
15
+ s.description = "A mock SMTP/POP3 server to aid in the development of applications with mail functionality.".freeze
16
+ s.email = "rene@bluerail.nl".freeze
17
+ s.executables = ["post_office".freeze, "post_officed".freeze]
16
18
  s.extra_rdoc_files = [
19
+ "LICENSE",
17
20
  "README.md"
18
21
  ]
19
22
  s.files = [
23
+ "LICENSE",
20
24
  "README.md",
21
25
  "Rakefile",
22
26
  "VERSION",
23
27
  "bin/post_office",
24
28
  "bin/post_officed",
29
+ "lib/config_file.rb",
25
30
  "lib/generic_server.rb",
26
31
  "lib/pop_server.rb",
27
32
  "lib/smtp_server.rb",
33
+ "lib/startup_item.rb",
28
34
  "lib/store.rb",
29
- "pkg/post_office-0.1.0.gem",
30
- "pkg/post_office-0.2.0.gem",
31
- "pkg/post_office-0.2.1.gem",
32
- "post_office.gemspec"
35
+ "post_office.gemspec",
36
+ "startup_item/PostOffice/PostOffice",
37
+ "startup_item/PostOffice/StartupParameters.plist"
33
38
  ]
34
- s.homepage = %q{http://github.com/bluerail/post_office}
35
- s.require_paths = ["lib"]
36
- s.rubygems_version = %q{1.5.0}
37
- s.summary = %q{PostOffice mock SMTP/POP3 server}
38
-
39
- if s.respond_to? :specification_version then
40
- s.specification_version = 3
41
-
42
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
- else
44
- end
45
- else
46
- end
39
+ s.homepage = "http://github.com/bluerail/post_office".freeze
40
+ s.rubygems_version = "3.0.9".freeze
41
+ s.summary = "PostOffice mock SMTP/POP3 server".freeze
47
42
  end
48
43
 
metadata CHANGED
@@ -1,83 +1,61 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: post_office
3
- version: !ruby/object:Gem::Version
4
- hash: 19
5
- prerelease:
6
- segments:
7
- - 0
8
- - 3
9
- - 0
10
- version: 0.3.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Rene van Lieshout
14
- autorequire:
8
+ autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2011-05-18 00:00:00 +02:00
19
- default_executable:
11
+ date: 2022-01-17 00:00:00.000000000 Z
20
12
  dependencies: []
21
-
22
- description: A mock SMTP/POP3 server to aid in the development of applications with mail functionality.
13
+ description: A mock SMTP/POP3 server to aid in the development of applications with
14
+ mail functionality.
23
15
  email: rene@bluerail.nl
24
- executables:
16
+ executables:
25
17
  - post_office
26
18
  - post_officed
27
19
  extensions: []
28
-
29
- extra_rdoc_files:
20
+ extra_rdoc_files:
21
+ - LICENSE
30
22
  - README.md
31
- files:
23
+ files:
24
+ - LICENSE
32
25
  - README.md
33
26
  - Rakefile
34
27
  - VERSION
35
28
  - bin/post_office
36
29
  - bin/post_officed
30
+ - lib/config_file.rb
37
31
  - lib/generic_server.rb
38
32
  - lib/pop_server.rb
39
33
  - lib/smtp_server.rb
40
34
  - lib/startup_item.rb
41
35
  - lib/store.rb
42
- - pkg/post_office-0.1.0.gem
43
- - pkg/post_office-0.2.0.gem
44
- - pkg/post_office-0.2.1.gem
45
36
  - post_office.gemspec
46
37
  - startup_item/PostOffice/PostOffice
47
38
  - startup_item/PostOffice/StartupParameters.plist
48
- has_rdoc: true
49
39
  homepage: http://github.com/bluerail/post_office
50
40
  licenses: []
51
-
52
- post_install_message:
41
+ metadata: {}
42
+ post_install_message:
53
43
  rdoc_options: []
54
-
55
- require_paths:
44
+ require_paths:
56
45
  - lib
57
- required_ruby_version: !ruby/object:Gem::Requirement
58
- none: false
59
- requirements:
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
60
48
  - - ">="
61
- - !ruby/object:Gem::Version
62
- hash: 3
63
- segments:
64
- - 0
65
- version: "0"
66
- required_rubygems_version: !ruby/object:Gem::Requirement
67
- none: false
68
- requirements:
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
69
53
  - - ">="
70
- - !ruby/object:Gem::Version
71
- hash: 3
72
- segments:
73
- - 0
74
- version: "0"
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
75
56
  requirements: []
76
-
77
- rubyforge_project:
78
- rubygems_version: 1.5.0
79
- signing_key:
80
- specification_version: 3
57
+ rubygems_version: 3.0.3
58
+ signing_key:
59
+ specification_version: 4
81
60
  summary: PostOffice mock SMTP/POP3 server
82
61
  test_files: []
83
-
Binary file
Binary file
Binary file