discourse_mail_receiver 4.0.7 → 4.1.0

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
  SHA256:
3
- metadata.gz: ad2a138074a1cd652fd5f1ac4001c85970145b35fd8b1808d44a5f3564634fe3
4
- data.tar.gz: 1931f2af0a17bbc0c9ed807b12b77a5c89954a97f2c9e323f6cad352ccc88bee
3
+ metadata.gz: 621926d0206bd4c21fc7e1c138ca3674154abba678c2e12f340391821c3232f3
4
+ data.tar.gz: 746ba23e178eb0b46f88827c6da15819a956576ff4fa91d344dcd429473a04e5
5
5
  SHA512:
6
- metadata.gz: 712cfab8ec40f3585c7ea7fc84510e9acfbc804dc3e7d42ed157d1c81709a67536e995d27a4f28f227825bb8576a9a5929174b5b8970198a08c87eed09f99f48
7
- data.tar.gz: ad844b3e84ff0cf3fc1ec16728ac7f3f1f74188dbc9a3fabc273c7085f3fdbb6564613d94cfd52c59611c3c27d55a344040464488cf409e0768da96df34284d8
6
+ metadata.gz: 85da9c1a37912f5962c9ca3b7f3f297818a4f95cba651855427c67007fa1f18b70ee52a43bc301ebfc4d5d2e7f37cf33cd1624ecd14fa0615dadd688c37e8ef6
7
+ data.tar.gz: 9dfae7da9939d77675cfad66aff9f3b732d09d3d5db3b9260b0093fbaedbb7cb7c59cf7ffaef5c43f336af083887a7b425dea3a604793aabc1c255d388afca8a
@@ -1,12 +1,11 @@
1
1
  # frozen_string_literal: true
2
- require 'syslog'
3
- require 'json'
2
+ require "syslog"
3
+ require "json"
4
4
  require "uri"
5
5
  require "net/http"
6
- require_relative 'mail_receiver_base'
6
+ require_relative "mail_receiver_base"
7
7
 
8
8
  class DiscourseMailReceiver < MailReceiverBase
9
-
10
9
  def initialize(env_file = nil, recipient = nil, mail = nil)
11
10
  super(env_file)
12
11
 
@@ -23,8 +22,8 @@ class DiscourseMailReceiver < MailReceiverBase
23
22
 
24
23
  @endpoint = @env["DISCOURSE_MAIL_ENDPOINT"]
25
24
 
26
- if @env['DISCOURSE_BASE_URL']
27
- @endpoint = "#{@env['DISCOURSE_BASE_URL']}/admin/email/handle_mail"
25
+ if @env["DISCOURSE_BASE_URL"]
26
+ @endpoint = "#{@env["DISCOURSE_BASE_URL"]}/admin/email/handle_mail"
28
27
  end
29
28
  @endpoint
30
29
  end
@@ -55,5 +54,4 @@ class DiscourseMailReceiver < MailReceiverBase
55
54
  logger.err "Failed to POST the e-mail to %s: %s", endpoint, response.code
56
55
  :failure
57
56
  end
58
-
59
57
  end
@@ -1,22 +1,25 @@
1
1
  # frozen_string_literal: true
2
- require 'set'
3
- require 'syslog'
4
- require 'json'
5
- require 'uri'
6
- require 'cgi'
7
- require 'net/http'
8
2
 
9
- require_relative 'mail'
10
- require_relative 'mail_receiver_base'
3
+ # rubocop:disable Lint/RedundantRequireStatement
4
+ # require "set" is needed for Set
5
+ require "set"
6
+ require "syslog"
7
+ require "json"
8
+ require "uri"
9
+ require "cgi"
10
+ require "net/http"
11
11
 
12
- class FastRejection < MailReceiverBase
12
+ require_relative "mail"
13
+ require_relative "mail_receiver_base"
13
14
 
15
+ class FastRejection < MailReceiverBase
14
16
  def initialize(env_file)
15
17
  super(env_file)
16
18
 
17
- @disabled = @env['DISCOURSE_FAST_REJECTION_DISABLED'] || !@env['DISCOURSE_BASE_URL']
19
+ @disabled = @env["DISCOURSE_FAST_REJECTION_DISABLED"] || !@env["DISCOURSE_BASE_URL"]
18
20
 
19
- @blacklisted_sender_domains = @env.fetch('BLACKLISTED_SENDER_DOMAINS', "").split(" ").map(&:downcase).to_set
21
+ @blacklisted_sender_domains =
22
+ Set.new(@env.fetch("BLACKLISTED_SENDER_DOMAINS", "").split(" ").map(&:downcase))
20
23
  end
21
24
 
22
25
  def disabled?
