668a953bff76719b5333bf5c2013d8946ad821d4
[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 '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 '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[1].name).to eq('C5986B4F1257FFA86632CBA746181433FBB75451')
53       expect(described_class.instances[1].id).to eq('46181433FBB75451')
54     end
55   end
56
57   context 'create apt_key resource' do
58     it 'apt_key with content set and source nil' do
59       expect(described_class).to receive(:apt_key).with(['adv', '--no-tty',
60                                                          '--keyserver',
61                                                          :"keyserver.ubuntu.com",
62                                                          '--recv-keys',
63                                                          'C105B9DE'])
64       resource = Puppet::Type::Apt_key.new(name: 'source and content nil',
65                                            id: 'C105B9DE',
66                                            ensure: 'present')
67
68       provider = described_class.new(resource)
69       expect(provider).not_to be_exist
70       provider.create
71       expect(provider).to be_exist
72     end
73
74     it 'apt_key content and source nil, options set' do
75       expect(described_class).to receive(:apt_key).with(['adv', '--no-tty',
76                                                          '--keyserver',
77                                                          :"keyserver.ubuntu.com",
78                                                          '--keyserver-options',
79                                                          'jimno',
80                                                          '--recv-keys',
81                                                          'C105B9DE'])
82       resource = Puppet::Type::Apt_key.new(name: 'source and content nil',
83                                            id: 'C105B9DE',
84                                            options: 'jimno',
85                                            ensure: 'present')
86
87       provider = described_class.new(resource)
88       expect(provider).not_to be_exist
89       provider.create
90       expect(provider).to be_exist
91     end
92
93     it 'apt_key with content set' do # rubocop:disable RSpec/MultipleExpectations
94       expect(described_class).to receive(:apt_key).with(array_including('add', kind_of(String)))
95       resource = Puppet::Type::Apt_key.new(name: 'gsd',
96                                            id: 'C105B9DE',
97                                            content: 'asad',
98                                            ensure: 'present')
99
100       provider = described_class.new(resource)
101       expect(provider).not_to be_exist
102       expect(provider).to receive(:tempfile).and_return(Tempfile.new('foo'))
103       provider.create
104       expect(provider).to be_exist
105     end
106
107     it 'apt_key with source set' do # rubocop:disable RSpec/MultipleExpectations
108       expect(described_class).to receive(:apt_key).with(array_including('add', kind_of(String)))
109       resource = Puppet::Type::Apt_key.new(name: 'gsd',
110                                            id: 'C105B9DE',
111                                            source: 'ftp://bla/herpderp.gpg',
112                                            ensure: 'present')
113
114       provider = described_class.new(resource)
115       expect(provider).not_to be_exist
116       expect(provider).to receive(:source_to_file).and_return(Tempfile.new('foo'))
117       provider.create
118       expect(provider).to be_exist
119     end
120
121     it 'apt_key with source and weak ssl verify set' do # rubocop:disable RSpec/MultipleExpectations
122       expect(described_class).to receive(:apt_key).with(array_including('add', kind_of(String)))
123       resource = Puppet::Type::Apt_key.new(name: 'gsd',
124                                            id: 'C105B9DE',
125                                            source: 'https://bla/herpderp.gpg',
126                                            ensure: 'present',
127                                            weak_ssl: true)
128
129       provider = described_class.new(resource)
130       expect(provider).not_to be_exist
131       expect(provider).to receive(:source_to_file).and_return(Tempfile.new('foo'))
132       provider.create
133       expect(provider).to be_exist
134     end
135
136     describe 'different valid id keys' do
137       hash_of_keys = {
138         '32bit key id' => 'EF8D349F',
139         '64bit key id' => '7F438280EF8D349F',
140         '160bit key fingerprint' => '6F6B15509CF8E59E6E469F327F438280EF8D349F',
141         '32bit key id lowercase' => 'EF8D349F'.downcase,
142         '64bit key id lowercase' => '7F438280EF8D349F'.downcase,
143         '160bit key fingerprint lowercase' => '6F6B15509CF8E59E6E469F327F438280EF8D349F'.downcase,
144         '32bit key id 0x formatted' => '0xEF8D349F',
145         '64bit key id 0x formatted' => '0x7F438280EF8D349F',
146         '160bit key fingerprint 0x formatted' => '0x6F6B15509CF8E59E6E469F327F438280EF8D349F',
147       }
148       hash_of_keys.each do |key_type, value|
149         it "#{key_type} #{value} is valid" do
150           expect(described_class).to receive(:apt_key).with(array_including('adv', '--no-tty',
151                                                                             '--keyserver',
152                                                                             :"keyserver.ubuntu.com",
153                                                                             '--recv-keys'))
154           resource = Puppet::Type::Apt_key.new(name: 'source and content nil',
155                                                id: value,
156                                                ensure: 'present')
157
158           provider = described_class.new(resource)
159           expect(provider).not_to be_exist
160           provider.create
161           expect(provider).to be_exist
162         end
163       end
164     end
165
166     it 'apt_key with invalid key length' do
167       expect {
168         Puppet::Type::Apt_key.new(name: 'source and content nil',
169                                   id: '1',
170                                   ensure: 'present')
171       }.to raise_error(Puppet::ResourceError, %r{Parameter id failed on Apt_key})
172     end
173   end
174
175   context 'key_line_hash function' do
176     it 'matches rsa' do
177       expect(described_class.key_line_hash('pub:-:1024:1:40976EAF437D05B5:1095016255:::-:::scESC:', 'fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:')).to include(
178         key_expiry: nil,
179         key_fingerprint: '630239CC130E1A7FD81A27B140976EAF437D05B5',
180         key_long: '40976EAF437D05B5',
181         key_short: '437D05B5',
182         key_size: '1024',
183         key_type: :rsa,
184       )
185     end
186
187     it 'matches dsa' do
188       expect(described_class.key_line_hash('pub:-:1024:17:40976EAF437D05B5:1095016255:::-:::scESC:', 'fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:')).to include(
189         key_expiry: nil,
190         key_fingerprint: '630239CC130E1A7FD81A27B140976EAF437D05B5',
191         key_long: '40976EAF437D05B5',
192         key_short: '437D05B5',
193         key_size: '1024',
194         key_type: :dsa,
195       )
196     end
197
198     it 'matches ecc' do
199       expect(described_class.key_line_hash('pub:-:1024:18:40976EAF437D05B5:1095016255:::-:::scESC:', 'fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:')).to include(
200         key_expiry: nil,
201         key_fingerprint: '630239CC130E1A7FD81A27B140976EAF437D05B5',
202         key_long: '40976EAF437D05B5',
203         key_short: '437D05B5',
204         key_size: '1024',
205         key_type: :ecc,
206       )
207     end
208
209     it 'matches ecdsa' do
210       expect(described_class.key_line_hash('pub:-:1024:19:40976EAF437D05B5:1095016255:::-:::scESC:', 'fpr:::::::::630239CC130E1A7FD81A27B140976EAF437D05B5:')).to include(
211         key_expiry: nil,
212         key_fingerprint: '630239CC130E1A7FD81A27B140976EAF437D05B5',
213         key_long: '40976EAF437D05B5',
214         key_short: '437D05B5',
215         key_size: '1024',
216         key_type: :ecdsa,
217       )
218     end
219   end
220 end