Completed
Push — master ( da34c0...e18438 )
by Tom
05:01 queued 04:53
created

testWillRequireCredentialValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 15
rs 9.4285
cc 1
eloc 10
nc 1
nop 0
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace DoctrineModuleTest\Authentication\Adapter;
21
22
use PHPUnit_Framework_TestCase as BaseTestCase;
23
use DoctrineModule\Authentication\Adapter\ObjectRepository as ObjectRepositoryAdapter;
24
use DoctrineModuleTest\Authentication\Adapter\TestAsset\IdentityObject;
25
use DoctrineModuleTest\Authentication\Adapter\TestAsset\PublicPropertiesIdentityObject;
26
27
/**
28
 * Tests for the ObjectRepository based authentication adapter
29
 *
30
 * @license MIT
31
 * @link    http://www.doctrine-project.org/
32
 * @author  Marco Pivetta <[email protected]>
33
 */
34
class ObjectRepositoryTest extends BaseTestCase
35
{
36
    public function testWillRejectInvalidIdentityProperty()
37
    {
38
        $this->setExpectedException(
39
            'Zend\Authentication\Adapter\Exception\InvalidArgumentException',
40
            'Provided $identityProperty is invalid, boolean given'
41
        );
42
43
        new ObjectRepositoryAdapter(['identity_property' => false]);
44
    }
45
46
    public function testWillRejectInvalidCredentialProperty()
47
    {
48
        $this->setExpectedException(
49
            'Zend\Authentication\Adapter\Exception\InvalidArgumentException',
50
            'Provided $credentialProperty is invalid, boolean given'
51
        );
52
        new ObjectRepositoryAdapter(['credential_property' => false]);
53
    }
54
55
    public function testWillRequireIdentityValue()
56
    {
57
        $this->setExpectedException(
58
            'Zend\Authentication\Adapter\Exception\RuntimeException',
59
            'A value for the identity was not provided prior to authentication with ObjectRepository authentication '
60
            . 'adapter'
61
        );
62
        $adapter = new ObjectRepositoryAdapter();
63
        $adapter->setOptions([
64
            'object_manager' => $this->getMock('Doctrine\Common\Persistence\ObjectManager'),
65
            'identity_class' => 'DoctrineModuleTest\Authentication\Adapter\TestAsset\IdentityObject',
66
        ]);
67
        $adapter->setCredential('a credential');
68
        $adapter->authenticate();
69
    }
70
71
    public function testWillRequireCredentialValue()
72
    {
73
        $this->setExpectedException(
74
            'Zend\Authentication\Adapter\Exception\RuntimeException',
75
            'A credential value was not provided prior to authentication with ObjectRepository authentication adapter'
76
        );
77
        $adapter = new ObjectRepositoryAdapter();
78
        $adapter->setOptions([
79
            'object_manager' => $this->getMock('Doctrine\Common\Persistence\ObjectManager'),
80
            'identity_class' => 'DoctrineModuleTest\Authentication\Adapter\TestAsset\IdentityObject',
81
        ]);
82
83
        $adapter->setIdentity('an identity');
84
        $adapter->authenticate();
85
    }
86
87
    public function testWillRejectInvalidCredentialCallable()
88
    {
89
        $this->setExpectedException(
90
            'Zend\Authentication\Adapter\Exception\InvalidArgumentException',
91
            '"array" is not a callable'
92
        );
93
        $adapter = new ObjectRepositoryAdapter();
94
        $adapter->setOptions([
95
            'object_manager'      => $this->getMock('Doctrine\Common\Persistence\ObjectManager'),
96
            'identity_class'      => 'DoctrineModuleTest\Authentication\Adapter\TestAsset\IdentityObject',
97
            'credential_callable' => [],
98
        ]);
99
100
        $adapter->authenticate();
101
    }
102
103
    public function testAuthentication()
104
    {
105
        $entity = new IdentityObject();
106
        $entity->setUsername('a username');
107
        $entity->setPassword('a password');
108
109
        $objectRepository = $this->getMock('Doctrine\Common\Persistence\ObjectRepository');
110
        $method           = $objectRepository
111
            ->expects($this->exactly(2))
112
            ->method('findOneBy')
113
            ->with($this->equalTo(['username' => 'a username']))
114
            ->will($this->returnValue($entity));
115
116
        $objectManager = $this->getMock('Doctrine\Common\Persistence\ObjectManager');
117
        $objectManager->expects($this->exactly(2))
118
                      ->method('getRepository')
119
                      ->with($this->equalTo('DoctrineModuleTest\Authentication\Adapter\TestAsset\IdentityObject'))
120
                      ->will($this->returnValue($objectRepository));
121
122
        $adapter = new ObjectRepositoryAdapter();
123
        $adapter->setOptions([
124
            'object_manager'      => $objectManager,
125
            'identity_class'      => 'DoctrineModuleTest\Authentication\Adapter\TestAsset\IdentityObject',
126
            'credential_property' => 'password',
127
            'identity_property'   => 'username',
128
        ]);
129
130
        $adapter->setIdentity('a username');
131
        $adapter->setCredential('a password');
132
133
        $result = $adapter->authenticate();
134
135
        $this->assertTrue($result->isValid());
136
        $this->assertInstanceOf(
137
            'DoctrineModuleTest\Authentication\Adapter\TestAsset\IdentityObject',
138
            $result->getIdentity()
139
        );
140
141
        $method->will($this->returnValue(null));
142
143
        $result = $adapter->authenticate();
144
145
        $this->assertFalse($result->isValid());
146
    }
147
148
    public function testAuthenticationWithPublicProperties()
149
    {
150
        $entity           = new PublicPropertiesIdentityObject();
151
        $entity->username = 'a username';
152
        $entity->password = 'a password';
153
154
        $objectRepository = $this->getMock('Doctrine\Common\Persistence\ObjectRepository');
155
        $method           = $objectRepository
156
            ->expects($this->exactly(2))
157
            ->method('findOneBy')
158
            ->with($this->equalTo(['username' => 'a username']))
159
            ->will($this->returnValue($entity));
160
161
        $adapter = new ObjectRepositoryAdapter();
162
        $adapter->setOptions([
163
            'object_repository' => $objectRepository,
164
            'credential_property' => 'password',
165
            'identity_property' => 'username',
166
        ]);
167
168
        $adapter->setIdentity('a username');
169
        $adapter->setCredential('a password');
170
171
        $result = $adapter->authenticate();
172
173
        $this->assertTrue($result->isValid());
174
175
        $method->will($this->returnValue(null));
176
177
        $result = $adapter->authenticate();
178
179
        $this->assertFalse($result->isValid());
180
    }
181
182
    public function testWillRefuseToAuthenticateWithoutGettersOrPublicMethods()
183
    {
184
        $this->setExpectedException('Zend\Authentication\Adapter\Exception\UnexpectedValueException');
185
186
        $objectRepository = $this->getMock('Doctrine\Common\Persistence\ObjectRepository');
187
        $objectRepository
188
            ->expects($this->once())
189
            ->method('findOneBy')
190
            ->with($this->equalTo(['username' => 'a username']))
191
            ->will($this->returnValue(new \stdClass()));
192
193
        $adapter = new ObjectRepositoryAdapter();
194
        $adapter->setOptions([
195
            'object_repository' => $objectRepository,
196
            'credential_property' => 'password',
197
            'identity_property' => 'username',
198
        ]);
199
200
        $adapter->setIdentity('a username');
201
        $adapter->setCredential('a password');
202
        $adapter->authenticate();
203
    }
204
205
    public function testCanValidateWithSpecialCrypt()
206
    {
207
        $hash   = '$2y$07$usesomesillystringforsalt$';
208
        $entity = new IdentityObject();
209
        $entity->setUsername('username');
210
        // Crypt password using Blowfish
211
        $entity->setPassword(crypt('password', $hash));
212
213
        $objectRepository = $this->getMock('Doctrine\Common\Persistence\ObjectRepository');
214
        $objectRepository
215
            ->expects($this->exactly(2))
216
            ->method('findOneBy')
217
            ->with($this->equalTo(['username' => 'username']))
218
            ->will($this->returnValue($entity));
219
220
        $adapter = new ObjectRepositoryAdapter();
221
        $adapter->setOptions([
222
            'object_repository' => $objectRepository,
223
            'credential_property' => 'password',
224
            'identity_property' => 'username',
225
            // enforced type hinting to verify that closure is invoked correctly
226
            'credential_callable' => function (IdentityObject $identity, $credentialValue) use ($hash) {
227
                return $identity->getPassword() === crypt($credentialValue, $hash);
228
            },
229
        ]);
230
231
        $adapter->setIdentity('username');
232
        $adapter->setCredential('password');
233
234
        $result = $adapter->authenticate();
235
236
        $this->assertTrue($result->isValid());
237
238
        $adapter->setCredential('wrong password');
239
        $result = $adapter->authenticate();
240
241
        $this->assertFalse($result->isValid());
242
    }
243
244
    public function testWillRefuseToAuthenticateWhenInvalidInstanceIsFound()
245
    {
246
        $this->setExpectedException('Zend\Authentication\Adapter\Exception\UnexpectedValueException');
247
248
        $objectRepository = $this->getMock('Doctrine\Common\Persistence\ObjectRepository');
249
        $objectRepository
250
            ->expects($this->once())
251
            ->method('findOneBy')
252
            ->with($this->equalTo(['username' => 'a username']))
253
            ->will($this->returnValue(new \stdClass()));
254
255
        $adapter = new ObjectRepositoryAdapter();
256
        $adapter->setOptions([
257
            'object_repository'   => $objectRepository,
258
            'credential_property' => 'password',
259
            'identity_property'   => 'username',
260
        ]);
261
262
        $adapter->setIdentity('a username');
263
        $adapter->setCredential('a password');
264
265
        $adapter->authenticate();
266
    }
267
268
    public function testWillNotCastAuthCredentialValue()
269
    {
270
        $objectRepository = $this->getMock('Doctrine\Common\Persistence\ObjectRepository');
271
        $adapter          = new ObjectRepositoryAdapter();
272
        $entity           = new IdentityObject();
273
274
        $entity->setPassword(0);
275
        $adapter->setOptions([
276
             'object_repository'   => $objectRepository,
277
             'credential_property' => 'password',
278
             'identity_property'   => 'username',
279
        ]);
280
        $adapter->setIdentity('a username');
281
        $adapter->setCredential('00000');
282
        $objectRepository
283
            ->expects($this->once())
284
            ->method('findOneBy')
285
            ->with($this->equalTo(['username' => 'a username']))
286
            ->will($this->returnValue($entity));
287
288
        $this->assertFalse($adapter->authenticate()->isValid());
289
    }
290
}
291