File: trusted_information_spec.rb

package info (click to toggle)
puppet 5.5.22-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 21,316 kB
  • sloc: ruby: 254,925; sh: 1,608; xml: 219; makefile: 153; sql: 103
file content (154 lines) | stat: -rw-r--r-- 4,707 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
require 'spec_helper'

require 'puppet/context/trusted_information'

describe Puppet::Context::TrustedInformation do
  let(:key) do
    key = Puppet::SSL::Key.new("myname")
    key.generate
    key
  end

  let(:csr) do
    csr = Puppet::SSL::CertificateRequest.new("csr")
    csr.generate(key, :extension_requests => {
      '1.3.6.1.4.1.15.1.2.1' => 'Ignored CSR extension',

      '1.3.6.1.4.1.34380.1.2.1' => 'CSR specific info',
      '1.3.6.1.4.1.34380.1.2.2' => 'more CSR specific info',
    })
    csr
  end

  let(:cert) do
    cert = Puppet::SSL::Certificate.from_instance(Puppet::SSL::CertificateFactory.build('ca', csr, csr.content, 1))

    # The cert must be signed so that it can be successfully be DER-decoded later
    signer = Puppet::SSL::CertificateSigner.new
    signer.sign(cert.content, key.content)
    cert
  end

  context "when remote" do
    it "has no cert information when it isn't authenticated" do
      trusted = Puppet::Context::TrustedInformation.remote(false, 'ignored', nil)

      expect(trusted.authenticated).to eq(false)
      expect(trusted.certname).to be_nil
      expect(trusted.extensions).to eq({})
    end

    it "is remote and has certificate information when it is authenticated" do
      trusted = Puppet::Context::TrustedInformation.remote(true, 'cert name', cert)

      expect(trusted.authenticated).to eq('remote')
      expect(trusted.certname).to eq('cert name')
      expect(trusted.extensions).to eq({
        '1.3.6.1.4.1.34380.1.2.1' => 'CSR specific info',
        '1.3.6.1.4.1.34380.1.2.2' => 'more CSR specific info',
      })
      expect(trusted.hostname).to eq('cert name')
      expect(trusted.domain).to be_nil
    end

    it "is remote but lacks certificate information when it is authenticated" do
      expect(Puppet).to receive(:info).once.with("TrustedInformation expected a certificate, but none was given.")

      trusted = Puppet::Context::TrustedInformation.remote(true, 'cert name', nil)

      expect(trusted.authenticated).to eq('remote')
      expect(trusted.certname).to eq('cert name')
      expect(trusted.extensions).to eq({})
    end
  end

  context "when local" do
    it "is authenticated local with the nodes clientcert" do
      node = Puppet::Node.new('testing', :parameters => { 'clientcert' => 'cert name' })

      trusted = Puppet::Context::TrustedInformation.local(node)

      expect(trusted.authenticated).to eq('local')
      expect(trusted.certname).to eq('cert name')
      expect(trusted.extensions).to eq({})
      expect(trusted.hostname).to eq('cert name')
      expect(trusted.domain).to be_nil
    end

    it "is authenticated local with no clientcert when there is no node" do
      trusted = Puppet::Context::TrustedInformation.local(nil)

      expect(trusted.authenticated).to eq('local')
      expect(trusted.certname).to be_nil
      expect(trusted.extensions).to eq({})
      expect(trusted.hostname).to be_nil
      expect(trusted.domain).to be_nil
    end
  end

  it "converts itself to a hash" do
    trusted = Puppet::Context::TrustedInformation.remote(true, 'cert name', cert)

    expect(trusted.to_h).to eq({
      'authenticated' => 'remote',
      'certname' => 'cert name',
      'extensions' => {
        '1.3.6.1.4.1.34380.1.2.1' => 'CSR specific info',
        '1.3.6.1.4.1.34380.1.2.2' => 'more CSR specific info',
      },
      'hostname' => 'cert name',
      'domain' => nil
    })
  end

  it "extracts domain and hostname from certname" do
    trusted = Puppet::Context::TrustedInformation.remote(true, 'hostname.domain.long', cert)

    expect(trusted.to_h).to eq({
      'authenticated' => 'remote',
      'certname' => 'hostname.domain.long',
      'extensions' => {
        '1.3.6.1.4.1.34380.1.2.1' => 'CSR specific info',
        '1.3.6.1.4.1.34380.1.2.2' => 'more CSR specific info',
      },
      'hostname' => 'hostname',
      'domain' => 'domain.long'
    })
  end

  it "freezes the hash" do
    trusted = Puppet::Context::TrustedInformation.remote(true, 'cert name', cert)

    expect(trusted.to_h).to be_deeply_frozen
  end

  matcher :be_deeply_frozen do
    match do |actual|
      unfrozen_items(actual).empty?
    end

    failure_message do |actual|
      "expected all items to be frozen but <#{unfrozen_items(actual).join(', ')}> was not"
    end

    define_method :unfrozen_items do |actual|
      unfrozen = []
      stack = [actual]
      while item = stack.pop
        if !item.frozen?
          unfrozen.push(item)
        end

        case item
        when Hash
          stack.concat(item.keys)
          stack.concat(item.values)
        when Array
          stack.concat(item)
        end
      end

      unfrozen
    end
  end
end