schleuder 3.2.2 → 3.5.2
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 +4 -4
- data/README.md +21 -11
- data/Rakefile +18 -10
- data/bin/schleuder +2 -1
- data/bin/schleuder-api-daemon +3 -2
- data/db/migrate/20180110203100_add_sig_enc_to_headers_to_meta_defaults.rb +30 -0
- data/db/migrate/20180723173900_add_deliver_selfsent_to_list.rb +11 -0
- data/db/migrate/20190906194820_add_autocrypt_header_to_list.rb +11 -0
- data/db/schema.rb +4 -2
- data/etc/list-defaults.yml +13 -3
- data/etc/schleuder.yml +11 -0
- data/lib/schleuder-api-daemon.rb +9 -354
- data/lib/schleuder-api-daemon/helpers/schleuder-api-daemon-helper.rb +143 -0
- data/lib/schleuder-api-daemon/routes/key.rb +40 -0
- data/lib/schleuder-api-daemon/routes/list.rb +69 -0
- data/lib/schleuder-api-daemon/routes/status.rb +5 -0
- data/lib/schleuder-api-daemon/routes/subscription.rb +99 -0
- data/lib/schleuder-api-daemon/routes/version.rb +5 -0
- data/lib/schleuder.rb +12 -3
- data/lib/schleuder/cli.rb +33 -3
- data/lib/schleuder/cli/subcommand_fix.rb +1 -1
- data/lib/schleuder/conf.rb +7 -1
- data/lib/schleuder/errors/active_model_error.rb +2 -5
- data/lib/schleuder/errors/decryption_failed.rb +2 -7
- data/lib/schleuder/errors/key_adduid_failed.rb +1 -5
- data/lib/schleuder/errors/key_generation_failed.rb +1 -8
- data/lib/schleuder/errors/keyword_admin_only.rb +1 -5
- data/lib/schleuder/errors/list_not_found.rb +1 -5
- data/lib/schleuder/errors/listdir_problem.rb +2 -7
- data/lib/schleuder/errors/loading_list_settings_failed.rb +2 -5
- data/lib/schleuder/errors/message_empty.rb +1 -5
- data/lib/schleuder/errors/message_not_from_admin.rb +2 -5
- data/lib/schleuder/errors/message_sender_not_subscribed.rb +2 -5
- data/lib/schleuder/errors/message_too_big.rb +2 -5
- data/lib/schleuder/errors/message_unauthenticated.rb +1 -4
- data/lib/schleuder/errors/message_unencrypted.rb +2 -5
- data/lib/schleuder/errors/message_unsigned.rb +2 -5
- data/lib/schleuder/errors/too_many_keys.rb +1 -8
- data/lib/schleuder/filters/{request_filter.rb → post_decryption/10_request.rb} +0 -0
- data/lib/schleuder/filters/{max_message_size.rb → post_decryption/20_max_message_size.rb} +0 -0
- data/lib/schleuder/filters/{forward_filter.rb → post_decryption/30_forward_to_owner.rb} +0 -0
- data/lib/schleuder/filters/post_decryption/40_receive_admin_only.rb +10 -0
- data/lib/schleuder/filters/post_decryption/50_receive_authenticated_only.rb +10 -0
- data/lib/schleuder/filters/post_decryption/60_receive_signed_only.rb +10 -0
- data/lib/schleuder/filters/post_decryption/70_receive_encrypted_only.rb +10 -0
- data/lib/schleuder/filters/post_decryption/80_receive_from_subscribed_emailaddresses_only.rb +10 -0
- data/lib/schleuder/filters/post_decryption/90_strip_html_from_alternative_if_keywords_present.rb +21 -0
- data/lib/schleuder/filters/{bounces_filter.rb → pre_decryption/10_forward_bounce_to_admins.rb} +0 -0
- data/lib/schleuder/filters/{forward_incoming.rb → pre_decryption/20_forward_all_incoming_to_admins.rb} +0 -0
- data/lib/schleuder/filters/{send_key_filter.rb → pre_decryption/30_send_key.rb} +0 -0
- data/lib/schleuder/filters/{hotmail_message_filter.rb → pre_decryption/40_fix_exchange_messages.rb} +5 -3
- data/lib/schleuder/filters/{strip_alternative_filter.rb → pre_decryption/50_strip_html_from_alternative.rb} +1 -1
- data/lib/schleuder/filters_runner.rb +41 -31
- data/lib/schleuder/gpgme/ctx.rb +24 -3
- data/lib/schleuder/gpgme/import_status.rb +13 -7
- data/lib/schleuder/gpgme/key.rb +8 -0
- data/lib/schleuder/list.rb +26 -4
- data/lib/schleuder/logger_notifications.rb +8 -1
- data/lib/schleuder/mail/encrypted_part.rb +14 -0
- data/lib/schleuder/mail/gpg.rb +15 -0
- data/lib/schleuder/mail/message.rb +97 -49
- data/lib/schleuder/plugins/attach_listkey.rb +6 -10
- data/lib/schleuder/plugins/key_management.rb +34 -26
- data/lib/schleuder/plugins/resend.rb +14 -11
- data/lib/schleuder/plugins/subscription_management.rb +70 -3
- data/lib/schleuder/runner.rb +49 -10
- data/lib/schleuder/subscription.rb +5 -9
- data/lib/schleuder/validators/fingerprint_validator.rb +1 -1
- data/lib/schleuder/version.rb +1 -1
- data/locales/de.yml +101 -9
- data/locales/en.yml +107 -11
- metadata +72 -34
- data/lib/schleuder/errors/file_not_found.rb +0 -14
- data/lib/schleuder/errors/invalid_listname.rb +0 -13
- data/lib/schleuder/errors/list_exists.rb +0 -13
- data/lib/schleuder/errors/unknown_list_option.rb +0 -14
- data/lib/schleuder/filters/auth_filter.rb +0 -39
@@ -1,16 +1,12 @@
|
|
1
1
|
module Schleuder
|
2
2
|
module ListPlugins
|
3
3
|
def self.attach_listkey(arguments, list, mail)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
})
|
11
|
-
mail.attachments[filename].content_type = 'application/pgp-keys'
|
12
|
-
mail.attachments[filename].content_description = "OpenPGP public key of #{list.email}"
|
13
|
-
mail.attachments[filename].content_disposition = "attachment; filename=#{filename}"
|
4
|
+
new_part = Mail::Part.new
|
5
|
+
new_part.body = list.export_key
|
6
|
+
new_part.content_type = 'application/pgp-keys'
|
7
|
+
new_part.content_description = "OpenPGP public key of #{list.email}"
|
8
|
+
new_part.content_disposition = "attachment; filename=#{list.fingerprint}.pgpkey"
|
9
|
+
mail.add_part new_part
|
14
10
|
nil
|
15
11
|
end
|
16
12
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module Schleuder
|
2
2
|
module RequestPlugins
|
3
3
|
def self.add_key(arguments, list, mail)
|
4
|
-
out = [I18n.t('plugins.key_management.import_result')]
|
5
4
|
|
6
5
|
if mail.has_attachments?
|
7
6
|
results = self.import_keys_from_attachments(list, mail)
|
@@ -9,15 +8,35 @@ module Schleuder
|
|
9
8
|
results = [self.import_key_from_body(list, mail)]
|
10
9
|
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
import_stati = results.compact.collect(&:imports).flatten
|
12
|
+
|
13
|
+
if import_stati.blank?
|
14
|
+
return I18n.t('plugins.key_management.no_imports')
|
15
|
+
end
|
16
|
+
|
17
|
+
out = []
|
18
|
+
|
19
|
+
import_stati.each do |import_status|
|
20
|
+
if import_status.action == 'error'
|
21
|
+
out << I18n.t("plugins.key_management.key_import_status.error", fingerprint: import_status.fingerprint)
|
22
|
+
else
|
23
|
+
key = list.gpg.find_distinct_key(import_status.fingerprint)
|
24
|
+
if key
|
25
|
+
out << I18n.t("plugins.key_management.key_import_status.#{import_status.action}", key_oneline: key.oneline)
|
26
|
+
end
|
27
|
+
end
|
15
28
|
end
|
16
29
|
|
17
|
-
out.join("\n")
|
30
|
+
out.join("\n\n")
|
18
31
|
end
|
19
32
|
|
20
33
|
def self.delete_key(arguments, list, mail)
|
34
|
+
if arguments.blank?
|
35
|
+
return I18n.t(
|
36
|
+
"plugins.key_management.delete_key_requires_arguments"
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
21
40
|
arguments.map do |argument|
|
22
41
|
keys = list.keys(argument)
|
23
42
|
case keys.size
|
@@ -26,9 +45,9 @@ module Schleuder
|
|
26
45
|
when 1
|
27
46
|
begin
|
28
47
|
keys.first.delete!
|
29
|
-
I18n.t('plugins.key_management.deleted', key_string: keys.first.
|
48
|
+
I18n.t('plugins.key_management.deleted', key_string: keys.first.oneline)
|
30
49
|
rescue GPGME::Error::Conflict
|
31
|
-
I18n.t('plugins.key_management.not_deletable', key_string: keys.first.
|
50
|
+
I18n.t('plugins.key_management.not_deletable', key_string: keys.first.oneline)
|
32
51
|
end
|
33
52
|
else
|
34
53
|
I18n.t('errors.too_many_matching_keys', {
|
@@ -71,6 +90,12 @@ module Schleuder
|
|
71
90
|
end
|
72
91
|
|
73
92
|
def self.fetch_key(arguments, list, mail)
|
93
|
+
if arguments.blank?
|
94
|
+
return I18n.t(
|
95
|
+
"plugins.key_management.fetch_key_requires_arguments"
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
74
99
|
arguments.map do |argument|
|
75
100
|
list.fetch_keys(argument)
|
76
101
|
end
|
@@ -79,35 +104,18 @@ module Schleuder
|
|
79
104
|
# helper methods
|
80
105
|
private
|
81
106
|
|
82
|
-
def self.is_armored_key?(material)
|
83
|
-
return false unless /^-----BEGIN PGP PUBLIC KEY BLOCK-----$/ =~ material
|
84
|
-
return false unless /^-----END PGP PUBLIC KEY BLOCK-----$/ =~ material
|
85
|
-
|
86
|
-
lines = material.split("\n").reject(&:empty?)
|
87
|
-
# remove header
|
88
|
-
lines.shift
|
89
|
-
# remove tail
|
90
|
-
lines.pop
|
91
|
-
# verify the rest
|
92
|
-
# TODO: verify length except for lasts lines?
|
93
|
-
# headers according to https://tools.ietf.org/html/rfc4880#section-6.2
|
94
|
-
lines.map do |line|
|
95
|
-
/\A((comment|version|messageid|hash|charset):.*|[0-9a-z\/=+]+)\Z/i =~ line
|
96
|
-
end.all?
|
97
|
-
end
|
98
|
-
|
99
107
|
def self.import_keys_from_attachments(list, mail)
|
100
108
|
mail.attachments.map do |attachment|
|
101
109
|
material = attachment.body.to_s
|
102
110
|
|
103
|
-
list.import_key(material)
|
111
|
+
list.import_key(material)
|
104
112
|
end
|
105
113
|
end
|
106
114
|
|
107
115
|
def self.import_key_from_body(list, mail)
|
108
116
|
key_material = mail.first_plaintext_part.body.to_s
|
109
117
|
|
110
|
-
list.import_key(key_material)
|
118
|
+
list.import_key(key_material)
|
111
119
|
end
|
112
120
|
end
|
113
121
|
end
|
@@ -56,6 +56,9 @@ module Schleuder
|
|
56
56
|
|
57
57
|
# Only continue if all recipients are still here.
|
58
58
|
if recip_map.size < arguments.size
|
59
|
+
recip_map.keys.each do |aborted_sender|
|
60
|
+
mail.add_pseudoheader(:error, I18n.t("plugins.resend.aborted", email: aborted_sender))
|
61
|
+
end
|
59
62
|
return
|
60
63
|
end
|
61
64
|
|
@@ -117,22 +120,22 @@ module Schleuder
|
|
117
120
|
Array(recipients).inject({}) do |hash, email|
|
118
121
|
keys = mail.list.keys(email)
|
119
122
|
# Exclude unusable keys.
|
120
|
-
keys.select
|
121
|
-
case
|
123
|
+
usable_keys = keys.select { |key| key.usable_for?(:encrypt) }
|
124
|
+
case usable_keys.size
|
122
125
|
when 1
|
123
|
-
hash[email] =
|
126
|
+
hash[email] = usable_keys.first
|
124
127
|
when 0
|
125
128
|
if encrypted_only
|
126
129
|
# Don't add the email to the result to exclude it from the
|
127
130
|
# recipients.
|
128
|
-
|
131
|
+
add_resend_msg(mail, email, :error, 'not_resent_no_keys', usable_keys.size, keys.size)
|
129
132
|
else
|
130
133
|
hash[email] = ''
|
131
134
|
end
|
132
135
|
else
|
133
136
|
# Always report this situation, regardless of sending or not. It's
|
134
137
|
# bad and should be fixed.
|
135
|
-
|
138
|
+
add_resend_msg(mail, email, :notice, 'not_resent_encrypted_no_keys', usable_keys.size, keys.size)
|
136
139
|
if ! encrypted_only
|
137
140
|
hash[email] = ''
|
138
141
|
end
|
@@ -152,8 +155,8 @@ module Schleuder
|
|
152
155
|
gpg_opts
|
153
156
|
end
|
154
157
|
|
155
|
-
def self.
|
156
|
-
mail.add_pseudoheader(
|
158
|
+
def self.add_resend_msg(mail, email, severity, msg, usable_keys_size, all_keys_size)
|
159
|
+
mail.add_pseudoheader(severity, I18n.t("plugins.resend.#{msg}", email: email, usable_keys: usable_keys_size, all_keys: all_keys_size))
|
157
160
|
end
|
158
161
|
|
159
162
|
def self.add_error_header(mail, recipients_map)
|
@@ -163,15 +166,15 @@ module Schleuder
|
|
163
166
|
def self.add_resent_headers(mail, recipients_map, to_or_cc, sent_encrypted)
|
164
167
|
if sent_encrypted
|
165
168
|
prefix = I18n.t('plugins.resend.encrypted_to')
|
166
|
-
str = recipients_map.map do |email, key|
|
169
|
+
str = "\n" + recipients_map.map do |email, key|
|
167
170
|
"#{email} (#{key.fingerprint})"
|
168
|
-
end.join(
|
171
|
+
end.join(",\n")
|
169
172
|
else
|
170
173
|
prefix = I18n.t('plugins.resend.unencrypted_to')
|
171
|
-
str = recipients_map.keys.join(
|
174
|
+
str = ' ' + recipients_map.keys.join(", ")
|
172
175
|
end
|
173
176
|
headername = resent_header_name(to_or_cc)
|
174
|
-
mail.add_pseudoheader(headername, "#{prefix}
|
177
|
+
mail.add_pseudoheader(headername, "#{prefix}#{str}")
|
175
178
|
end
|
176
179
|
|
177
180
|
def self.resent_header_name(to_or_cc)
|
@@ -1,12 +1,18 @@
|
|
1
1
|
module Schleuder
|
2
2
|
module RequestPlugins
|
3
3
|
def self.subscribe(arguments, list, mail)
|
4
|
+
if arguments.blank?
|
5
|
+
return I18n.t(
|
6
|
+
"plugins.subscription_management.subscribe_requires_arguments"
|
7
|
+
)
|
8
|
+
end
|
9
|
+
|
4
10
|
email = arguments.shift
|
5
11
|
|
6
12
|
if arguments.present?
|
7
13
|
# Collect all arguments that look like fingerprint-material
|
8
14
|
fingerprint = ''
|
9
|
-
while arguments.first.present? && arguments.first.match(
|
15
|
+
while arguments.first.present? && arguments.first.match(/^(0x)?[a-f0-9]+$/i)
|
10
16
|
fingerprint << arguments.shift
|
11
17
|
end
|
12
18
|
# Use possibly remaining args as flags.
|
@@ -37,6 +43,13 @@ module Schleuder
|
|
37
43
|
# If no address was given we unsubscribe the sender.
|
38
44
|
email = arguments.first.presence || mail.signer.email
|
39
45
|
|
46
|
+
# Refuse to unsubscribe the last admin.
|
47
|
+
if list.admins.size == 1 && list.admins.first.email == email
|
48
|
+
return I18n.t(
|
49
|
+
"plugins.subscription_management.cannot_unsubscribe_last_admin", email: email
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
40
53
|
# TODO: May signers have multiple UIDs? We don't match those currently.
|
41
54
|
if ! list.from_admin?(mail) && email != mail.signer.email
|
42
55
|
# Only admins may unsubscribe others.
|
@@ -98,6 +111,12 @@ module Schleuder
|
|
98
111
|
end
|
99
112
|
|
100
113
|
def self.set_fingerprint(arguments, list, mail)
|
114
|
+
if arguments.blank?
|
115
|
+
return I18n.t(
|
116
|
+
"plugins.subscription_management.set_fingerprint_requires_arguments"
|
117
|
+
)
|
118
|
+
end
|
119
|
+
|
101
120
|
if arguments.first.match(/@/)
|
102
121
|
if arguments.first == mail.signer.email || list.from_admin?(mail)
|
103
122
|
email = arguments.shift
|
@@ -118,8 +137,15 @@ module Schleuder
|
|
118
137
|
)
|
119
138
|
end
|
120
139
|
|
121
|
-
|
140
|
+
fingerprint = arguments.join
|
141
|
+
unless GPGME::Key.valid_fingerprint?(fingerprint)
|
142
|
+
return I18n.t(
|
143
|
+
"plugins.subscription_management.set_fingerprint_requires_valid_fingerprint",
|
144
|
+
fingerprint: fingerprint
|
145
|
+
)
|
146
|
+
end
|
122
147
|
|
148
|
+
sub.fingerprint = fingerprint
|
123
149
|
if sub.save
|
124
150
|
I18n.t(
|
125
151
|
"plugins.subscription_management.fingerprint_set",
|
@@ -130,7 +156,48 @@ module Schleuder
|
|
130
156
|
I18n.t(
|
131
157
|
"plugins.subscription_management.setting_fingerprint_failed",
|
132
158
|
email: email,
|
133
|
-
fingerprint:
|
159
|
+
fingerprint: sub.fingerprint,
|
160
|
+
errors: sub.errors.to_a.join("\n")
|
161
|
+
)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def self.unset_fingerprint(arguments, list, mail)
|
166
|
+
if arguments.blank?
|
167
|
+
return I18n.t(
|
168
|
+
"plugins.subscription_management.unset_fingerprint_requires_arguments"
|
169
|
+
)
|
170
|
+
end
|
171
|
+
|
172
|
+
email = arguments.first
|
173
|
+
unless email == mail.signer.email || list.from_admin?(mail)
|
174
|
+
return I18n.t(
|
175
|
+
"plugins.subscription_management.unset_fingerprint_only_self"
|
176
|
+
)
|
177
|
+
end
|
178
|
+
if email == mail.signer.email && list.from_admin?(mail) && arguments.last != 'force'
|
179
|
+
return I18n.t(
|
180
|
+
"plugins.subscription_management.unset_fingerprint_requires_arguments"
|
181
|
+
)
|
182
|
+
end
|
183
|
+
|
184
|
+
sub = list.subscriptions.where(email: email).first
|
185
|
+
if sub.blank?
|
186
|
+
return I18n.t(
|
187
|
+
"plugins.subscription_management.is_not_subscribed", email: email
|
188
|
+
)
|
189
|
+
end
|
190
|
+
|
191
|
+
sub.fingerprint = ''
|
192
|
+
if sub.save
|
193
|
+
I18n.t(
|
194
|
+
"plugins.subscription_management.fingerprint_unset",
|
195
|
+
email: email
|
196
|
+
)
|
197
|
+
else
|
198
|
+
I18n.t(
|
199
|
+
"plugins.subscription_management.unsetting_fingerprint_failed",
|
200
|
+
email: email,
|
134
201
|
errors: sub.errors.to_a.join("\n")
|
135
202
|
)
|
136
203
|
end
|
data/lib/schleuder/runner.rb
CHANGED
@@ -5,20 +5,48 @@ module Schleuder
|
|
5
5
|
return error if error
|
6
6
|
|
7
7
|
logger.info "Parsing incoming email."
|
8
|
+
|
9
|
+
# is it valid utf-8?
|
10
|
+
msg_scrubbed = false
|
11
|
+
unless msg.valid_encoding?
|
12
|
+
logger.warn "Converting message due to invalid characters"
|
13
|
+
detection = CharlockHolmes::EncodingDetector.detect(msg)
|
14
|
+
begin
|
15
|
+
msg = CharlockHolmes::Converter.convert(msg, detection[:encoding], 'UTF-8')
|
16
|
+
rescue ArgumentError
|
17
|
+
# it looks like even icu wasn't able to convert
|
18
|
+
# so we scrub the invalid characters to be able to
|
19
|
+
# at least parse the message somehow. Though this might
|
20
|
+
# result in data loss.
|
21
|
+
logger.warn "Scrubbing message due to invalid characters"
|
22
|
+
msg = msg.scrub
|
23
|
+
msg_scrubbed = true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
8
27
|
@mail = Mail.create_message_to_list(msg, recipient, list)
|
9
28
|
|
10
|
-
|
29
|
+
if msg_scrubbed
|
30
|
+
@mail.add_pseudoheader(:note, I18n.t("pseudoheaders.scrubbed_message"))
|
31
|
+
end
|
32
|
+
|
33
|
+
error = run_filters('pre')
|
11
34
|
return error if error
|
12
35
|
|
13
36
|
begin
|
14
37
|
# This decrypts, verifies, etc.
|
15
38
|
@mail = @mail.setup
|
16
|
-
|
39
|
+
|
40
|
+
rescue GPGME::Error::BadPassphrase,
|
41
|
+
GPGME::Error::DecryptFailed,
|
42
|
+
GPGME::Error::NoData,
|
43
|
+
GPGME::Error::NoSecretKey
|
44
|
+
|
17
45
|
logger.warn "Decryption of incoming message failed."
|
18
46
|
return Errors::DecryptionFailed.new(list)
|
19
47
|
end
|
20
48
|
|
21
|
-
error = run_filters(
|
49
|
+
error = run_filters('post')
|
22
50
|
return error if error
|
23
51
|
|
24
52
|
if ! @mail.was_validly_signed?
|
@@ -45,8 +73,8 @@ module Schleuder
|
|
45
73
|
|
46
74
|
# Subscriptions
|
47
75
|
logger.debug "Creating clean copy of message"
|
48
|
-
copy = @mail.clean_copy(
|
49
|
-
list.send_to_subscriptions(copy)
|
76
|
+
copy = @mail.clean_copy(list.headers_to_meta.any?)
|
77
|
+
list.send_to_subscriptions(copy, @mail)
|
50
78
|
nil
|
51
79
|
end
|
52
80
|
|
@@ -56,8 +84,8 @@ module Schleuder
|
|
56
84
|
@list
|
57
85
|
end
|
58
86
|
|
59
|
-
def run_filters(
|
60
|
-
error = filters_runner.run(@mail
|
87
|
+
def run_filters(filter_type)
|
88
|
+
error = filters_runner(filter_type).run(@mail)
|
61
89
|
if error
|
62
90
|
if list.bounces_notify_admins?
|
63
91
|
text = "#{I18n.t('.bounces_notify_admins')}\n\n#{error}"
|
@@ -68,8 +96,19 @@ module Schleuder
|
|
68
96
|
end
|
69
97
|
end
|
70
98
|
|
71
|
-
def filters_runner
|
72
|
-
|
99
|
+
def filters_runner(filter_type)
|
100
|
+
if filter_type == 'pre'
|
101
|
+
filters_runner_pre_decryption
|
102
|
+
else
|
103
|
+
filters_runner_post_decryption
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def filters_runner_pre_decryption
|
108
|
+
@filters_runner_pre_decryption ||= Filters::Runner.new(list,'pre')
|
109
|
+
end
|
110
|
+
def filters_runner_post_decryption
|
111
|
+
@filters_runner_post_decryption ||= Filters::Runner.new(list,'post')
|
73
112
|
end
|
74
113
|
|
75
114
|
def logger
|
@@ -94,7 +133,7 @@ module Schleuder
|
|
94
133
|
return log_and_return(Errors::ListNotFound.new(recipient), true)
|
95
134
|
end
|
96
135
|
|
97
|
-
# Check
|
136
|
+
# Check necessary permissions of crucial files.
|
98
137
|
if ! File.exist?(@list.listdir)
|
99
138
|
return log_and_return(Errors::ListdirProblem.new(@list.listdir, :not_existing))
|
100
139
|
elsif ! File.directory?(@list.listdir)
|
@@ -23,10 +23,11 @@ module Schleuder
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def fingerprint=(arg)
|
26
|
-
#
|
27
|
-
#
|
28
|
-
|
29
|
-
|
26
|
+
# Always assign the given value, because it must be possible to overwrite
|
27
|
+
# the previous fingerprint with an empty value. That value should better
|
28
|
+
# be nil instead of a blank string, but currently schleuder-cli (v0.1.0) expects
|
29
|
+
# only strings.
|
30
|
+
write_attribute(:fingerprint, arg.to_s.gsub(/\s*/, '').gsub(/^0x/, '').chomp.upcase)
|
30
31
|
end
|
31
32
|
|
32
33
|
def key
|
@@ -39,11 +40,6 @@ module Schleuder
|
|
39
40
|
def send_mail(mail)
|
40
41
|
list.logger.debug "Preparing sending to #{self.inspect}"
|
41
42
|
|
42
|
-
if ! self.delivery_enabled
|
43
|
-
list.logger.info "Not sending to #{self.email}: delivery is disabled."
|
44
|
-
return false
|
45
|
-
end
|
46
|
-
|
47
43
|
mail = ensure_headers(mail)
|
48
44
|
gpg_opts = self.list.gpg_sign_options
|
49
45
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class FingerprintValidator < ActiveModel::EachValidator
|
2
2
|
def validate_each(record, attribute, value)
|
3
|
-
unless value
|
3
|
+
unless GPGME::Key.valid_fingerprint?(value)
|
4
4
|
record.errors[attribute] << (options[:message] || I18n.t("errors.invalid_fingerprint"))
|
5
5
|
end
|
6
6
|
end
|