File: inline_decrypted_message_test.rb

package info (click to toggle)
ruby-mail-gpg 0.4.4-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 328 kB
  • sloc: ruby: 2,289; makefile: 6
file content (161 lines) | stat: -rw-r--r-- 6,253 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
require 'test_helper'

# test cases for PGP inline messages (i.e. non-mime)
class InlineDecryptedMessageTest < MailGpgTestCase

  context "InlineDecryptedMessage" do

    setup do
      (@mails = Mail::TestMailer.deliveries).clear
      @mail = Mail.new do
        to 'jane@foo.bar'
        from 'joe@foo.bar'
        subject 'test'
        body 'i am unencrypted'
        gpg encrypt: false
      end
    end

    context "inline message" do
      should "decrypt and verify body" do
        mail = Mail.new(@mail)
        mail.body = InlineDecryptedMessageTest.encrypt(mail, mail.body.to_s)

        assert !mail.multipart?
        assert mail.encrypted?
        assert decrypted = mail.decrypt(:password => 'abc', verify: true)
        assert decrypted == @mail
        assert !decrypted.encrypted?
        assert vr = decrypted.verify_result
        assert sig = vr.signatures.first
        assert sig.to_s=~ /Joe/
        assert sig.valid?
      end
    end

    context "multipart/alternative message" do
      should "have dropped HTML-part" do
        mail = Mail.new(@mail)
        mail.body = InlineDecryptedMessageTest.encrypt(mail, mail.body.to_s)
        mail.html_part do |p|
          p.body "<pre>#{InlineDecryptedMessageTest.encrypt(mail, mail.body.to_s)}</pre>"
        end

        assert mail.multipart?
        assert mail.encrypted?
        assert decrypted = mail.decrypt(:password => 'abc', verify: true)
        assert !decrypted.encrypted?
        assert decrypted.mime_type == 'multipart/mixed'
        assert decrypted.parts.size == 1
        assert decrypted.parts.first.mime_type == 'text/plain'
        assert decrypted.header['X-MailGpg-Deleted-Html-Part'].value == 'true'
      end
    end

    context "attachment message" do
      should "decrypt attachment" do
        rakefile = File.open('Rakefile') { |file| file.read }
        mail = Mail.new(@mail)
        mail.content_type = 'multipart/mixed'
        mail.body = ''
        mail.part do |p|
          p.content_type 'application/octet-stream; name=Rakefile.pgp'
          p.content_transfer_encoding Mail::Encodings::Base64
          p.content_disposition 'attachment; filename="Rakefile.pgp"'
          p.body Mail::Encodings::Base64::encode(InlineDecryptedMessageTest.encrypt(mail, rakefile, false))
        end

        assert mail.multipart?
        assert mail.encrypted?
        assert decrypted = mail.decrypt(:password => 'abc')
        assert !decrypted.encrypted?
        check_headers(@mail, decrypted)
        assert_equal 1, decrypted.parts.length
        assert /application\/octet-stream; (?:charset=UTF-8; )?name=Rakefile/ =~ decrypted.parts[0].content_type
        assert_equal 'attachment; filename=Rakefile', decrypted.parts[0].content_disposition
        assert_equal rakefile, decrypted.parts[0].body.decoded
      end
    end

    context "cleartext body and encrypted attachment message" do
      should "decrypt and verify attachment" do
        rakefile = File.open('Rakefile') { |file| file.read }
        mail = Mail.new(@mail)
        mail.content_type = 'multipart/mixed'
        mail.part do |p|
          p.content_type 'application/octet-stream; name=Rakefile.pgp'
          p.content_transfer_encoding Mail::Encodings::Base64
          p.content_disposition 'attachment; filename="Rakefile.pgp"'
          p.body Mail::Encodings::Base64::encode(InlineDecryptedMessageTest.encrypt(mail, rakefile, false))
        end

        assert mail.multipart?
        assert mail.encrypted?
        assert decrypted = mail.decrypt(password: 'abc', verify: true)
        assert !decrypted.encrypted?
        check_headers(@mail, decrypted)
        assert_equal 2, decrypted.parts.length
        assert @mail.body.to_s == decrypted.parts[0].body.to_s
        assert /application\/octet-stream; (?:charset=UTF-8; )?name=Rakefile/ =~ decrypted.parts[1].content_type
        assert_equal 'attachment; filename=Rakefile', decrypted.parts[1].content_disposition
        assert_equal rakefile, decrypted.parts[1].body.decoded

        assert_nil decrypted.parts[0].verify_result
        assert vr = decrypted.parts[1].verify_result
        assert sig = vr.signatures.first
        assert sig.to_s=~ /Joe/
        assert sig.valid?
      end
    end

    context "encrypted body and attachment message" do
      should "decrypt and verify" do
        rakefile = File.open('Rakefile') { |file| file.read }
        mail = Mail.new(@mail)
        mail.content_type = 'multipart/mixed'
        mail.body = InlineDecryptedMessageTest.encrypt(mail, mail.body.to_s)
        mail.part do |p|
          p.content_type 'application/octet-stream; name=Rakefile.pgp'
          p.content_transfer_encoding Mail::Encodings::Base64
          p.content_disposition 'attachment; filename="Rakefile.pgp"'
          p.body Mail::Encodings::Base64::encode(InlineDecryptedMessageTest.encrypt(mail, rakefile, false))
        end

        assert mail.multipart?
        assert mail.encrypted?
        assert decrypted = mail.decrypt(password: 'abc', verify: true)
        assert !decrypted.encrypted?
        check_headers(@mail, decrypted)
        assert_equal 2, decrypted.parts.length
        assert @mail.body.to_s == decrypted.parts[0].body.to_s
        assert /application\/octet-stream; (?:charset=UTF-8; )?name=Rakefile/ =~ decrypted.parts[1].content_type
        assert_equal 'attachment; filename=Rakefile', decrypted.parts[1].content_disposition
        assert_equal rakefile, decrypted.parts[1].body.decoded
        decrypted.parts.each do |part|
          assert vr = part.verify_result
          assert sig = vr.signatures.first
          assert sig.to_s=~ /Joe/
          assert sig.valid?
        end
      end
    end
  end

  def self.encrypt(mail, plain, armor = true)
    GPGME::Crypto.new.encrypt(plain,
      password: 'abc',
      recipients: mail.to,
      sign: true,
      signers: mail.from,
      armor: armor).to_s
  end

  def check_headers(expected, actual)
    assert_equal expected.to, actual.to
    assert_equal expected.cc, actual.cc
    assert_equal expected.bcc, actual.bcc
    assert_equal expected.subject, actual.subject
    assert_equal expected.message_id, actual.message_id
    assert_equal expected.date, actual.date
  end
end