@@ -24,7 +27,7 @@ class FastRejection < MailReceiverBase
24
27
  end
25
28
 
26
29
  def process
27
- $stdout.sync = true # unbuffered output
30
+ $stdout.sync = true # unbuffered output
28
31
 
29
32
  args = {}
30
33
  while line = gets
@@ -32,29 +35,29 @@ class FastRejection < MailReceiverBase
32
35
  line = line.chomp
33
36
  if line.empty?
34
37
  puts "action=#{process_single_request(args)}"
35
- puts ''
38
+ puts ""
36
39
 
37
- args = {} # reset for next request.
40
+ args = {} # reset for next request.
38
41
  else
39
- k, v = line.chomp.split('=', 2)
42
+ k, v = line.chomp.split("=", 2)
40
43
  args[k] = v
41
44
  end
42
45
  end
43
46
  end
44
47
 
45
48
  def process_single_request(args)
46
- return 'dunno' if disabled?
49
+ return "dunno" if disabled?
47
50
 
48
- if args['request'] != 'smtpd_access_policy'
49
- return 'defer_if_permit Internal error, Request type invalid'
50
- elsif args['protocol_state'] != 'RCPT'
51
- return 'dunno'
52
- elsif args['sender'].nil?
51
+ if args["request"] != "smtpd_access_policy"
52
+ return "defer_if_permit Internal error, Request type invalid"
53
+ elsif args["protocol_state"] != "RCPT"
54
+ return "dunno"
55
+ elsif args["sender"].nil?
53
56
  # Note that while this key should always exist, its value may be the empty
54
57
  # string. Postfix will convert the "<>" null sender to "".
55
- return 'defer_if_permit No sender specified'
56
- elsif args['recipient'].nil?
57
- return 'defer_if_permit No recipient specified'
58
+ return "defer_if_permit No sender specified"
59
+ elsif args["recipient"].nil?
60
+ return "defer_if_permit No recipient specified"
58
61
  end
59
62
 
60
63
  run_filters(args)
@@ -62,8 +65,8 @@ class FastRejection < MailReceiverBase
62
65
 
63
66
  def maybe_reject_email(from, to)
64
67
  uri = URI.parse(endpoint)
65
- fromarg = CGI::escape(from)
66
- toarg = CGI::escape(to)
68
+ fromarg = CGI.escape(from)
69
+ toarg = CGI.escape(to)
67
70
 
68
71
  qs = "from=#{fromarg}&to=#{toarg}"
69
72
  if uri.query && !uri.query.empty?
@@ -80,7 +83,10 @@ class FastRejection < MailReceiverBase
80
83
  get["Api-Key"] = key
81
84
  response = http.request(get)
82
85
  rescue StandardError => ex
83
- logger.err "Failed to GET smtp_should_reject answer from %s: %s (%s)", endpoint, ex.message, ex.class
86
+ logger.err "Failed to GET smtp_should_reject answer from %s: %s (%s)",
87
+ endpoint,
88
+ ex.message,
89
+ ex.class
84
90
  logger.err ex.backtrace.map { |l| " #{l}" }.join("\n")
85
91
  return "defer_if_permit Internal error, API request preparation failed"
86
92
  ensure
@@ -89,28 +95,23 @@ class FastRejection < MailReceiverBase
89
95
 
90
96
  if Net::HTTPSuccess === response
91
97
  reply = JSON.parse(response.body)
92
- if reply['reject']
93
- return "reject #{reply['reason']}"
94
- end
98
+ return "reject #{reply["reason"]}" if reply["reject"]
95
99
  else
96
100
  logger.err "Failed to GET smtp_should_reject answer from %s: %s", endpoint, response.code
97
101
  return "defer_if_permit Internal error, API request failed"
98
102
  end
99
103
 
100
- "dunno" # let future tests also be allowed to reject this one.
104
+ "dunno" # let future tests also be allowed to reject this one.
101
105
  end
102
106
 
103
107
  def endpoint
104
- "#{@env['DISCOURSE_BASE_URL']}/admin/email/smtp_should_reject.json"
108
+ "#{@env["DISCOURSE_BASE_URL"]}/admin/email/smtp_should_reject.json"
105
109
  end
106
110
 
107
111
  private
108
112
 
109
113
  def run_filters(args)
110
- filters = [
111
- :maybe_reject_by_sender_domain,
112
- :maybe_reject_by_api,
113
- ]
114
+ filters = %i[maybe_reject_by_sender_domain maybe_reject_by_api]
114
115
 
115
116
  filters.each do |f|
116
117
  action = send(f, args)
@@ -121,25 +122,24 @@ class FastRejection < MailReceiverBase
121
122
  end
122
123
 
123
124
  def maybe_reject_by_sender_domain(args)
