Completed
Pull Request — master (#5741)
by Damian
12:40
created

PasswordEncryptorTest::testEncryptorBlowfish()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 48
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 32
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 48
rs 9.125
1
<?php
2
3
use SilverStripe\Security\PasswordEncryptor_Blowfish;
4
use SilverStripe\Security\PasswordEncryptor;
5
6
class PasswordEncryptorTest extends SapphireTest {
7
8
	/**
9
	 *
10
	 * @var Config
11
	 */
12
	private $config = null;
13
14
	public function setUp() {
15
		parent::setUp();
16
		$this->config = clone(Config::inst());
17
	}
18
19
	public function tearDown() {
20
		parent::tearDown();
21
		Config::set_instance($this->config);
22
		PasswordEncryptor_Blowfish::set_cost(10);
23
	}
24
25
	public function testCreateForCode() {
26
		Config::inst()->update(
27
			'SilverStripe\\Security\\PasswordEncryptor',
28
			'encryptors',
29
			['test' => ['PasswordEncryptorTest_TestEncryptor' => null]]
30
		);
31
		$e = PasswordEncryptor::create_for_algorithm('test');
32
		$this->assertInstanceOf('PasswordEncryptorTest_TestEncryptor', $e );
33
	}
34
35
	/**
36
	 * @expectedException SilverStripe\Security\PasswordEncryptor_NotFoundException
37
	 */
38
	public function testCreateForCodeNotFound() {
39
		PasswordEncryptor::create_for_algorithm('unknown');
40
	}
41
42
	public function testRegister() {
43
		Config::inst()->update(
44
			'SilverStripe\\Security\\PasswordEncryptor',
45
			'encryptors',
46
			array('test' => array('PasswordEncryptorTest_TestEncryptor' => null))
47
		);
48
		$encryptors = PasswordEncryptor::get_encryptors();
49
		$this->assertContains('test', array_keys($encryptors));
50
		$encryptor = $encryptors['test'];
51
		$this->assertContains('PasswordEncryptorTest_TestEncryptor', key($encryptor));
52
	}
53
54
	public function testUnregister() {
55
		Config::inst()->update(
56
			'SilverStripe\\Security\\PasswordEncryptor',
57
			'encryptors',
58
			array('test' => array('PasswordEncryptorTest_TestEncryptor' => null))
59
		);
60
		Config::inst()->remove('SilverStripe\\Security\\PasswordEncryptor', 'encryptors', 'test');
61
		$this->assertNotContains('test', array_keys(PasswordEncryptor::get_encryptors()));
62
	}
63
64
	public function testEncryptorPHPHashWithArguments() {
65
		Config::inst()->update(
66
			'SilverStripe\\Security\\PasswordEncryptor',
67
			'encryptors',
68
			['test_md5' => ['SilverStripe\\Security\\PasswordEncryptor_PHPHash'=>'md5']]
69
		);
70
		$e = PasswordEncryptor::create_for_algorithm('test_md5');
71
		$this->assertEquals('md5', $e->getAlgorithm());
72
	}
73
74
	public function testEncryptorPHPHash() {
75
		Config::inst()->update(
76
			'SilverStripe\\Security\\PasswordEncryptor',
77
			'encryptors',
78
			['test_sha1' => ['SilverStripe\\Security\\PasswordEncryptor_PHPHash' => 'sha1']]
79
		);
80
		$e = PasswordEncryptor::create_for_algorithm('test_sha1');
81
		$password = 'mypassword';
82
		$salt = 'mysalt';
83
		$this->assertEquals(
84
			hash('sha1', $password . $salt),
85
			$e->encrypt($password, $salt)
86
		);
87
	}
88
89
	public function testEncryptorBlowfish() {
90
		Config::inst()->update(
91
			'SilverStripe\\Security\\PasswordEncryptor',
92
			'encryptors',
93
			['test_blowfish' => ['SilverStripe\\Security\\PasswordEncryptor_Blowfish' => '']]
94
		);
95
		$e = PasswordEncryptor::create_for_algorithm('test_blowfish');
96
97
		$password = 'mypassword';
98
99
		$salt = $e->salt($password);
100
		$modSalt = substr($salt, 0, 3) . str_shuffle(substr($salt, 3, strlen($salt)));
101
102
		$this->assertTrue($e->checkAEncryptionLevel() == 'y' || $e->checkAEncryptionLevel() == 'x'
0 ignored issues
show
Bug introduced by
The method checkAEncryptionLevel() does not exist on SilverStripe\Security\PasswordEncryptor. Did you maybe mean encrypt()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
103
			|| $e->checkAEncryptionLevel() == 'a');
0 ignored issues
show
Bug introduced by
The method checkAEncryptionLevel() does not exist on SilverStripe\Security\PasswordEncryptor. Did you maybe mean encrypt()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
104
		$this->assertTrue($e->check($e->encrypt($password, $salt), "mypassword", $salt));
105
		$this->assertFalse($e->check($e->encrypt($password, $salt), "anotherpw", $salt));
106
		$this->assertFalse($e->check($e->encrypt($password, $salt), "mypassword", $modSalt));
107
108
		PasswordEncryptor_Blowfish::set_cost(1);
109
		$salt = $e->salt($password);
110
		$modSalt = substr($salt, 0, 3) . str_shuffle(substr($salt, 3, strlen($salt)));
111
112
		$this->assertNotEquals(1, PasswordEncryptor_Blowfish::get_cost());
113
		$this->assertEquals(4, PasswordEncryptor_Blowfish::get_cost());
114
115
		$this->assertTrue($e->check($e->encrypt($password, $salt), "mypassword", $salt));
116
		$this->assertFalse($e->check($e->encrypt($password, $salt), "anotherpw", $salt));
117
		$this->assertFalse($e->check($e->encrypt($password, $salt), "mypassword", $modSalt));
118
119
		PasswordEncryptor_Blowfish::set_cost(11);
120
		$salt = $e->salt($password);
121
		$modSalt = substr($salt, 0, 3) . str_shuffle(substr($salt, 3, strlen($salt)));
122
123
		$this->assertEquals(11, PasswordEncryptor_Blowfish::get_cost());
124
125
		$this->assertTrue($e->check($e->encrypt($password, $salt), "mypassword", $salt));
126
		$this->assertFalse($e->check($e->encrypt($password, $salt), "anotherpw", $salt));
127
		$this->assertFalse($e->check($e->encrypt($password, $salt), "mypassword", $modSalt));
128
129
130
		PasswordEncryptor_Blowfish::set_cost(35);
131
132
		$this->assertNotEquals(35, PasswordEncryptor_Blowfish::get_cost());
133
		$this->assertEquals(31, PasswordEncryptor_Blowfish::get_cost());
134
135
		//Don't actually test this one. It takes too long. 31 takes too long to process
136
	}
137
138
	public function testEncryptorPHPHashCheck() {
139
		Config::inst()->update(
140
			'SilverStripe\\Security\\PasswordEncryptor',
141
			'encryptors',
142
			['test_sha1' => ['SilverStripe\\Security\\PasswordEncryptor_PHPHash' => 'sha1']]
143
		);
144
		$e = PasswordEncryptor::create_for_algorithm('test_sha1');
145
		$this->assertTrue($e->check(sha1('mypassword'), 'mypassword'));
146
		$this->assertFalse($e->check(sha1('mypassword'), 'mywrongpassword'));
147
	}
148
149
	/**
150
	 * See http://open.silverstripe.org/ticket/3004
151
	 *
152
	 * Handy command for reproducing via CLI on different architectures:
153
	 * 	php -r "echo(base_convert(sha1('mypassword'), 16, 36));"
154
	 */
155
	public function testEncryptorLegacyPHPHashCheck() {
156
		Config::inst()->update(
157
			'SilverStripe\\Security\\PasswordEncryptor',
158
			'encryptors',
159
			['test_sha1legacy' => ['SilverStripe\\Security\\PasswordEncryptor_LegacyPHPHash' => 'sha1']]
160
		);
161
		$e = PasswordEncryptor::create_for_algorithm('test_sha1legacy');
162
		// precomputed hashes for 'mypassword' from different architectures
163
		$amdHash = 'h1fj0a6m4o6k0sosks88oo08ko4gc4s';
164
		$intelHash = 'h1fj0a6m4o0g04ocg00o4kwoc4wowws';
165
		$wrongHash = 'h1fjxxxxxxxxxxxxxxxxxxxxxxxxxxx';
166
		$this->assertTrue($e->check($amdHash, "mypassword"));
167
		$this->assertTrue($e->check($intelHash, "mypassword"));
168
		$this->assertFalse($e->check($wrongHash, "mypassword"));
169
	}
170
}
171
172
class PasswordEncryptorTest_TestEncryptor extends PasswordEncryptor implements TestOnly {
173
	public function encrypt($password, $salt = null, $member = null) {
174
		return 'password';
175
	}
176
177
	public function salt($password, $member = null) {
178
		return 'salt';
179
	}
180
}
181