@@ -53,6 +53,7 @@ protected function setUp(): void
5353
5454 /**
5555 * @group time-sensitive
56+ *
5657 * @dataProvider provideCreateLoginLinkData
5758 */
5859 public function testCreateLoginLink ($ user , array $ extraProperties , Request $ request = null )
@@ -68,7 +69,7 @@ public function testCreateLoginLink($user, array $extraProperties, Request $requ
6869 // allow a small expiration offset to avoid time-sensitivity
6970 && abs (time () + 600 - $ parameters ['expires ' ]) <= 1
7071 // make sure hash is what we expect
71- && $ parameters ['hash ' ] === $ this ->createSignatureHash ('weaverryan ' , $ parameters ['expires ' ], array_values ( $ extraProperties) );
72+ && $ parameters ['hash ' ] === $ this ->createSignatureHash ('weaverryan ' , $ parameters ['expires ' ], $ extraProperties );
7273 }),
7374 UrlGeneratorInterface::ABSOLUTE_URL
7475 )
@@ -127,7 +128,7 @@ public function testCreateLoginLinkWithLifetime()
127128 && abs (time () + 1000 - $ parameters ['expires ' ]) <= 1
128129 && isset ($ parameters ['hash ' ])
129130 // make sure hash is what we expect
130- && $ parameters ['hash ' ] === $ this ->createSignatureHash ('weaverryan ' , $ parameters ['expires ' ], array_values ( $ extraProperties) );
131+ && $ parameters ['hash ' ] === $ this ->createSignatureHash ('weaverryan ' , $ parameters ['expires ' ], $ extraProperties );
131132 }),
132133 UrlGeneratorInterface::ABSOLUTE_URL
133134 )
@@ -147,7 +148,7 @@ public function testCreateLoginLinkWithLifetime()
147148 public function testConsumeLoginLink ()
148149 {
149150 $ expires = time () + 500 ;
150- $ signature =
$ this ->
createSignatureHash (
'weaverryan ' ,
$ expires, [ ' [email protected] ' , ' pwhash ' ] );
151+ $ signature = $ this ->createSignatureHash ('weaverryan ' , $ expires );
151152 $ request = Request::create (sprintf ('/login/verify?user=weaverryan&hash=%s&expires=%d ' , $ signature , $ expires ));
152153
153154 $ user =
new TestLoginLinkHandlerUser (
'weaverryan ' ,
'[email protected] ' ,
'pwhash ' );
@@ -163,44 +164,37 @@ public function testConsumeLoginLink()
163164
164165 public function testConsumeLoginLinkWithExpired ()
165166 {
166- $ this ->expectException (ExpiredLoginLinkException::class);
167167 $ expires = time () - 500 ;
168- $ signature =
$ this ->
createSignatureHash (
'weaverryan ' ,
$ expires, [ ' [email protected] ' , ' pwhash ' ] );
168+ $ signature = $ this ->createSignatureHash ('weaverryan ' , $ expires );
169169 $ request = Request::create (sprintf ('/login/verify?user=weaverryan&hash=%s&expires=%d ' , $ signature , $ expires ));
170170
171- $ user =
new TestLoginLinkHandlerUser (
'weaverryan ' ,
'[email protected] ' ,
'pwhash ' );
172- $ this ->userProvider ->createUser ($ user );
173-
174171 $ linker = $ this ->createLinker (['max_uses ' => 3 ]);
172+ $ this ->expectException (ExpiredLoginLinkException::class);
175173 $ linker ->consumeLoginLink ($ request );
176174 }
177175
178176 public function testConsumeLoginLinkWithUserNotFound ()
179177 {
180- $ this ->expectException (InvalidLoginLinkException::class);
181- $ request = Request::create ('/login/verify?user=weaverryan&hash=thehash&expires=10000 ' );
178+ $ request = Request::create ('/login/verify?user=weaverryan&hash=thehash&expires= ' .(time () + 500 ));
182179
183180 $ linker = $ this ->createLinker ();
181+ $ this ->expectException (InvalidLoginLinkException::class);
184182 $ linker ->consumeLoginLink ($ request );
185183 }
186184
187185 public function testConsumeLoginLinkWithDifferentSignature ()
188186 {
189- $ this ->expectException (InvalidLoginLinkException::class);
190187 $ request = Request::create (sprintf ('/login/verify?user=weaverryan&hash=fake_hash&expires=%d ' , time () + 500 ));
191188
192- $ user =
new TestLoginLinkHandlerUser (
'weaverryan ' ,
'[email protected] ' ,
'pwhash ' );
193- $ this ->userProvider ->createUser ($ user );
194-
195189 $ linker = $ this ->createLinker ();
190+ $ this ->expectException (InvalidLoginLinkException::class);
196191 $ linker ->consumeLoginLink ($ request );
197192 }
198193
199194 public function testConsumeLoginLinkExceedsMaxUsage ()
200195 {
201- $ this ->expectException (ExpiredLoginLinkException::class);
202196 $ expires = time () + 500 ;
203- $ signature =
$ this ->
createSignatureHash (
'weaverryan ' ,
$ expires, [ ' [email protected] ' , ' pwhash ' ] );
197+ $ signature = $ this ->createSignatureHash ('weaverryan ' , $ expires );
204198 $ request = Request::create (sprintf ('/login/verify?user=weaverryan&hash=%s&expires=%d ' , $ signature , $ expires ));
205199
206200 $ user =
new TestLoginLinkHandlerUser (
'weaverryan ' ,
'[email protected] ' ,
'pwhash ' );
@@ -211,6 +205,7 @@ public function testConsumeLoginLinkExceedsMaxUsage()
211205 $ this ->expiredLinkCache ->save ($ item );
212206
213207 $ linker = $ this ->createLinker (['max_uses ' => 3 ]);
208+ $ this ->expectException (ExpiredLoginLinkException::class);
214209 $ linker ->consumeLoginLink ($ request );
215210 }
216211
@@ -238,15 +233,12 @@ public function testConsumeLoginLinkWithMissingExpiration()
238233 $ linker ->consumeLoginLink ($ request );
239234 }
240235
241- private function createSignatureHash (string $ username , int $ expires , array $ extraFields ): string
236+ private function createSignatureHash (
string $ username,
int $ expires,
array $ extraFields = [ ' emailProperty ' => ' [email protected] ' , ' passwordProperty ' => ' pwhash ' ] ):
string 242237 {
243- $ fields = [base64_encode ($ username ), $ expires ];
244- foreach ($ extraFields as $ extraField ) {
245- $ fields [] = base64_encode ($ extraField );
246- }
238+ $ hasher = new SignatureHasher ($ this ->propertyAccessor , array_keys ($ extraFields ), 's3cret ' );
239+ $ user = new TestLoginLinkHandlerUser ($ username , $ extraFields ['emailProperty ' ] ?? '' , $ extraFields ['passwordProperty ' ] ?? '' , $ extraFields ['lastAuthenticatedAt ' ] ?? null );
247240
248- // matches hash logic in the class
249- return base64_encode (hash_hmac ('sha256 ' , implode (': ' , $ fields ), 's3cret ' ));
241+ return $ hasher ->computeSignatureHash ($ user , $ expires );
250242 }
251243
252244 private function createLinker (array $ options = [], array $ extraProperties = ['emailProperty ' , 'passwordProperty ' ]): LoginLinkHandler
@@ -330,7 +322,7 @@ public function loadUserByIdentifier(string $userIdentifier): TestLoginLinkHandl
330322
331323 public function refreshUser (UserInterface $ user ): TestLoginLinkHandlerUser
332324 {
333- return $ this ->users [$ username ];
325+ return $ this ->users [$ user -> getUserIdentifier () ];
334326 }
335327
336328 public function supportsClass (string $ class ): bool
0 commit comments