124
- sender = args['sender']
125
+ sender = args["sender"]
125
126
 
126
127
  return "dunno" if sender.empty?
127
128
 
128
129
  domain = domain_from_addrspec(sender)
129
130
  if domain.empty?
130
131
  logger.info("deferred mail with domainless sender #{sender}")
131
- return 'defer_if_permit Invalid sender'
132
+ return "defer_if_permit Invalid sender"
132
133
  end
133
134
  if @blacklisted_sender_domains.include? domain
134
135
  logger.info("rejected mail from blacklisted sender domain #{domain} (from #{sender})")
135
- return 'reject Invalid sender'
136
+ return "reject Invalid sender"
136
137
  end
137
138
 
138
139
  "dunno"
139
140
  end
140
141
 
141
142
  def maybe_reject_by_api(args)
142
- maybe_reject_email(args['sender'], args['recipient'])
143
+ maybe_reject_email(args["sender"], args["recipient"])
143
144
  end
144
-
145
145
  end
@@ -1,21 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
  class MailReceiverBase
3
- class ReceiverException < StandardError; end
3
+ class ReceiverException < StandardError
4
+ end
4
5
 
5
6
  attr_reader :env
6
7
 
7
8
  def initialize(env_file)
8
- unless File.exists?(env_file)
9
- fatal "Config file %s does not exist. Aborting.", env_file
10
- end
9
+ fatal "Config file %s does not exist. Aborting.", env_file unless File.exist?(env_file)
11
10
 
12
11
  @env = JSON.parse(File.read(env_file))
13
12
 
14
- %w{DISCOURSE_API_KEY DISCOURSE_API_USERNAME}.each do |kw|
13
+ %w[DISCOURSE_API_KEY DISCOURSE_API_USERNAME].each do |kw|
15
14
  fatal "env var %s is required", kw unless @env[kw]
16
15
  end
17
16
 
18
- if @env['DISCOURSE_MAIL_ENDPOINT'].nil? && @env['DISCOURSE_BASE_URL'].nil?
17
+ if @env["DISCOURSE_MAIL_ENDPOINT"].nil? && @env["DISCOURSE_BASE_URL"].nil?
19
18
  fatal "DISCOURSE_MAIL_ENDPOINT and DISCOURSE_BASE_URL env var missing"
20
19
  end
21
20
  end
@@ -29,11 +28,11 @@ class MailReceiverBase
29
28
  end
30
29
 
31
30
  def key
32
- @env['DISCOURSE_API_KEY']
31
+ @env["DISCOURSE_API_KEY"]
33
32
  end
34
33
 
35
34
  def username
36
- @env['DISCOURSE_API_USERNAME']
35
+ @env["DISCOURSE_API_USERNAME"]
37
36
  end
38
37
 
39
38
  def fatal(*args)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: discourse_mail_receiver
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.7
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Discourse Team
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-02 00:00:00.000000000 Z
11
+ date: 2024-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mail
@@ -25,61 +25,89 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 2.7.1
27
27
  - !ruby/object:Gem::Dependency
28
- name: bundler
28
+ name: net-smtp
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.0'
34
- type: :development
33
+ version: 0.3.3
34
+ type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '2.0'
40
+ version: 0.3.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '13.0'
47
+ version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '13.0'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '3.10'
61
+ version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '3.10'
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rubocop-discourse
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: 2.4.1
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: syntax_tree
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: syntax_tree-disable_ternary
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
81
109
  - !ruby/object:Gem::Version
82
- version: 2.4.1
110
+ version: '0'
83
111
  description: A gem used to package the core .rb files of the mail-receiver.
84
112
  email:
85
113
  - team@discourse.org
@@ -95,7 +123,7 @@ homepage: https://github.com/discourse/mail-receiver
95
123
  licenses:
96
124
  - MIT
97
125
  metadata: {}
98
- post_install_message:
126
+ post_install_message:
99
127
  rdoc_options: []
100
128
  require_paths:
101
129
  - lib
@@ -103,15 +131,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
103
131
  requirements:
104
132
  - - ">="
105
133
  - !ruby/object:Gem::Version
106
- version: 2.5.0
134
+ version: 3.0.0
107
135
  required_rubygems_version: !ruby/object:Gem::Requirement
108
136
  requirements:
109
137
  - - ">="
110
138
  - !ruby/object:Gem::Version
111
139
  version: '0'
112
140
  requirements: []
113
- rubygems_version: 3.1.4
114
- signing_key:
141
+ rubygems_version: 3.5.11
142
+ signing_key:
115
143
  specification_version: 4
116
144
  summary: A gem used to package the core .rb files of the mail-receiver.
117
145
  test_files: []