Passed
Pull Request — 4 (#10028)
by Steve
09:11 queued 18s
created

PasswordEncryptorTest::testCreateForCodeNotFound()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Security\Tests;
4
5
use SilverStripe\Security\PasswordEncryptor_Blowfish;
6
use SilverStripe\Security\PasswordEncryptor;
7
use SilverStripe\Core\Config\Config;
8
use SilverStripe\Dev\SapphireTest;
9
use SilverStripe\Security\PasswordEncryptor_LegacyPHPHash;
10
use SilverStripe\Security\PasswordEncryptor_NotFoundException;
11
use SilverStripe\Security\PasswordEncryptor_PHPHash;
12
use SilverStripe\Security\Tests\PasswordEncryptorTest\TestEncryptor;
13
14
class PasswordEncryptorTest extends SapphireTest
15
{
16
    protected function tearDown(): void
17
    {
18
        parent::tearDown();
19
        PasswordEncryptor_Blowfish::set_cost(10);
20
    }
21
22
    public function testCreateForCode()
23
    {
24
        Config::modify()->merge(
25
            PasswordEncryptor::class,
26
            'encryptors',
27
            ['test' => [TestEncryptor::class => null]]
28
        );
29
        $e = PasswordEncryptor::create_for_algorithm('test');
30
        $this->assertInstanceOf(TestEncryptor::class, $e);
31
    }
32
33
    public function testCreateForCodeNotFound()
34
    {
35
        $this->expectException(PasswordEncryptor_NotFoundException::class)
36
        PasswordEncryptor::create_for_algorithm('unknown');
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_STRING on line 36 at column 8
Loading history...
37
    }
38
39
    public function testRegister()
40
    {
41
        Config::modify()->merge(
42
            PasswordEncryptor::class,
43
            'encryptors',
44
            ['test' => [TestEncryptor::class => null]]
45
        );
46
        $encryptors = PasswordEncryptor::get_encryptors();
47
        $this->assertContains('test', array_keys($encryptors));
48
        $encryptor = $encryptors['test'];
49
        $this->assertContains(TestEncryptor::class, key($encryptor));
50
    }
51
52
    public function testEncryptorPHPHashWithArguments()
53
    {
54
        Config::modify()->merge(
55
            PasswordEncryptor::class,
56
            'encryptors',
57
            ['test_md5' => [PasswordEncryptor_PHPHash::class=>'md5']]
58
        );
59
        /** @var PasswordEncryptor_PHPHash $e */
60
        $e = PasswordEncryptor::create_for_algorithm('test_md5');
61
        $this->assertEquals('md5', $e->getAlgorithm());
62
    }
63
64
    public function testEncryptorPHPHash()
65
    {
66
        Config::modify()->merge(
67
            PasswordEncryptor::class,
68
            'encryptors',
69
            ['test_sha1' => [PasswordEncryptor_PHPHash::class => 'sha1']]
70
        );
71
        $e = PasswordEncryptor::create_for_algorithm('test_sha1');
72
        $password = 'mypassword';
73
        $salt = 'mysalt';
74
        $this->assertEquals(
75
            hash('sha1', $password . $salt),
76
            $e->encrypt($password, $salt)
77
        );
78
    }
79
80
    public function testEncryptorBlowfish()
81
    {
82
        Config::modify()->merge(
83
            PasswordEncryptor::class,
84
            'encryptors',
85
            ['test_blowfish' => [PasswordEncryptor_Blowfish::class => '']]
86
        );
87
        /** @var PasswordEncryptor_Blowfish $e */
88
        $e = PasswordEncryptor::create_for_algorithm('test_blowfish');
89
90
        $password = 'mypassword';
91
92
        $salt = $e->salt($password);
93
        $modSalt = substr($salt, 0, 3) . str_shuffle(substr($salt, 3, strlen($salt)));
94
95
        $this->assertTrue(
96
            $e->checkAEncryptionLevel() == 'y' || $e->checkAEncryptionLevel() == 'x'
97
            || $e->checkAEncryptionLevel() == 'a'
98
        );
99
        $this->assertTrue($e->check($e->encrypt($password, $salt), "mypassword", $salt));
100
        $this->assertFalse($e->check($e->encrypt($password, $salt), "anotherpw", $salt));
101
        $this->assertFalse($e->check($e->encrypt($password, $salt), "mypassword", $modSalt));
102
103
        PasswordEncryptor_Blowfish::set_cost(1);
104
        $salt = $e->salt($password);
105
        $modSalt = substr($salt, 0, 3) . str_shuffle(substr($salt, 3, strlen($salt)));
106
107
        $this->assertNotEquals(1, PasswordEncryptor_Blowfish::get_cost());
108
        $this->assertEquals(4, PasswordEncryptor_Blowfish::get_cost());
109
110
        $this->assertTrue($e->check($e->encrypt($password, $salt), "mypassword", $salt));
111
        $this->assertFalse($e->check($e->encrypt($password, $salt), "anotherpw", $salt));
112
        $this->assertFalse($e->check($e->encrypt($password, $salt), "mypassword", $modSalt));
113
114
        PasswordEncryptor_Blowfish::set_cost(11);
115
        $salt = $e->salt($password);
116
        $modSalt = substr($salt, 0, 3) . str_shuffle(substr($salt, 3, strlen($salt)));
117
118
        $this->assertEquals(11, PasswordEncryptor_Blowfish::get_cost());
119
120
        $this->assertTrue($e->check($e->encrypt($password, $salt), "mypassword", $salt));
121
        $this->assertFalse($e->check($e->encrypt($password, $salt), "anotherpw", $salt));
122
        $this->assertFalse($e->check($e->encrypt($password, $salt), "mypassword", $modSalt));
123
124
125
        PasswordEncryptor_Blowfish::set_cost(35);
126
127
        $this->assertNotEquals(35, PasswordEncryptor_Blowfish::get_cost());
128
        $this->assertEquals(31, PasswordEncryptor_Blowfish::get_cost());
129
130
        //Don't actually test this one. It takes too long. 31 takes too long to process
131
    }
132
133
    public function testEncryptorPHPHashCheck()
134
    {
135
        Config::modify()->merge(
136
            PasswordEncryptor::class,
137
            'encryptors',
138
            ['test_sha1' => [PasswordEncryptor_PHPHash::class => 'sha1']]
139
        );
140
        $e = PasswordEncryptor::create_for_algorithm('test_sha1');
141
        $this->assertTrue($e->check(sha1('mypassword'), 'mypassword'));
142
        $this->assertFalse($e->check(sha1('mypassword'), 'mywrongpassword'));
143
    }
144
145
    /**
146
     * See http://open.silverstripe.org/ticket/3004
147
     *
148
     * Handy command for reproducing via CLI on different architectures:
149
     *  php -r "echo(base_convert(sha1('mypassword'), 16, 36));"
150
     */
151
    public function testEncryptorLegacyPHPHashCheck()
152
    {
153
        Config::modify()->merge(
154
            PasswordEncryptor::class,
155
            'encryptors',
156
            ['test_sha1legacy' => [PasswordEncryptor_LegacyPHPHash::class => 'sha1']]
157
        );
158
        $e = PasswordEncryptor::create_for_algorithm('test_sha1legacy');
159
        // precomputed hashes for 'mypassword' from different architectures
160
        $amdHash = 'h1fj0a6m4o6k0sosks88oo08ko4gc4s';
161
        $intelHash = 'h1fj0a6m4o0g04ocg00o4kwoc4wowws';
162
        $wrongHash = 'h1fjxxxxxxxxxxxxxxxxxxxxxxxxxxx';
163
        $this->assertTrue($e->check($amdHash, "mypassword"));
164
        $this->assertTrue($e->check($intelHash, "mypassword"));
165
        $this->assertFalse($e->check($wrongHash, "mypassword"));
166
    }
167
}
168