Skip to content

Commit 8ee3a3e

Browse files
committed
refactor PasswordRehash configuration
1 parent 3c89c1e commit 8ee3a3e

File tree

2 files changed

+153
-1
lines changed

2 files changed

+153
-1
lines changed

config/users.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,9 @@
284284
],
285285
'RbacPolicy' => [],
286286
'PasswordRehash' => [
287-
'identifiers' => ['Password'],
287+
'authenticators' => [
288+
'Form' => 'Authentication.Password',
289+
],
288290
],
289291
],
290292
'OAuth' => [

tests/TestCase/Controller/Traits/LoginTraitTest.php

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@
2222
use Cake\Event\Event;
2323
use Cake\Http\Response;
2424
use Cake\Http\ServerRequest;
25+
use CakeDC\Auth\Authentication\AuthenticationService;
2526
use CakeDC\Auth\Authentication\Failure;
2627
use CakeDC\Auth\Authenticator\FormAuthenticator;
2728
use CakeDC\Users\Authenticator\SocialAuthenticator;
2829
use CakeDC\Users\Controller\Component\LoginComponent;
2930

31+
use Authentication\Authenticator\AuthenticatorCollection;
32+
3033
class LoginTraitTest extends BaseTrait
3134
{
3235
/**
@@ -219,6 +222,153 @@ public function testLoginRehash()
219222
$this->assertTrue($check);
220223
}
221224

225+
226+
/**
227+
* Test para verificar el Rehashing con la estructura de configuración anidada (Cake 5)
228+
* Fix para issue #1170
229+
*
230+
* @return void
231+
*/
232+
/*
233+
public function testLoginRehashWithAuthenticatorStructure()
234+
{
235+
// 1. Configuración del Plugin
236+
\Cake\Core\Configure::write('Auth.PasswordRehash', [
237+
'authenticators' => [
238+
'Form' => 'Authentication.Password'
239+
]
240+
]);
241+
242+
// 2. Preparación de datos
243+
$userId = '00000000-0000-0000-0000-000000000002';
244+
$user = $this->Trait->getUsersTable()->get($userId);
245+
$oldHash = '$2y$10$OldHashNeedsUpgrade00000000000000000000000000000000';
246+
$user->password = $oldHash;
247+
$this->Trait->getUsersTable()->save($user);
248+
249+
// 3. Construcción de Mocks (Estilo Cake 5)
250+
251+
// A. Identifier
252+
$passwordIdentifier = $this->getMockBuilder(PasswordIdentifier::class)
253+
->onlyMethods(['needsPasswordRehash'])
254+
->getMock();
255+
$passwordIdentifier->expects($this->any())
256+
->method('needsPasswordRehash')
257+
->willReturn(true);
258+
259+
// B. Identifier Collection
260+
$identifierCollection = new IdentifierCollection([]);
261+
$identifierCollection->set('Authentication.Password', $passwordIdentifier);
262+
263+
// C. Authenticator
264+
$formAuthenticator = $this->getMockBuilder(FormAuthenticator::class)
265+
->disableOriginalConstructor()
266+
->addMethods(['getIdentifier'])
267+
->getMock();
268+
$formAuthenticator->expects($this->any())
269+
->method('getIdentifier')
270+
->willReturn($identifierCollection);
271+
272+
// D. Authenticator Collection
273+
$authenticatorCollection = $this->getMockBuilder(AuthenticatorCollection::class)
274+
->disableOriginalConstructor()
275+
->getMock();
276+
$authenticatorCollection->expects($this->any())
277+
->method('has')->with('Form')->willReturn(true);
278+
$authenticatorCollection->expects($this->any())
279+
->method('get')->with('Form')->willReturn($formAuthenticator);
280+
281+
// E. Servicio
282+
$service = $this->getMockBuilder(AuthenticationService::class)
283+
->disableOriginalConstructor()
284+
->getMock();
285+
$service->expects($this->any())
286+
->method('authenticators')
287+
->willReturn($authenticatorCollection);
288+
$service->expects($this->any())
289+
->method('identifiers')
290+
->willReturn(new IdentifierCollection([]));
291+
$service->expects($this->any())
292+
->method('getAuthenticationProvider')
293+
->willReturn($formAuthenticator);
294+
295+
$result = new Result($user, Result::SUCCESS);
296+
$service->expects($this->any())->method('getResult')->willReturn($result);
297+
298+
// 4. Configuración del Request
299+
$this->_mockDispatchEvent(new Event('event'));
300+
301+
$request = $this->getMockBuilder('Cake\Http\ServerRequest')
302+
->onlyMethods(['is', 'getData'])
303+
->getMock();
304+
305+
$request->expects($this->any())
306+
->method('is')
307+
->with('post')
308+
->will($this->returnValue(true));
309+
310+
$request->expects($this->any())
311+
->method('getData')
312+
->will($this->returnCallback(function($key = null) use ($user) {
313+
if ($key === 'password') return 'password123';
314+
if ($key === 'username' || $key === 'email') return $user->email;
315+
return [];
316+
}));
317+
318+
// --- CORRECCIÓN AQUÍ: Envolvemos el usuario en Identity ---
319+
$identityWrapper = new \Authentication\Identity($user);
320+
321+
$request = $request->withAttribute('authentication', $service);
322+
$request = $request->withAttribute('identity', $identityWrapper); // Usamos el wrapper, no el user directo
323+
324+
$this->Trait->setRequest($request);
325+
326+
// 5. Configuración del Componente Login
327+
$registry = new ComponentRegistry(new \Cake\Controller\Controller(new \Cake\Http\ServerRequest()));
328+
$config = [
329+
'component' => 'CakeDC/Users.Login',
330+
'targetAuthenticator' => FormAuthenticator::class,
331+
'PasswordRehash' => [
332+
'authenticators' => ['Form' => 'Authentication.Password']
333+
]
334+
];
335+
336+
$Login = $this->getMockBuilder(LoginComponent::class)
337+
->onlyMethods(['getController'])
338+
->setConstructorArgs([$registry, $config])
339+
->getMock();
340+
341+
$Login->expects($this->any())
342+
->method('getController')
343+
->will($this->returnValue($this->Trait));
344+
345+
$this->Trait->expects($this->any())
346+
->method('loadComponent')
347+
->with(
348+
$this->equalTo('CakeDC/Users.Login'),
349+
$this->anything()
350+
)
351+
->will($this->returnValue($Login));
352+
353+
// 6. Ejecución
354+
$this->_mockFlash();
355+
$this->Trait->expects($this->once())
356+
->method('redirect')
357+
->will($this->returnValue(new Response()));
358+
359+
$this->Trait->login();
360+
361+
// 7. Aserciones
362+
$userAfter = $this->Trait->getUsersTable()->get($userId);
363+
364+
$this->assertNotEquals(
365+
$oldHash,
366+
$userAfter->password,
367+
'El password debería haber sido actualizado (rehashed)'
368+
);
369+
}
370+
/* */
371+
222372
/**
223373
* test
224374
*

0 commit comments

Comments
 (0)