mail-gpg 0.4.4 → 0.4.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 +5 -5
- data/.github/workflows/test.yml +60 -0
- data/History.txt +7 -0
- data/README.md +1 -1
- data/lib/hkp.rb +14 -5
- data/lib/mail/gpg/version.rb +1 -1
- data/mail-gpg.gemspec +1 -0
- data/test/hkp_test.rb +219 -1
- data/test/message_test.rb +5 -7
- data/test/test_helper.rb +4 -0
- metadata +21 -10
- data/.travis.yml +0 -21
- data/test/gpghome/random_seed +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: c21d99f46e1cf61f5f6b528d75189d90dd0543c6937c346d0435ad5dc23b9d25
|
|
4
|
+
data.tar.gz: a33073e63f6353184d87188a81996147ffcff43a98818fc46c07bcf9ac2e5d7b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: edc5a48bad65750933dba1cc7d50c157c3c38a96d101e4106af284389199ea74564ed92689583a17a537f357a823dec9c8c301f7aca437c6f5dc9caf3030e109
|
|
7
|
+
data.tar.gz: e6040cb3fb89303a145a4a5158134437e66b52beca5628e6b154baf41560b53386b3e60bb93b915af4bc228b173b0d8f4f45e9cbbb4185f1387120d2e111159f
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [master]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
ruby-version: ["2.7", "3.0", "3.1", "3.2", "3.3", "3.4"]
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Install GPG
|
|
22
|
+
run: sudo apt-get update && sudo apt-get install -y gnupg
|
|
23
|
+
|
|
24
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
|
25
|
+
uses: ruby/setup-ruby@v1
|
|
26
|
+
with:
|
|
27
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
28
|
+
bundler-cache: true
|
|
29
|
+
|
|
30
|
+
- name: Run tests
|
|
31
|
+
run: bundle exec rake
|
|
32
|
+
|
|
33
|
+
test-with-rails:
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
|
|
36
|
+
strategy:
|
|
37
|
+
fail-fast: false
|
|
38
|
+
matrix:
|
|
39
|
+
include:
|
|
40
|
+
- ruby-version: "3.2"
|
|
41
|
+
rails-version: "7.1"
|
|
42
|
+
- ruby-version: "3.4"
|
|
43
|
+
rails-version: "7.2"
|
|
44
|
+
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v4
|
|
47
|
+
|
|
48
|
+
- name: Install GPG
|
|
49
|
+
run: sudo apt-get update && sudo apt-get install -y gnupg
|
|
50
|
+
|
|
51
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
|
52
|
+
uses: ruby/setup-ruby@v1
|
|
53
|
+
with:
|
|
54
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
55
|
+
bundler-cache: true
|
|
56
|
+
|
|
57
|
+
- name: Run tests with Rails ${{ matrix.rails-version }}
|
|
58
|
+
env:
|
|
59
|
+
RAILS: ${{ matrix.rails-version }}
|
|
60
|
+
run: bundle update && bundle exec rake
|
data/History.txt
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
== 0.4.5 2026-01-20
|
|
2
|
+
|
|
3
|
+
* fix HKP client for Ruby 3.0+ (replaced deprecated URI.escape/decode)
|
|
4
|
+
* change default keyserver from defunct pool.sks-keyservers.net to
|
|
5
|
+
keyserver.ubuntu.com
|
|
6
|
+
* fix HKP client redirect handling
|
|
7
|
+
|
|
1
8
|
== 0.4.4 2020-07-30
|
|
2
9
|
|
|
3
10
|
* preserve Content-ID header of signed parts (relevant for inline images in
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Mail::Gpg [](https://github.com/jkraemer/mail-gpg/actions/workflows/test.yml)
|
|
2
2
|
|
|
3
3
|
This gem adds GPG/MIME encryption capabilities to the [Ruby Mail
|
|
4
4
|
Library](https://github.com/mikel/mail)
|
data/lib/hkp.rb
CHANGED
|
@@ -49,7 +49,16 @@ class Hkp
|
|
|
49
49
|
if redirect_depth >= MAX_REDIRECTS
|
|
50
50
|
raise TooManyRedirects
|
|
51
51
|
else
|
|
52
|
-
|
|
52
|
+
location = URI.parse(response['location'])
|
|
53
|
+
if location.host && (location.host != @host || location.port != @port)
|
|
54
|
+
# Cross-host redirect - create new client for the target server
|
|
55
|
+
redirect_client = Client.new(response['location'], ssl_verify_mode: @ssl_verify_mode)
|
|
56
|
+
return redirect_client.get(location.request_uri, redirect_depth + 1)
|
|
57
|
+
else
|
|
58
|
+
# Same-host redirect (relative path or same host)
|
|
59
|
+
redirect_path = location.respond_to?(:request_uri) ? location.request_uri : response['location']
|
|
60
|
+
return get(redirect_path, redirect_depth + 1)
|
|
61
|
+
end
|
|
53
62
|
end
|
|
54
63
|
else
|
|
55
64
|
raise InvalidResponse, response.code
|
|
@@ -65,7 +74,7 @@ class Hkp
|
|
|
65
74
|
if String === options
|
|
66
75
|
options = { keyserver: options }
|
|
67
76
|
end
|
|
68
|
-
@keyserver = options.delete(:keyserver) || lookup_keyserver || '
|
|
77
|
+
@keyserver = options.delete(:keyserver) || lookup_keyserver || 'hkp://keyserver.ubuntu.com'
|
|
69
78
|
@options = { raise_errors: true }.merge options
|
|
70
79
|
end
|
|
71
80
|
|
|
@@ -83,7 +92,7 @@ class Hkp
|
|
|
83
92
|
# and what info they return besides the key id
|
|
84
93
|
def search(name)
|
|
85
94
|
[].tap do |results|
|
|
86
|
-
result = hkp_client.get "/pks/lookup?options=mr&search=#{URI.
|
|
95
|
+
result = hkp_client.get "/pks/lookup?op=index&options=mr&search=#{URI.encode_www_form_component(name)}"
|
|
87
96
|
|
|
88
97
|
result.each_line do |l|
|
|
89
98
|
components = l.strip.split(':')
|
|
@@ -101,7 +110,7 @@ class Hkp
|
|
|
101
110
|
|
|
102
111
|
# returns the key data as returned from the server as a string
|
|
103
112
|
def fetch(id)
|
|
104
|
-
result = hkp_client.get "/pks/lookup?options=mr&
|
|
113
|
+
result = hkp_client.get "/pks/lookup?op=get&options=mr&search=0x#{URI.encode_www_form_component(id)}"
|
|
105
114
|
return clean_key(result) if result
|
|
106
115
|
|
|
107
116
|
rescue Exception
|
|
@@ -142,7 +151,7 @@ class Hkp
|
|
|
142
151
|
def lookup_keyserver
|
|
143
152
|
url = nil
|
|
144
153
|
if res = exec_cmd("gpgconf --list-options gpgs 2>&1 | grep keyserver 2>&1")
|
|
145
|
-
url = URI.
|
|
154
|
+
url = URI.decode_www_form_component(res.split(":").last.split("\"").last.strip)
|
|
146
155
|
elsif res = exec_cmd("gpg --gpgconf-list 2>&1 | grep gpgconf-gpg.conf 2>&1")
|
|
147
156
|
conf_file = res.split(":").last.split("\"").last.strip
|
|
148
157
|
if res = exec_cmd("cat #{conf_file} 2>&1 | grep ^keyserver 2>&1")
|
data/lib/mail/gpg/version.rb
CHANGED
data/mail-gpg.gemspec
CHANGED
data/test/hkp_test.rb
CHANGED
|
@@ -4,7 +4,7 @@ require 'hkp'
|
|
|
4
4
|
|
|
5
5
|
class HkpTest < MailGpgTestCase
|
|
6
6
|
|
|
7
|
-
context "
|
|
7
|
+
context "hkp client" do
|
|
8
8
|
{
|
|
9
9
|
"http://pool.sks-keyservers.net:11371" => {
|
|
10
10
|
host: 'pool.sks-keyservers.net',
|
|
@@ -99,4 +99,222 @@ class HkpTest < MailGpgTestCase
|
|
|
99
99
|
|
|
100
100
|
end
|
|
101
101
|
|
|
102
|
+
context 'with mocked server' do
|
|
103
|
+
setup do
|
|
104
|
+
WebMock.disable_net_connect!
|
|
105
|
+
@keyserver = 'hkp://keys.example.com'
|
|
106
|
+
@hkp = Hkp.new(keyserver: @keyserver)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
teardown do
|
|
110
|
+
WebMock.allow_net_connect!
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
context 'search' do
|
|
114
|
+
should 'include op=index parameter in request' do
|
|
115
|
+
stub_request(:get, "http://keys.example.com:11371/pks/lookup")
|
|
116
|
+
.with(query: hash_including('op' => 'index'))
|
|
117
|
+
.to_return(status: 200, body: "info:1:1\npub:ABC123:1:2048:1234567890::\nuid:Test User <test@example.com>:1234567890::")
|
|
118
|
+
|
|
119
|
+
result = @hkp.search('test@example.com')
|
|
120
|
+
assert_requested :get, "http://keys.example.com:11371/pks/lookup",
|
|
121
|
+
query: hash_including('op' => 'index', 'search' => 'test@example.com')
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
should 'properly encode special characters in search query' do
|
|
125
|
+
stub_request(:get, /keys\.example\.com/)
|
|
126
|
+
.to_return(status: 200, body: "info:1:1\npub:ABC123:1:2048:1234567890::\n")
|
|
127
|
+
|
|
128
|
+
@hkp.search('test+user@example.com')
|
|
129
|
+
|
|
130
|
+
# Should use proper URL encoding, + should become %2B
|
|
131
|
+
assert_requested :get, "http://keys.example.com:11371/pks/lookup",
|
|
132
|
+
query: hash_including('search' => 'test+user@example.com')
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
should 'parse machine readable response' do
|
|
136
|
+
stub_request(:get, /keys\.example\.com/)
|
|
137
|
+
.to_return(status: 200, body: <<~RESPONSE)
|
|
138
|
+
info:1:2
|
|
139
|
+
pub:ABC123DEF456:1:2048:1234567890::
|
|
140
|
+
uid:Test User <test@example.com>:1234567890::
|
|
141
|
+
pub:789GHI012JKL:1:4096:1234567891::
|
|
142
|
+
uid:Another User <another@example.com>:1234567891::
|
|
143
|
+
RESPONSE
|
|
144
|
+
|
|
145
|
+
result = @hkp.search('example.com')
|
|
146
|
+
|
|
147
|
+
assert_equal 2, result.size
|
|
148
|
+
assert_equal 'ABC123DEF456', result[0][0]
|
|
149
|
+
assert_equal '789GHI012JKL', result[1][0]
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
should 'return empty array when no keys found' do
|
|
153
|
+
stub_request(:get, /keys\.example\.com/)
|
|
154
|
+
.to_return(status: 200, body: "info:1:0\n")
|
|
155
|
+
|
|
156
|
+
result = @hkp.search('nonexistent@example.com')
|
|
157
|
+
|
|
158
|
+
assert_equal [], result
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
should 'raise error on server error when raise_errors is true' do
|
|
162
|
+
stub_request(:get, /keys\.example\.com/)
|
|
163
|
+
.to_return(status: 500, body: "Internal Server Error")
|
|
164
|
+
|
|
165
|
+
assert_raises(Hkp::InvalidResponse) do
|
|
166
|
+
@hkp.search('test@example.com')
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
should 'return nil on server error when raise_errors is false' do
|
|
171
|
+
hkp = Hkp.new(keyserver: @keyserver, raise_errors: false)
|
|
172
|
+
stub_request(:get, /keys\.example\.com/)
|
|
173
|
+
.to_return(status: 500, body: "Internal Server Error")
|
|
174
|
+
|
|
175
|
+
result = hkp.search('test@example.com')
|
|
176
|
+
|
|
177
|
+
assert_nil result
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
context 'fetch' do
|
|
182
|
+
should 'include op=get parameter in request' do
|
|
183
|
+
stub_request(:get, "http://keys.example.com:11371/pks/lookup")
|
|
184
|
+
.with(query: hash_including('op' => 'get'))
|
|
185
|
+
.to_return(status: 200, body: <<~KEY)
|
|
186
|
+
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
|
187
|
+
mQENBFxxxxxxx
|
|
188
|
+
-----END PGP PUBLIC KEY BLOCK-----
|
|
189
|
+
KEY
|
|
190
|
+
|
|
191
|
+
result = @hkp.fetch('ABC123')
|
|
192
|
+
assert_requested :get, "http://keys.example.com:11371/pks/lookup",
|
|
193
|
+
query: hash_including('op' => 'get', 'search' => '0xABC123')
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
should 'properly encode key id with special characters' do
|
|
197
|
+
stub_request(:get, /keys\.example\.com/)
|
|
198
|
+
.to_return(status: 200, body: <<~KEY)
|
|
199
|
+
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
|
200
|
+
mQENBFxxxxxxx
|
|
201
|
+
-----END PGP PUBLIC KEY BLOCK-----
|
|
202
|
+
KEY
|
|
203
|
+
|
|
204
|
+
# Key IDs shouldn't normally have special chars, but testing encoding anyway
|
|
205
|
+
@hkp.fetch('ABC+123')
|
|
206
|
+
|
|
207
|
+
assert_requested :get, "http://keys.example.com:11371/pks/lookup",
|
|
208
|
+
query: hash_including('search' => '0xABC+123')
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
should 'extract key from response' do
|
|
212
|
+
stub_request(:get, /keys\.example\.com/)
|
|
213
|
+
.to_return(status: 200, body: <<~RESPONSE)
|
|
214
|
+
Some header text
|
|
215
|
+
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
|
216
|
+
|
|
217
|
+
mQENBFxxxxxxx
|
|
218
|
+
=xxxx
|
|
219
|
+
-----END PGP PUBLIC KEY BLOCK-----
|
|
220
|
+
Some footer text
|
|
221
|
+
RESPONSE
|
|
222
|
+
|
|
223
|
+
result = @hkp.fetch('ABC123')
|
|
224
|
+
|
|
225
|
+
assert result.start_with?('-----BEGIN PGP PUBLIC KEY BLOCK-----')
|
|
226
|
+
assert result.end_with?('-----END PGP PUBLIC KEY BLOCK-----')
|
|
227
|
+
refute result.include?('Some header text')
|
|
228
|
+
refute result.include?('Some footer text')
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
should 'return nil when key not found' do
|
|
232
|
+
stub_request(:get, /keys\.example\.com/)
|
|
233
|
+
.to_return(status: 404, body: "Not Found")
|
|
234
|
+
|
|
235
|
+
hkp = Hkp.new(keyserver: @keyserver, raise_errors: false)
|
|
236
|
+
result = hkp.fetch('NONEXISTENT')
|
|
237
|
+
|
|
238
|
+
assert_nil result
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
should 'return nil when response has no valid key block' do
|
|
242
|
+
stub_request(:get, /keys\.example\.com/)
|
|
243
|
+
.to_return(status: 200, body: "No key here")
|
|
244
|
+
|
|
245
|
+
result = @hkp.fetch('ABC123')
|
|
246
|
+
|
|
247
|
+
assert_nil result
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
context 'redirects' do
|
|
252
|
+
should 'follow same-host redirects' do
|
|
253
|
+
stub_request(:get, "http://keys.example.com:11371/pks/lookup")
|
|
254
|
+
.with(query: hash_including('op' => 'index', 'search' => 'test'))
|
|
255
|
+
.to_return(status: 302, headers: { 'Location' => '/pks/lookup?op=index&options=mr&search=test&new=1' })
|
|
256
|
+
|
|
257
|
+
stub_request(:get, "http://keys.example.com:11371/pks/lookup")
|
|
258
|
+
.with(query: hash_including('op' => 'index', 'new' => '1'))
|
|
259
|
+
.to_return(status: 200, body: "info:1:1\npub:ABC123:1:2048:1234567890::\n")
|
|
260
|
+
|
|
261
|
+
result = @hkp.search('test')
|
|
262
|
+
assert_equal 1, result.size
|
|
263
|
+
assert_equal 'ABC123', result[0][0]
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
should 'follow cross-host redirects' do
|
|
267
|
+
stub_request(:get, "http://keys.example.com:11371/pks/lookup")
|
|
268
|
+
.with(query: hash_including('op' => 'index'))
|
|
269
|
+
.to_return(status: 302, headers: { 'Location' => 'http://keys2.example.com/pks/lookup?op=index&options=mr&search=test' })
|
|
270
|
+
|
|
271
|
+
stub_request(:get, "http://keys2.example.com:80/pks/lookup")
|
|
272
|
+
.with(query: hash_including('op' => 'index'))
|
|
273
|
+
.to_return(status: 200, body: "info:1:1\npub:DEF456:1:2048:1234567890::\n")
|
|
274
|
+
|
|
275
|
+
result = @hkp.search('test')
|
|
276
|
+
assert_equal 1, result.size
|
|
277
|
+
assert_equal 'DEF456', result[0][0]
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
should 'raise TooManyRedirects after MAX_REDIRECTS' do
|
|
281
|
+
stub_request(:get, /keys\.example\.com/)
|
|
282
|
+
.to_return(status: 302, headers: { 'Location' => 'http://keys.example.com:11371/pks/lookup?op=index&search=test' })
|
|
283
|
+
|
|
284
|
+
assert_raises(Hkp::TooManyRedirects) do
|
|
285
|
+
@hkp.search('test')
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
context 'lookup_keyserver' do
|
|
292
|
+
setup do
|
|
293
|
+
WebMock.disable_net_connect!
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
teardown do
|
|
297
|
+
WebMock.allow_net_connect!
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
should 'decode percent-encoded keyserver URL from gpgconf' do
|
|
301
|
+
# Create a testable subclass that stubs exec_cmd
|
|
302
|
+
hkp_class = Class.new(Hkp) do
|
|
303
|
+
def exec_cmd(cmd)
|
|
304
|
+
if cmd.include?('gpgconf --list-options')
|
|
305
|
+
# Simulated gpgconf output with percent-encoded URL
|
|
306
|
+
# Format: name:flags:value (value may be quoted)
|
|
307
|
+
"keyserver:0:hkp%3A%2F%2Fkeys.example.com\n"
|
|
308
|
+
else
|
|
309
|
+
nil
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
hkp = hkp_class.new
|
|
315
|
+
keyserver = hkp.instance_variable_get('@keyserver')
|
|
316
|
+
assert_equal 'hkp://keys.example.com', keyserver
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
|
|
102
320
|
end
|
data/test/message_test.rb
CHANGED
|
@@ -53,8 +53,6 @@ class MessageTest < MailGpgTestCase
|
|
|
53
53
|
@mail.deliver
|
|
54
54
|
@signed = Mail.new @mails.first.to_s
|
|
55
55
|
@verified = @signed.verify
|
|
56
|
-
# Mail gem from 2.7.1 onwards converts "\n" to "\r\n"
|
|
57
|
-
@body = Mail::Utilities.to_crlf(@body)
|
|
58
56
|
end
|
|
59
57
|
|
|
60
58
|
should 'keep body unchanged' do
|
|
@@ -88,7 +86,7 @@ class MessageTest < MailGpgTestCase
|
|
|
88
86
|
body "and\nanother part euro €"
|
|
89
87
|
end
|
|
90
88
|
@mail.add_part p
|
|
91
|
-
#
|
|
89
|
+
# attachment bodies are returned as binary
|
|
92
90
|
@attachment_data = "this is\n € not an image".force_encoding(Encoding::BINARY)
|
|
93
91
|
@mail.attachments['test.jpg'] = { mime_type: 'image/jpeg',
|
|
94
92
|
content: @attachment_data }
|
|
@@ -106,7 +104,7 @@ class MessageTest < MailGpgTestCase
|
|
|
106
104
|
should 'have original three parts' do
|
|
107
105
|
assert_equal 3, @verified.parts.size
|
|
108
106
|
assert_equal 'i am unencrypted', @verified.parts[0].body.to_s
|
|
109
|
-
assert_equal "and\
|
|
107
|
+
assert_equal "and\nanother part euro €", @verified.parts[1].body.to_s.force_encoding('UTF-8')
|
|
110
108
|
assert attachment = @verified.parts[2]
|
|
111
109
|
assert attachment.attachment?
|
|
112
110
|
assert_equal "attachment; filename=test.jpg", attachment.content_disposition
|
|
@@ -141,8 +139,8 @@ class MessageTest < MailGpgTestCase
|
|
|
141
139
|
assert_equal 3, @mail.parts.size
|
|
142
140
|
assert_equal 3, @verified.parts.size
|
|
143
141
|
assert_equal 'i am unencrypted', @verified.parts[0].body.to_s
|
|
144
|
-
assert_equal "and\
|
|
145
|
-
assert_equal "and an\
|
|
142
|
+
assert_equal "and\nanother part euro €", @verified.parts[1].body.to_s.force_encoding('UTF-8')
|
|
143
|
+
assert_equal "and an\nHTML part €", @verified.parts[2].body.to_s.force_encoding('UTF-8')
|
|
146
144
|
end
|
|
147
145
|
end
|
|
148
146
|
|
|
@@ -227,7 +225,7 @@ class MessageTest < MailGpgTestCase
|
|
|
227
225
|
assert decrypted = m.decrypt(:password => 'abc', verify: true)
|
|
228
226
|
assert_equal 'test', decrypted.subject
|
|
229
227
|
assert decrypted == @mail
|
|
230
|
-
assert_equal "one\
|
|
228
|
+
assert_equal "one\neuro €", decrypted.body.to_s.force_encoding('UTF-8')
|
|
231
229
|
assert decrypted.signature_valid?
|
|
232
230
|
assert_equal 1, decrypted.signatures.size
|
|
233
231
|
end
|
data/test/test_helper.rb
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
require 'open3'
|
|
2
2
|
require 'test/unit'
|
|
3
3
|
require 'shoulda/context'
|
|
4
|
+
require 'webmock/test_unit'
|
|
4
5
|
require 'mail-gpg'
|
|
5
6
|
require 'action_mailer'
|
|
6
7
|
require 'securerandom'
|
|
7
8
|
require 'byebug'
|
|
8
9
|
|
|
10
|
+
# Allow real connections by default, individual tests can disable
|
|
11
|
+
WebMock.allow_net_connect!
|
|
12
|
+
|
|
9
13
|
Mail.defaults do
|
|
10
14
|
delivery_method :test
|
|
11
15
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mail-gpg
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jens Kraemer
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-01-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: mail
|
|
@@ -134,6 +134,20 @@ dependencies:
|
|
|
134
134
|
- - "~>"
|
|
135
135
|
- !ruby/object:Gem::Version
|
|
136
136
|
version: '1.1'
|
|
137
|
+
- !ruby/object:Gem::Dependency
|
|
138
|
+
name: webmock
|
|
139
|
+
requirement: !ruby/object:Gem::Requirement
|
|
140
|
+
requirements:
|
|
141
|
+
- - "~>"
|
|
142
|
+
- !ruby/object:Gem::Version
|
|
143
|
+
version: '3.0'
|
|
144
|
+
type: :development
|
|
145
|
+
prerelease: false
|
|
146
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
147
|
+
requirements:
|
|
148
|
+
- - "~>"
|
|
149
|
+
- !ruby/object:Gem::Version
|
|
150
|
+
version: '3.0'
|
|
137
151
|
description: |-
|
|
138
152
|
GPG/MIME encryption plugin for the Ruby Mail Library
|
|
139
153
|
This tiny gem adds GPG capabilities to Mail::Message and ActionMailer::Base. Because privacy matters.
|
|
@@ -143,8 +157,8 @@ executables: []
|
|
|
143
157
|
extensions: []
|
|
144
158
|
extra_rdoc_files: []
|
|
145
159
|
files:
|
|
160
|
+
- ".github/workflows/test.yml"
|
|
146
161
|
- ".gitignore"
|
|
147
|
-
- ".travis.yml"
|
|
148
162
|
- Gemfile
|
|
149
163
|
- History.txt
|
|
150
164
|
- LICENSE.txt
|
|
@@ -179,7 +193,6 @@ files:
|
|
|
179
193
|
- test/gpghome/gpg-agent.conf
|
|
180
194
|
- test/gpghome/pubring.gpg
|
|
181
195
|
- test/gpghome/pubring.gpg~
|
|
182
|
-
- test/gpghome/random_seed
|
|
183
196
|
- test/gpghome/secring.gpg
|
|
184
197
|
- test/gpghome/trustdb.gpg
|
|
185
198
|
- test/gpgme_helper_test.rb
|
|
@@ -194,7 +207,7 @@ homepage: https://github.com/jkraemer/mail-gpg
|
|
|
194
207
|
licenses:
|
|
195
208
|
- MIT
|
|
196
209
|
metadata: {}
|
|
197
|
-
post_install_message:
|
|
210
|
+
post_install_message:
|
|
198
211
|
rdoc_options: []
|
|
199
212
|
require_paths:
|
|
200
213
|
- lib
|
|
@@ -209,9 +222,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
209
222
|
- !ruby/object:Gem::Version
|
|
210
223
|
version: '0'
|
|
211
224
|
requirements: []
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
signing_key:
|
|
225
|
+
rubygems_version: 3.5.22
|
|
226
|
+
signing_key:
|
|
215
227
|
specification_version: 4
|
|
216
228
|
summary: GPG/MIME encryption plugin for the Ruby Mail Library
|
|
217
229
|
test_files:
|
|
@@ -222,7 +234,6 @@ test_files:
|
|
|
222
234
|
- test/gpghome/gpg-agent.conf
|
|
223
235
|
- test/gpghome/pubring.gpg
|
|
224
236
|
- test/gpghome/pubring.gpg~
|
|
225
|
-
- test/gpghome/random_seed
|
|
226
237
|
- test/gpghome/secring.gpg
|
|
227
238
|
- test/gpghome/trustdb.gpg
|
|
228
239
|
- test/gpgme_helper_test.rb
|
data/.travis.yml
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
language: ruby
|
|
2
|
-
rvm:
|
|
3
|
-
- 2.6.3
|
|
4
|
-
- 2.5.5
|
|
5
|
-
- 2.4.6
|
|
6
|
-
env:
|
|
7
|
-
- RAILS=4.2.11.1 GPG_BIN=/usr/bin/gpg2
|
|
8
|
-
- RAILS=4.2.11.1 GPG_BIN=/usr/bin/gpg
|
|
9
|
-
- RAILS=5.2.3 GPG_BIN=/usr/bin/gpg2
|
|
10
|
-
- RAILS=5.2.3 GPG_BIN=/usr/bin/gpg
|
|
11
|
-
matrix:
|
|
12
|
-
exclude:
|
|
13
|
-
before_install:
|
|
14
|
-
- gem install bundler -v "~> 2.0"
|
|
15
|
-
- sudo apt install -y gnupg gnupg2
|
|
16
|
-
cache: bundler
|
|
17
|
-
dist: xenial
|
|
18
|
-
addons:
|
|
19
|
-
apt:
|
|
20
|
-
update: true
|
|
21
|
-
|
data/test/gpghome/random_seed
DELETED
|
Binary file
|