mail-gpg 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/History.txt +9 -0
- data/README.md +58 -20
- data/lib/mail/gpg.rb +13 -5
- data/lib/mail/gpg/delivery_handler.rb +24 -0
- data/lib/mail/gpg/encrypted_part.rb +4 -4
- data/lib/mail/gpg/message_patch.rb +56 -0
- data/lib/mail/gpg/rails.rb +8 -0
- data/lib/mail/gpg/rails/action_mailer_base_patch.rb +44 -0
- data/lib/mail/gpg/version.rb +1 -1
- data/mail-gpg.gemspec +3 -2
- data/test/action_mailer_test.rb +46 -0
- data/test/gpg_test.rb +73 -17
- data/test/message_test.rb +92 -0
- data/test/test_helper.rb +5 -0
- metadata +56 -17
- checksums.yaml +0 -7
data/.gitignore
CHANGED
data/History.txt
ADDED
data/README.md
CHANGED
@@ -21,33 +21,58 @@ Or install it yourself as:
|
|
21
21
|
## Usage
|
22
22
|
|
23
23
|
### Encrypting / Signing
|
24
|
-
Construct your Mail object as usual and
|
25
|
-
|
24
|
+
Construct your Mail object as usual and specify you want it to be encrypted
|
25
|
+
with the gpg method:
|
26
26
|
|
27
|
-
|
27
|
+
Mail.new do
|
28
28
|
to 'jane@doe.net'
|
29
29
|
from 'john@doe.net'
|
30
30
|
subject 'gpg test'
|
31
31
|
body "encrypt me!"
|
32
32
|
add_file "some_attachment.zip"
|
33
|
-
end
|
34
33
|
|
35
|
-
|
36
|
-
|
34
|
+
# encrypt message, no signing
|
35
|
+
gpg true
|
36
|
+
|
37
|
+
# encrypt and sign message with sender's private key, using the given
|
38
|
+
# passphrase to decrypt the key
|
39
|
+
gpg sign: true, password: 'secret'
|
40
|
+
|
41
|
+
# encrypt and sign message using a different key
|
42
|
+
gpg sign_as: 'joe@otherdomain.com', password: 'secret'
|
43
|
+
|
37
44
|
|
38
|
-
|
39
|
-
|
40
|
-
|
45
|
+
# encrypt and sign message and use a callback function to provide the
|
46
|
+
# passphrase.
|
47
|
+
gpg sign_as: 'joe@otherdomain.com',
|
48
|
+
passphrase_callback: ->(obj, uid_hint, passphrase_info, prev_was_bad, fd){puts "Enter passphrase for #{passphrase_info}: "; (IO.for_fd(fd, 'w') << readline.chomp).flush }
|
49
|
+
end.deliver
|
41
50
|
|
42
|
-
# encrypt and sign message using a different key
|
43
|
-
Mail::Gpg.encrypt(m, sign_as: 'joe@otherdomain.com', password: 'secret').deliver
|
44
51
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
52
|
+
Make sure all recipients' public keys are present in your local gpg keychain.
|
53
|
+
You will get errors in case encryption is not possible due to missing keys.
|
54
|
+
If you collect public key data from your users, you can specify the ascii
|
55
|
+
armored key data for recipients using the `:keys` option like this:
|
49
56
|
|
50
|
-
|
57
|
+
johns_key = <<-END
|
58
|
+
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
59
|
+
Version: GnuPG v1.4.12 (GNU/Linux)
|
60
|
+
|
61
|
+
mQGiBEk39msRBADw1ExmrLD1OUMdfvA7cnVVYTC7CyqfNvHUVuuBDhV7azs
|
62
|
+
....
|
63
|
+
END
|
64
|
+
|
65
|
+
Mail.new do
|
66
|
+
to 'john@foo.bar'
|
67
|
+
gpg keys: { 'john@foo.bar' => johns_key }
|
68
|
+
end
|
69
|
+
|
70
|
+
The key will then be imported before actually trying to encrypt/send the mail.
|
71
|
+
SoiIn theory you only need to specify the key once like that, however doing it
|
72
|
+
every time does not hurt as gpg is clever enough to recognize known keys, only
|
73
|
+
updating it's db when necessary.
|
74
|
+
|
75
|
+
You may also want to have a look at the [GPGME](https://github.com/ueno/ruby-gpgme) docs and code base for more info on the various options, especially regarding the `passphrase_callback` arguments.
|
51
76
|
|
52
77
|
|
53
78
|
### Signing only
|
@@ -55,22 +80,35 @@ Make sure all recipients' public keys are in your local gpg keychain. You may al
|
|
55
80
|
This is not implemented yet
|
56
81
|
|
57
82
|
|
83
|
+
## Rails / ActionMailer integration
|
84
|
+
|
85
|
+
class MyMailer < ActionMailer::Base
|
86
|
+
default from: 'baz@bar.com'
|
87
|
+
def some_mail
|
88
|
+
mail to: 'foo@bar.com', subject: 'subject!', gpg: true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
The gpg option takes the same arguments as outlined above for the
|
93
|
+
Mail::Message#gpg method.
|
94
|
+
|
58
95
|
## Running the tests
|
59
96
|
|
60
|
-
rake
|
97
|
+
bundle exec rake
|
61
98
|
|
62
|
-
The first run
|
63
|
-
test/gpghome containing two different identities used in the test cases.
|
99
|
+
The first run will take a while since it sets up a mock gpg home directory in
|
100
|
+
`test/gpghome` containing two different identities used in the test cases.
|
64
101
|
Following test runs will use that directory if it still exists and will
|
65
102
|
therefore be substantially faster.
|
66
103
|
|
67
104
|
## Todo
|
68
105
|
|
69
106
|
* Signing of unencrypted mails
|
107
|
+
* Decryption
|
108
|
+
* Signature verification
|
70
109
|
* Add optional on the fly import of recipients' keys from public key servers based on email address
|
71
110
|
* Send encrypted mails to recipients when possible, fall back to unencrypted
|
72
111
|
mail otherwise
|
73
|
-
* Ease and document usage with Rails' ActionMailer
|
74
112
|
|
75
113
|
|
76
114
|
## Contributing
|
data/lib/mail/gpg.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
require 'mail'
|
2
|
+
require 'mail/message'
|
2
3
|
require 'gpgme'
|
3
4
|
|
4
5
|
require 'mail/gpg/version'
|
5
6
|
require 'mail/gpg/version_part'
|
6
7
|
require 'mail/gpg/encrypted_part'
|
8
|
+
require 'mail/gpg/message_patch'
|
9
|
+
require 'mail/gpg/rails'
|
7
10
|
|
8
11
|
module Mail
|
9
12
|
module Gpg
|
@@ -11,6 +14,9 @@ module Mail
|
|
11
14
|
# :sign : sign message using the sender's private key
|
12
15
|
# :sign_as : sign using this key (give the corresponding email address)
|
13
16
|
# :passphrase: passphrase for the signing key
|
17
|
+
# :keys : A hash mapping recipient email addresses to public keys or public
|
18
|
+
# key ids. Imports any keys given here that are not already part of the
|
19
|
+
# local keychain before sending the mail.
|
14
20
|
# :always_trust : send encrypted mail to untrusted receivers, true by default
|
15
21
|
def self.encrypt(cleartext_mail, options = {})
|
16
22
|
receivers = []
|
@@ -26,11 +32,13 @@ module Mail
|
|
26
32
|
end
|
27
33
|
|
28
34
|
Mail.new do
|
29
|
-
|
30
|
-
to
|
31
|
-
|
32
|
-
|
33
|
-
|
35
|
+
self.perform_deliveries = cleartext_mail.perform_deliveries
|
36
|
+
%w(from to cc bcc subject reply_to in_reply_to).each do |field|
|
37
|
+
send field, cleartext_mail.send(field)
|
38
|
+
end
|
39
|
+
cleartext_mail.header.fields.each do |field|
|
40
|
+
header[field.name] = field.value if field.name =~ /^X-/
|
41
|
+
end
|
34
42
|
add_part VersionPart.new
|
35
43
|
add_part EncryptedPart.new(cleartext_mail,
|
36
44
|
options.merge({recipients: receivers}))
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Mail
|
2
|
+
module Gpg
|
3
|
+
class DeliveryHandler
|
4
|
+
|
5
|
+
def self.deliver_mail(mail)
|
6
|
+
if mail.gpg
|
7
|
+
encrypted_mail = nil
|
8
|
+
begin
|
9
|
+
options = TrueClass === mail.gpg ? {} : mail.gpg
|
10
|
+
encrypted_mail = Mail::Gpg.encrypt(mail, options)
|
11
|
+
rescue Exception
|
12
|
+
raise $! if mail.raise_encryption_errors
|
13
|
+
end
|
14
|
+
encrypted_mail.deliver if encrypted_mail
|
15
|
+
else
|
16
|
+
yield
|
17
|
+
end
|
18
|
+
rescue Exception
|
19
|
+
raise $! if mail.raise_delivery_errors
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -3,16 +3,16 @@ module Mail
|
|
3
3
|
class EncryptedPart < Mail::Part
|
4
4
|
|
5
5
|
# options are:
|
6
|
+
#
|
6
7
|
# :signers : sign using this key (give the corresponding email address)
|
7
8
|
# :passphrase: passphrase for the signing key
|
8
9
|
# :recipients : array of receiver addresses
|
10
|
+
# :keys : A hash mapping recipient email addresses to public keys or public
|
11
|
+
# key ids. Imports any keys given here that are not already part of the
|
12
|
+
# local keychain before sending the mail.
|
9
13
|
# :always_trust : send encrypted mail to untrusted receivers, true by default
|
10
14
|
def initialize(cleartext_mail, options = {})
|
11
15
|
options = { always_trust: true }.merge options
|
12
|
-
#clear_part = Mail.new
|
13
|
-
#parts.each do |p|
|
14
|
-
# clear_part.add_part p
|
15
|
-
#end
|
16
16
|
|
17
17
|
encrypted = encrypt(cleartext_mail.encoded, options)
|
18
18
|
super() do
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'mail/gpg/delivery_handler'
|
2
|
+
|
3
|
+
module Mail
|
4
|
+
module Gpg
|
5
|
+
module MessagePatch
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.class_eval do
|
9
|
+
attr_accessor :raise_encryption_errors
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# turn on gpg encryption / set gpg options.
|
14
|
+
#
|
15
|
+
# options are:
|
16
|
+
#
|
17
|
+
# encrypt: encrypt the message. defaults to true
|
18
|
+
# sign: also sign the message. false by default
|
19
|
+
# sign_as: UIDs to sign the message with
|
20
|
+
#
|
21
|
+
# See Mail::Gpg methods encrypt and sign for more
|
22
|
+
# possible options
|
23
|
+
#
|
24
|
+
# mail.gpg true
|
25
|
+
# mail.gpg sign_as: 'jane@doe.com', encrypt: false
|
26
|
+
#
|
27
|
+
# To turn off gpg encryption use:
|
28
|
+
# mail.gpg false
|
29
|
+
#
|
30
|
+
def gpg(options = nil)
|
31
|
+
case options
|
32
|
+
when nil
|
33
|
+
@gpg
|
34
|
+
when false
|
35
|
+
@gpg = nil
|
36
|
+
if Mail::Gpg::DeliveryHandler == delivery_handler
|
37
|
+
self.delivery_handler = nil
|
38
|
+
end
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
if options
|
42
|
+
self.raise_encryption_errors = true if raise_encryption_errors.nil?
|
43
|
+
@gpg = options
|
44
|
+
self.delivery_handler ||= Mail::Gpg::DeliveryHandler
|
45
|
+
else
|
46
|
+
@gpg
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
unless Mail::Message.included_modules.include?(Mail::Gpg::MessagePatch)
|
55
|
+
Mail::Message.send :include, Mail::Gpg::MessagePatch
|
56
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'action_mailer/base'
|
2
|
+
|
3
|
+
module Mail
|
4
|
+
module Gpg
|
5
|
+
module Rails
|
6
|
+
|
7
|
+
module ActionMailerPatch
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
alias_method_chain :mail, :gpg
|
12
|
+
class << self
|
13
|
+
alias_method_chain :deliver_mail, :gpg
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def mail_with_gpg(headers = {}, &block)
|
18
|
+
headers = headers.dup
|
19
|
+
gpg_options = headers.delete :gpg
|
20
|
+
mail_without_gpg(headers, &block).tap do |m|
|
21
|
+
if gpg_options
|
22
|
+
m.gpg gpg_options
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
def deliver_mail_with_gpg(mail, &block)
|
29
|
+
deliver_mail_without_gpg(mail) do
|
30
|
+
Mail::Gpg::DeliveryHandler.deliver_mail mail, &block
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
unless ActionMailer::Base.included_modules.include?(ActionMailerPatch)
|
38
|
+
ActionMailer::Base.send :include, ActionMailerPatch
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
data/lib/mail/gpg/version.rb
CHANGED
data/mail-gpg.gemspec
CHANGED
@@ -8,9 +8,9 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Mail::Gpg::VERSION
|
9
9
|
spec.authors = ["Jens Kraemer"]
|
10
10
|
spec.email = ["jk@jkraemer.net"]
|
11
|
-
spec.description = "GPG/MIME encryption plugin for the Ruby Mail Library\
|
11
|
+
spec.description = "GPG/MIME encryption plugin for the Ruby Mail Library\nThis tiny gem adds GPG capabilities to Mail::Message and ActionMailer::Base. Because privacy matters."
|
12
12
|
spec.summary = %q{GPG/MIME encryption plugin for the Ruby Mail Library}
|
13
|
-
spec.homepage = ""
|
13
|
+
spec.homepage = "https://github.com/jkraemer/mail-gpg"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_dependency "gpgme", "~> 2.0.2"
|
23
23
|
spec.add_development_dependency "bundler", "~> 1.3"
|
24
24
|
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "actionmailer", ">= 3.2.0"
|
25
26
|
spec.add_development_dependency "pry-nav"
|
26
27
|
spec.add_development_dependency "shoulda-context"
|
27
28
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class MyMailer < ActionMailer::Base
|
4
|
+
default from: 'joe@foo.bar', to: 'jane@foo.bar'
|
5
|
+
|
6
|
+
def unencrypted
|
7
|
+
mail subject: 'unencrypted', body: 'unencrypted mail'
|
8
|
+
end
|
9
|
+
|
10
|
+
def encrypted
|
11
|
+
mail subject: 'encrypted', body: 'encrypted mail', gpg: true
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
class ActionMailerTest < Test::Unit::TestCase
|
18
|
+
context "with action mailer" do
|
19
|
+
setup do
|
20
|
+
(@emails = ActionMailer::Base.deliveries).clear
|
21
|
+
end
|
22
|
+
|
23
|
+
should "send unencrypted mail" do
|
24
|
+
MyMailer.unencrypted.deliver
|
25
|
+
assert_equal 1, @emails.size
|
26
|
+
assert m = @emails.first
|
27
|
+
assert_equal 'unencrypted', m.subject
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
should "send encrypted mail" do
|
32
|
+
assert m = MyMailer.encrypted
|
33
|
+
assert true == m.gpg
|
34
|
+
m.deliver
|
35
|
+
assert_equal 1, @emails.size
|
36
|
+
assert m = @emails.first
|
37
|
+
assert_equal 'encrypted', m.subject
|
38
|
+
assert_equal 2, m.parts.size
|
39
|
+
assert encrypted = m.parts.detect{|p| p.content_type =~ /encrypted\.asc/}
|
40
|
+
assert clear = GPGME::Crypto.new.decrypt(encrypted.body.to_s, password: 'abc')
|
41
|
+
m = Mail.new clear
|
42
|
+
assert_equal 'encrypted mail', m.body.to_s
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
data/test/gpg_test.rb
CHANGED
@@ -2,18 +2,32 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class GpgTest < Test::Unit::TestCase
|
4
4
|
|
5
|
-
def check_headers(mail, encrypted)
|
5
|
+
def check_headers(mail = @mail, encrypted = @encrypted)
|
6
6
|
assert_equal mail.to, encrypted.to
|
7
7
|
assert_equal mail.cc, encrypted.cc
|
8
8
|
assert_equal mail.bcc, encrypted.bcc
|
9
9
|
assert_equal mail.subject, encrypted.subject
|
10
10
|
end
|
11
11
|
|
12
|
-
def check_mime_structure(mail, encrypted)
|
12
|
+
def check_mime_structure(mail = @mail, encrypted = @encrypted)
|
13
13
|
assert_equal 2, encrypted.parts.size
|
14
|
-
|
14
|
+
v_part, enc_part = encrypted.parts
|
15
|
+
|
16
|
+
assert_match /Version 1/, v_part.to_s
|
17
|
+
assert_equal 'application/pgp-encrypted; charset=UTF-8', v_part.content_type
|
18
|
+
|
19
|
+
assert_equal 'application/octet-stream; name=encrypted.asc',
|
20
|
+
enc_part.content_type
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def check_content
|
25
|
+
assert enc = @encrypted.parts.last
|
26
|
+
assert clear = GPGME::Crypto.new.decrypt(enc.to_s, password: 'abc').to_s
|
27
|
+
assert_match /encrypt me/, clear
|
15
28
|
end
|
16
29
|
|
30
|
+
|
17
31
|
context "gpg installation" do
|
18
32
|
should "have keys for jane and joe" do
|
19
33
|
assert joe = GPGME::Key.find(:public, 'joe@foo.bar').first
|
@@ -32,58 +46,100 @@ class GpgTest < Test::Unit::TestCase
|
|
32
46
|
end
|
33
47
|
end
|
34
48
|
|
35
|
-
|
36
|
-
context 'mail with multiple recipients' do
|
49
|
+
context 'simple mail' do
|
37
50
|
setup do
|
38
|
-
# @mail.bcc 'joe@foo.bar'
|
39
51
|
@encrypted = Mail::Gpg.encrypt(@mail)
|
40
52
|
end
|
41
53
|
|
42
54
|
should 'have same recipients and subject' do
|
43
|
-
check_headers
|
55
|
+
check_headers
|
44
56
|
end
|
45
57
|
|
46
58
|
should 'have proper gpgmime structure' do
|
47
|
-
check_mime_structure
|
59
|
+
check_mime_structure
|
48
60
|
end
|
49
61
|
|
50
|
-
should
|
51
|
-
|
62
|
+
should 'have correctly encrypted content' do
|
63
|
+
check_content
|
52
64
|
end
|
53
65
|
|
54
66
|
end
|
55
67
|
|
56
|
-
context '
|
68
|
+
context 'mail with custom header' do
|
57
69
|
setup do
|
58
|
-
@mail.
|
70
|
+
@mail.header['X-Custom-Header'] = 'custom value'
|
59
71
|
@encrypted = Mail::Gpg.encrypt(@mail)
|
60
72
|
end
|
61
73
|
|
62
74
|
should 'have same recipients and subject' do
|
63
|
-
check_headers
|
75
|
+
check_headers
|
64
76
|
end
|
65
77
|
|
66
78
|
should 'have proper gpgmime structure' do
|
67
|
-
check_mime_structure
|
79
|
+
check_mime_structure
|
80
|
+
end
|
81
|
+
|
82
|
+
should 'have correctly encrypted content' do
|
83
|
+
check_content
|
84
|
+
end
|
85
|
+
|
86
|
+
should 'preserve customer header values' do
|
87
|
+
assert_equal 'custom value', @encrypted.header['X-Custom-Header'].to_s
|
68
88
|
end
|
69
89
|
end
|
70
90
|
|
71
|
-
context '
|
91
|
+
context 'mail with multiple recipients' do
|
72
92
|
setup do
|
93
|
+
@mail.bcc 'joe@foo.bar'
|
73
94
|
@encrypted = Mail::Gpg.encrypt(@mail)
|
74
95
|
end
|
75
96
|
|
76
97
|
should 'have same recipients and subject' do
|
77
|
-
check_headers
|
98
|
+
check_headers
|
78
99
|
end
|
79
100
|
|
80
101
|
should 'have proper gpgmime structure' do
|
81
|
-
check_mime_structure
|
102
|
+
check_mime_structure
|
103
|
+
end
|
104
|
+
|
105
|
+
should 'have correctly encrypted content' do
|
106
|
+
check_content
|
107
|
+
end
|
108
|
+
|
109
|
+
should "encrypt for all recipients" do
|
110
|
+
assert encrypted_body = @encrypted.parts.last.to_s
|
82
111
|
end
|
83
112
|
|
84
113
|
end
|
85
114
|
|
115
|
+
context 'multipart mail' do
|
116
|
+
setup do
|
117
|
+
@mail.add_file 'Rakefile'
|
118
|
+
@encrypted = Mail::Gpg.encrypt(@mail)
|
119
|
+
end
|
120
|
+
|
121
|
+
should 'have same recipients and subject' do
|
122
|
+
check_headers
|
123
|
+
end
|
124
|
+
|
125
|
+
should 'have proper gpgmime structure' do
|
126
|
+
check_mime_structure
|
127
|
+
end
|
86
128
|
|
129
|
+
should 'have correctly encrypted content' do
|
130
|
+
check_content
|
131
|
+
end
|
132
|
+
|
133
|
+
should 'have multiple parts in encrypted content' do
|
134
|
+
assert encrypted_body = @encrypted.parts.last.to_s
|
135
|
+
assert clear = GPGME::Crypto.new.decrypt(encrypted_body.to_s, password: 'abc').to_s
|
136
|
+
assert m = Mail::Message.new(clear.to_s)
|
137
|
+
assert m.multipart?
|
138
|
+
assert_equal 2, m.parts.size
|
139
|
+
assert_match /encrypt me/, m.parts.first.body.to_s
|
140
|
+
assert_match /Rakefile/, m.parts.last.content_disposition
|
141
|
+
end
|
142
|
+
end
|
87
143
|
end
|
88
144
|
end
|
89
145
|
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class MessageTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "Mail::Message" do
|
6
|
+
|
7
|
+
setup do
|
8
|
+
(@mails = Mail::TestMailer.deliveries).clear
|
9
|
+
@mail = Mail.new do
|
10
|
+
to 'jane@foo.bar'
|
11
|
+
from 'joe@foo.bar'
|
12
|
+
subject 'test'
|
13
|
+
body 'i am unencrypted'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "with gpg turned off" do
|
18
|
+
setup do
|
19
|
+
@mail.deliver
|
20
|
+
end
|
21
|
+
|
22
|
+
should "deliver unencrypted mail as usual" do
|
23
|
+
assert_equal 1, @mails.size
|
24
|
+
assert m = @mails.first
|
25
|
+
assert_equal 'test', m.subject
|
26
|
+
assert_equal 'i am unencrypted', m.body.to_s
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "with gpg turned on" do
|
31
|
+
setup do
|
32
|
+
@mail.gpg true
|
33
|
+
end
|
34
|
+
|
35
|
+
context "with missing key" do
|
36
|
+
setup do
|
37
|
+
@mail.to = 'user@host.com'
|
38
|
+
end
|
39
|
+
|
40
|
+
should "raise encryption error" do
|
41
|
+
assert_raises(GPGME::Error::InvalidValue){
|
42
|
+
@mail.deliver
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
should "not raise error when encryption errors are turned off" do
|
47
|
+
@mail.raise_encryption_errors = false
|
48
|
+
@mail.deliver
|
49
|
+
assert_equal 0, @mails.size
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "" do
|
54
|
+
setup do
|
55
|
+
@mail.deliver
|
56
|
+
end
|
57
|
+
|
58
|
+
should "deliver encrypted mail" do
|
59
|
+
assert_equal 1, @mails.size
|
60
|
+
assert m = @mails.first
|
61
|
+
assert_equal 'test', m.subject
|
62
|
+
assert m.multipart?
|
63
|
+
assert enc_part = m.parts.last
|
64
|
+
assert clear = GPGME::Crypto.new.decrypt(enc_part.body.to_s, password: 'abc').to_s
|
65
|
+
assert m = Mail::Message.new(clear)
|
66
|
+
assert !m.multipart?
|
67
|
+
assert_equal 'i am unencrypted', m.body.to_s
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
should "respond to gpg method" do
|
73
|
+
assert Mail::Message.new.respond_to?(:gpg)
|
74
|
+
end
|
75
|
+
|
76
|
+
context "gpg method" do
|
77
|
+
|
78
|
+
should "set and unset delivery_handler" do
|
79
|
+
m = Mail.new do
|
80
|
+
gpg true
|
81
|
+
end
|
82
|
+
assert m.gpg
|
83
|
+
assert dh = m.delivery_handler
|
84
|
+
assert_equal Mail::Gpg::DeliveryHandler, dh
|
85
|
+
m.gpg false
|
86
|
+
assert_nil m.delivery_handler
|
87
|
+
assert_nil m.gpg
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mail-gpg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Jens Kraemer
|
@@ -13,6 +14,7 @@ dependencies:
|
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: mail
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
19
|
- - ~>
|
18
20
|
- !ruby/object:Gem::Version
|
@@ -20,6 +22,7 @@ dependencies:
|
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
27
|
- - ~>
|
25
28
|
- !ruby/object:Gem::Version
|
@@ -27,6 +30,7 @@ dependencies:
|
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
31
|
name: gpgme
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
35
|
- - ~>
|
32
36
|
- !ruby/object:Gem::Version
|
@@ -34,6 +38,7 @@ dependencies:
|
|
34
38
|
type: :runtime
|
35
39
|
prerelease: false
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
37
42
|
requirements:
|
38
43
|
- - ~>
|
39
44
|
- !ruby/object:Gem::Version
|
@@ -41,6 +46,7 @@ dependencies:
|
|
41
46
|
- !ruby/object:Gem::Dependency
|
42
47
|
name: bundler
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
44
50
|
requirements:
|
45
51
|
- - ~>
|
46
52
|
- !ruby/object:Gem::Version
|
@@ -48,6 +54,7 @@ dependencies:
|
|
48
54
|
type: :development
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
51
58
|
requirements:
|
52
59
|
- - ~>
|
53
60
|
- !ruby/object:Gem::Version
|
@@ -55,48 +62,71 @@ dependencies:
|
|
55
62
|
- !ruby/object:Gem::Dependency
|
56
63
|
name: rake
|
57
64
|
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
58
66
|
requirements:
|
59
|
-
- - '>='
|
67
|
+
- - ! '>='
|
60
68
|
- !ruby/object:Gem::Version
|
61
69
|
version: '0'
|
62
70
|
type: :development
|
63
71
|
prerelease: false
|
64
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
65
74
|
requirements:
|
66
|
-
- - '>='
|
75
|
+
- - ! '>='
|
67
76
|
- !ruby/object:Gem::Version
|
68
77
|
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: actionmailer
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 3.2.0
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 3.2.0
|
69
94
|
- !ruby/object:Gem::Dependency
|
70
95
|
name: pry-nav
|
71
96
|
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
72
98
|
requirements:
|
73
|
-
- - '>='
|
99
|
+
- - ! '>='
|
74
100
|
- !ruby/object:Gem::Version
|
75
101
|
version: '0'
|
76
102
|
type: :development
|
77
103
|
prerelease: false
|
78
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
79
106
|
requirements:
|
80
|
-
- - '>='
|
107
|
+
- - ! '>='
|
81
108
|
- !ruby/object:Gem::Version
|
82
109
|
version: '0'
|
83
110
|
- !ruby/object:Gem::Dependency
|
84
111
|
name: shoulda-context
|
85
112
|
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
86
114
|
requirements:
|
87
|
-
- - '>='
|
115
|
+
- - ! '>='
|
88
116
|
- !ruby/object:Gem::Version
|
89
117
|
version: '0'
|
90
118
|
type: :development
|
91
119
|
prerelease: false
|
92
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
93
122
|
requirements:
|
94
|
-
- - '>='
|
123
|
+
- - ! '>='
|
95
124
|
- !ruby/object:Gem::Version
|
96
125
|
version: '0'
|
97
|
-
description:
|
98
|
-
|
99
|
-
|
126
|
+
description: ! 'GPG/MIME encryption plugin for the Ruby Mail Library
|
127
|
+
|
128
|
+
This tiny gem adds GPG capabilities to Mail::Message and ActionMailer::Base. Because
|
129
|
+
privacy matters.'
|
100
130
|
email:
|
101
131
|
- jk@jkraemer.net
|
102
132
|
executables: []
|
@@ -105,43 +135,52 @@ extra_rdoc_files: []
|
|
105
135
|
files:
|
106
136
|
- .gitignore
|
107
137
|
- Gemfile
|
138
|
+
- History.txt
|
108
139
|
- LICENSE.txt
|
109
140
|
- README.md
|
110
141
|
- Rakefile
|
111
142
|
- lib/hkp.rb
|
112
143
|
- lib/mail-gpg.rb
|
113
144
|
- lib/mail/gpg.rb
|
145
|
+
- lib/mail/gpg/delivery_handler.rb
|
114
146
|
- lib/mail/gpg/encrypted_part.rb
|
147
|
+
- lib/mail/gpg/message_patch.rb
|
148
|
+
- lib/mail/gpg/rails.rb
|
149
|
+
- lib/mail/gpg/rails/action_mailer_base_patch.rb
|
115
150
|
- lib/mail/gpg/version.rb
|
116
151
|
- lib/mail/gpg/version_part.rb
|
117
152
|
- mail-gpg.gemspec
|
153
|
+
- test/action_mailer_test.rb
|
118
154
|
- test/gpg_test.rb
|
155
|
+
- test/message_test.rb
|
119
156
|
- test/test_helper.rb
|
120
|
-
homepage:
|
157
|
+
homepage: https://github.com/jkraemer/mail-gpg
|
121
158
|
licenses:
|
122
159
|
- MIT
|
123
|
-
metadata: {}
|
124
160
|
post_install_message:
|
125
161
|
rdoc_options: []
|
126
162
|
require_paths:
|
127
163
|
- lib
|
128
164
|
required_ruby_version: !ruby/object:Gem::Requirement
|
165
|
+
none: false
|
129
166
|
requirements:
|
130
|
-
- - '>='
|
167
|
+
- - ! '>='
|
131
168
|
- !ruby/object:Gem::Version
|
132
169
|
version: '0'
|
133
170
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
171
|
+
none: false
|
134
172
|
requirements:
|
135
|
-
- - '>='
|
173
|
+
- - ! '>='
|
136
174
|
- !ruby/object:Gem::Version
|
137
175
|
version: '0'
|
138
176
|
requirements: []
|
139
177
|
rubyforge_project:
|
140
|
-
rubygems_version:
|
178
|
+
rubygems_version: 1.8.23
|
141
179
|
signing_key:
|
142
|
-
specification_version:
|
180
|
+
specification_version: 3
|
143
181
|
summary: GPG/MIME encryption plugin for the Ruby Mail Library
|
144
182
|
test_files:
|
183
|
+
- test/action_mailer_test.rb
|
145
184
|
- test/gpg_test.rb
|
185
|
+
- test/message_test.rb
|
146
186
|
- test/test_helper.rb
|
147
|
-
has_rdoc:
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 0b78947766a213897b05befac957f4897f431b9a
|
4
|
-
data.tar.gz: 50434795fe71f90c31e792080a2e961ad18424d4
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: e4d529af60a76911181bd5be28dbf074e2636f9401bed1634cf277c567d9f8041a63cd5b6b6159be5db82a0cf92f80ec9278d98d46261e9f669f3bdc0eec4e5d
|
7
|
-
data.tar.gz: a40e501cf9b446d6be4c9a1342d4bbed72427f28bb5b41301409959baef215dba9e8a0eb52fd5c275e2f0170a7ac3df968bc571ee13035383985c79310abb89b
|