Release prep v9.1.0
[puppet-modules/puppetlabs-apt.git] / spec / unit / puppet / provider / apt_key_spec.rb
1 # frozen_string_literal: true
2
3 require 'spec_helper'
4
5 describe Puppet::Type.type(:apt_key).provider(:apt_key) do
6   describe 'instances' do
7     it 'has an instance method' do
8       expect(described_class).to respond_to :instances
9     end
10   end
11
12   describe 'prefetch' do
13     it 'has a prefetch method' do
14       expect(described_class).to respond_to :prefetch
15     end
16   end
17
18   context 'with self.instances no key' do
19     before :each do
20       # Unable to remove `master` from below terminology as it relies on outside code
21       allow(described_class).to receive(:apt_key).with(
22         ['adv', '--no-tty', '--list-keys', '--with-colons', '--fingerprint', '--fixed-list-mode'],
23       ).and_return('uid:-::::1284991450::07BEBE04F4AE4A8E885A761325717D8509D9C1DC::Ubuntu Extras Archive Automatic Signing Key <ftpmaster@ubuntu.com>::::::::::0:')
24     end
25
26     it 'returns no resources' do
27       expect(described_class.instances.size).to eq(0)
28     end
29   end
30
31   context 'with self.instances multiple keys' do
32     before :each do
33       command_output = <<~OUTPUT
34         Executing: gpg --ignore-time-conflict --no-options --no-default-keyring --homedir /tmp/tmp.DU0GdRxjmE --no-auto-check-trustdb --trust-model always --keyring /etc/apt/trusted.gpg --primary-keyring /etc/apt/trusted.gpg --keyring /etc/apt/trusted.gpg.d/puppetlabs-pc1-keyring.gpg --no-tty --list-keys --with-colons --fingerprint --fixed-list-mode
35         tru:t:1:1549900774:0:3:1:5
36         pub:-:1024:17:40976EAF437D05B5:1095016255:::-:::scESC:
37         fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:
38         uid:-::::1095016255::B84AE656F4F5A826C273A458512EF8E282754CE1::Ubuntu Archive Automatic Signing Key <ftpmaster@ubuntu.com>:
39         sub:-:2048:16:251BEFF479164387:1095016263::::::e:
40         pub:-:1024:17:46181433FBB75451:1104433784:::-:::scSC:
41         fpr:::::::::C5986B4F1257FFA86632CBA746181433FBB75451:
42       OUTPUT
43       allow(described_class).to receive(:apt_key).with(
44         ['adv', '--no-tty', '--list-keys', '--with-colons', '--fingerprint', '--fixed-list-mode'],
45       ).and_return(command_output)
46     end
47
48     it 'returns 2 resources' do # rubocop:disable RSpec/MultipleExpectations
49       expect(described_class.instances.size).to eq(2)
50       expect(described_class.instances[0].name).to eq('630239CC130E1A7FD81A27B140976EAF437D05B5')
51       expect(described_class.instances[0].id).to eq('40976EAF437D05B5')
52       expect(described_class.instances[0].expired).to be_falsey
53       expect(described_class.instances[1].name).to eq('C5986B4F1257FFA86632CBA746181433FBB75451')
54       expect(described_class.instances[1].id).to eq('46181433FBB75451')
55       expect(described_class.instances[1].expired).to be_falsey
56     end
57   end
58
59   context 'with self.instances expired subkeys' do
60     before :each do
61       command_output = <<~OUTPUT
62         Executing: /tmp/apt-key-gpghome.0lru3TZOtF/gpg.1.sh --list-keys --with-colons --fingerprint 0x7721F63BD38B4796
63         tru:t:1:1682141947:0:3:1:5
64         pub:-:4096:1:7721F63BD38B4796:1460440275:::-:::scSC::::::23::0:
65         fpr:::::::::EB4C1BFD4F042F6DDDCCEC917721F63BD38B4796:
66         uid:-::::1460440275::7830FE2652F718E78EEE5881B7FA2CE8E3533BE4::Google Inc. (Linux Packages Signing Authority) <linux-packages-keymaster@google.com>::::::::::0:
67         sub:e:4096:1:1397BC53640DB551:1460440520:1555048520:::::s::::::23:
68         fpr:::::::::3B068FB4789ABE4AEFA3BB491397BC53640DB551:
69         sub:e:4096:1:6494C6D6997C215E:1485225932:1579833932:::::s::::::23:
70         fpr:::::::::3E50F6D3EC278FDEB655C8CA6494C6D6997C215E:
71       OUTPUT
72       allow(described_class).to receive(:apt_key).with(
73         ['adv', '--no-tty', '--list-keys', '--with-colons', '--fingerprint', '--fixed-list-mode'],
74       ).and_return(command_output)
75     end
76
77     it 'returns 1 expired resource' do
78       expect(described_class.instances.size).to eq(1)
79       expect(described_class.instances[0].expired).to be_truthy
80     end
81   end
82
83   context 'with create apt_key resource' do
84     it 'apt_key with content set and source nil' do
85       expect(described_class).to receive(:apt_key).with(['adv', '--no-tty',
86                                                          '--keyserver',
87                                                          :'keyserver.ubuntu.com',
88                                                          '--recv-keys',
89                                                          'C105B9DE'])
90       resource = Puppet::Type::Apt_key.new(name: 'source and content nil',
91                                            id: 'C105B9DE',
92                                            ensure: 'present')
93
94       provider = described_class.new(resource)
95       expect(provider).not_to be_exist
96       provider.create
97       expect(provider).to be_exist
98     end
99
100     it 'apt_key content and source nil, options set' do
101       expect(described_class).to receive(:apt_key).with(['adv', '--no-tty',
102                                                          '--keyserver',
103                                                          :'keyserver.ubuntu.com',
104                                                          '--keyserver-options',
105                                                          'jimno',
106                                                          '--recv-keys',
107                                                          'C105B9DE'])
108       resource = Puppet::Type::Apt_key.new(name: 'source and content nil',
109                                            id: 'C105B9DE',
110                                            options: 'jimno',
111                                            ensure: 'present')
112
113       provider = described_class.new(resource)
114       expect(provider).not_to be_exist
115       provider.create
116       expect(provider).to be_exist
117     end
118
119     it 'apt_key with content set' do # rubocop:disable RSpec/MultipleExpectations
120       expect(described_class).to receive(:apt_key).with(array_including('add', kind_of(String)))
121       resource = Puppet::Type::Apt_key.new(name: 'gsd',
122                                            id: 'C105B9DE',
123                                            content: 'asad',
124                                            ensure: 'present')
125
126       provider = described_class.new(resource)
127       expect(provider).not_to be_exist
128       expect(provider).to receive(:tempfile).and_return(Tempfile.new('foo'))
129       provider.create
130       expect(provider).to be_exist
131     end
132
133     it 'apt_key with source set' do # rubocop:disable RSpec/MultipleExpectations
134       expect(described_class).to receive(:apt_key).with(array_including('add', kind_of(String)))
135       resource = Puppet::Type::Apt_key.new(name: 'gsd',
136                                            id: 'C105B9DE',
137                                            source: 'ftp://bla/herpderp.gpg',
138                                            ensure: 'present')
139
140       provider = described_class.new(resource)
141       expect(provider).not_to be_exist
142       expect(provider).to receive(:source_to_file).and_return(Tempfile.new('foo'))
143       provider.create
144       expect(provider).to be_exist
145     end
146
147     it 'apt_key with source and weak ssl verify set' do # rubocop:disable RSpec/MultipleExpectations
148       expect(described_class).to receive(:apt_key).with(array_including('add', kind_of(String)))
149       resource = Puppet::Type::Apt_key.new(name: 'gsd',
150                                            id: 'C105B9DE',
151                                            source: 'https://bla/herpderp.gpg',
152                                            ensure: 'present',
153                                            weak_ssl: true)
154
155       provider = described_class.new(resource)
156       expect(provider).not_to be_exist
157       expect(provider).to receive(:source_to_file).and_return(Tempfile.new('foo'))
158       provider.create
159       expect(provider).to be_exist
160     end
161
162     describe 'different valid id keys' do
163       hash_of_keys = {
164         '32bit key id' => 'EF8D349F',
165         '64bit key id' => '7F438280EF8D349F',
166         '160bit key fingerprint' => '6F6B15509CF8E59E6E469F327F438280EF8D349F',
167         '32bit key id lowercase' => 'EF8D349F'.downcase,
168         '64bit key id lowercase' => '7F438280EF8D349F'.downcase,
169         '160bit key fingerprint lowercase' => '6F6B15509CF8E59E6E469F327F438280EF8D349F'.downcase,
170         '32bit key id 0x formatted' => '0xEF8D349F',
171         '64bit key id 0x formatted' => '0x7F438280EF8D349F',
172         '160bit key fingerprint 0x formatted' => '0x6F6B15509CF8E59E6E469F327F438280EF8D349F'
173       }
174       hash_of_keys.each do |key_type, value|
175         it "#{key_type} #{value} is valid" do
176           expect(described_class).to receive(:apt_key).with(array_including('adv', '--no-tty',
177                                                                             '--keyserver',
178                                                                             :'keyserver.ubuntu.com',
179                                                                             '--recv-keys'))
180           resource = Puppet::Type::Apt_key.new(name: 'source and content nil',
181                                                id: value,
182                                                ensure: 'present')
183
184           provider = described_class.new(resource)
185           expect(provider).not_to be_exist
186           provider.create
187           expect(provider).to be_exist
188         end
189       end
190     end
191
192     it 'apt_key with invalid key length' do
193       expect {
194         Puppet::Type::Apt_key.new(name: 'source and content nil',
195                                   id: '1',
196                                   ensure: 'present')
197       }.to raise_error(Puppet::ResourceError, %r{Parameter id failed on Apt_key})
198     end
199   end
200
201   context 'with key_line_hash function' do
202     it 'matches rsa' do
203       expect(described_class.key_line_hash('pub:-:1024:1:40976EAF437D05B5:1095016255:::-:::scESC:', ['fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:'])).to include(
204         key_expiry: nil,
205         key_fingerprint: '630239CC130E1A7FD81A27B140976EAF437D05B5',
206         key_long: '40976EAF437D05B5',
207         key_short: '437D05B5',
208         key_size: '1024',
209         key_type: :rsa,
210       )
211     end
212
213     it 'matches dsa' do
214       expect(described_class.key_line_hash('pub:-:1024:17:40976EAF437D05B5:1095016255:::-:::scESC:', ['fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:'])).to include(
215         key_expiry: nil,
216         key_fingerprint: '630239CC130E1A7FD81A27B140976EAF437D05B5',
217         key_long: '40976EAF437D05B5',
218         key_short: '437D05B5',
219         key_size: '1024',
220         key_type: :dsa,
221       )
222     end
223
224     it 'matches ecc' do
225       expect(described_class.key_line_hash('pub:-:1024:18:40976EAF437D05B5:1095016255:::-:::scESC:', ['fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:'])).to include(
226         key_expiry: nil,
227         key_fingerprint: '630239CC130E1A7FD81A27B140976EAF437D05B5',
228         key_long: '40976EAF437D05B5',
229         key_short: '437D05B5',
230         key_size: '1024',
231         key_type: :ecc,
232       )
233     end
234
235     it 'matches ecdsa' do
236       expect(described_class.key_line_hash('pub:-:1024:19:40976EAF437D05B5:1095016255:::-:::scESC:', ['fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:'])).to include(
237         key_expiry: nil,
238         key_fingerprint: '630239CC130E1A7FD81A27B140976EAF437D05B5',
239         key_long: '40976EAF437D05B5',
240         key_short: '437D05B5',
241         key_size: '1024',
242         key_type: :ecdsa,
243       )
244     end
245   end
246 end