RealMeServiceTest::testGetAuth()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 13
nc 1
nop 0
dl 0
loc 21
rs 9.8333
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\RealMe\Tests;
4
5
use OneLogin\Saml2\Auth;
6
use SilverStripe\Control\NullHTTPRequest;
7
use SilverStripe\Core\Config\Config;
8
use SilverStripe\Core\Environment;
9
use SilverStripe\Core\Injector\Injector;
10
use SilverStripe\Core\TempFolder;
11
use SilverStripe\Dev\SapphireTest;
12
use SilverStripe\RealMe\RealMeService;
13
14
class RealMeServiceTest extends SapphireTest
15
{
16
    private static $pathForTempCertificate;
17
18
    /**
19
     * @var RealMeService
20
     */
21
    private $service;
22
23
    public function testGetCertificateContents()
24
    {
25
        self::$pathForTempCertificate = TempFolder::getTempFolder(BASE_PATH) . '/tmpcert.pem';
26
27
        /**
28
         * Test standard certificate
29
         */
30
31
        $contents = file_get_contents(__DIR__ . '/certs/standard_cert.pem');
32
33
        // Strip carriage returns
34
        $contents = str_replace("\r", '', $contents);
35
36
        $path = self::$pathForTempCertificate;
37
        file_put_contents($path, $contents);
38
39
        /** @var RealMeService $service */
40
        $service = Injector::inst()->get(RealMeService::class);
41
42
        $this->assertEquals('Redacted private key goes here', $service->getCertificateContents($path, 'key'));
43
        $this->assertEquals('Redacted certificate goes here', $service->getCertificateContents($path, 'certificate'));
44
45
        unlink($path);
46
47
        /**
48
         * Test certificate with RSA private key
49
         */
50
51
        $contents = file_get_contents(__DIR__ . '/certs/rsa_cert.pem');
52
53
        // Strip carriage returns
54
        $contents = str_replace("\r", '', $contents);
55
56
        $path = self::$pathForTempCertificate;
57
        file_put_contents($path, $contents);
58
59
        /** @var RealMeService $service */
60
        $service = Injector::inst()->get(RealMeService::class);
61
        $this->assertEquals('Redacted private key goes here', $service->getCertificateContents($path, 'key'));
62
        $this->assertEquals('Redacted certificate goes here', $service->getCertificateContents($path, 'certificate'));
63
64
        unlink($path);
65
    }
66
67
    public function testGetAuth()
68
    {
69
        $auth = $this->service->getAuth(new NullHTTPRequest());
70
        $this->assertTrue(get_class($auth) === Auth::class);
71
72
        // Service Provider settings
73
        $spData = $auth->getSettings()->getSPData();
74
        $this->assertSame('https://example.com/realm/service', $spData['entityId']);
75
        $this->assertSame('https://example.com/Security/login/RealMe/acs', $spData['assertionConsumerService']['url']);
76
        $this->assertSame('urn:oasis:names:tc:SAML:2.0:nameid-format:persistent', $spData['NameIDFormat']);
77
78
        // Identity Provider settings
79
        $idpData = $auth->getSettings()->getIdPData();
80
        $this->assertSame('https://mts.realme.govt.nz/saml2', $idpData['entityId']);
81
        $this->assertSame('https://mts.realme.govt.nz/logon-mts/mtsEntryPoint', $idpData['singleSignOnService']['url']);
82
83
        // Security settings
84
        $securityData = $auth->getSettings()->getSecurityData();
85
        $this->assertSame(
86
            'urn:nzl:govt:ict:stds:authn:deployment:GLS:SAML:2.0:ac:classes:LowStrength',
87
            $securityData['requestedAuthnContext'][0]
88
        );
89
    }
90
91
    public function testGetAuthCustomSPEntityId()
92
    {
93
        Config::modify()->set(
94
            RealMeService::class,
95
            'sp_entity_ids',
96
            ['mts' => 'https://example.com/custom-realm/custom-service']
97
        );
98
        $spData = $this->service->getAuth(new NullHTTPRequest())->getSettings()->getSPData();
99
        $this->assertSame('https://example.com/custom-realm/custom-service', $spData['entityId']);
100
    }
101
102
    public function testGetAuthCustomIdPEntityId()
103
    {
104
        Config::modify()->set(
105
            RealMeService::class,
106
            'idp_entity_ids',
107
            ['mts' => ['login' => 'https://example.com/idp-entry']]
108
        );
109
        $idpData = $this->service->getAuth(new NullHTTPRequest())->getSettings()->getIdPData();
110
        $this->assertSame('https://example.com/idp-entry', $idpData['entityId']);
111
    }
112
113
    public function testGetAuthCustomAuthnContext()
114
    {
115
        Config::modify()->set(
116
            RealMeService::class,
117
            'authn_contexts',
118
            ['mts' => 'urn:nzl:govt:ict:stds:authn:deployment:GLS:SAML:2.0:ac:classes:ModStrength::OTP:Mobile:SMS']
119
        );
120
        $securityData = $this->service->getAuth(new NullHTTPRequest())->getSettings()->getSecurityData();
121
        $this->assertSame(
122
            'urn:nzl:govt:ict:stds:authn:deployment:GLS:SAML:2.0:ac:classes:ModStrength::OTP:Mobile:SMS',
123
            $securityData['requestedAuthnContext'][0]
124
        );
125
    }
126
127
    public static function setUpBeforeClass()
128
    {
129
        Environment::putEnv('REALME_CERT_DIR=' . __DIR__ . '/certs');
130
        Environment::putEnv('REALME_SIGNING_CERT_FILENAME=' . 'standard_cert.pem');
131
132
        parent::setUpBeforeClass();
133
    }
134
135
    protected function setUp()
136
    {
137
        parent::setUp();
138
        $this->service = Injector::inst()->create(RealMeService::class);
139
140
        // Configure for login integration and mts by default
141
        Config::modify()->set(RealMeService::class, 'sp_entity_ids', ['mts' => 'https://example.com/realm/service']);
142
        Config::modify()->set(
143
            RealMeService::class,
144
            'metadata_assertion_service_domains',
145
            ['mts' => 'https://example.com']
146
        );
147
        Config::modify()->set(
148
            RealMeService::class,
149
            'authn_contexts',
150
            ['mts' => 'urn:nzl:govt:ict:stds:authn:deployment:GLS:SAML:2.0:ac:classes:LowStrength']
151
        );
152
    }
153
154
    public static function tearDownAfterClass()
155
    {
156
        parent::tearDownAfterClass();
157
158
        // Ensure self::$pathForTempCertificate is unlink'd (otherwise it won't get unlinked if the test fails)
159
        if (file_exists(self::$pathForTempCertificate)) {
160
            unlink(self::$pathForTempCertificate);
161
        }
162
    }
163
}
164