18
18
use App \Helpers \FailureHelper ;
19
19
use Nette \Utils \Arrays ;
20
20
use Nette \Http \IResponse ;
21
+ use Tracy \ILogger ;
21
22
use Firebase \JWT \JWT ;
22
23
use Firebase \JWT \Key ;
23
24
use DomainException ;
@@ -46,6 +47,9 @@ class ExternalServiceAuthenticator
46
47
/** @var FailureHelper */
47
48
public $ failureHelper ;
48
49
50
+ /** @var ILogger|null */
51
+ public $ logger = null ;
52
+
49
53
/**
50
54
* @var array [ name => { jwtSecret, expiration } ]
51
55
*/
@@ -67,13 +71,15 @@ public function __construct(
67
71
Instances $ instances ,
68
72
EmailVerificationHelper $ emailVerificationHelper ,
69
73
FailureHelper $ failureHelper ,
74
+ ?ILogger $ logger = null ,
70
75
) {
71
76
$ this ->externalLogins = $ externalLogins ;
72
77
$ this ->users = $ users ;
73
78
$ this ->logins = $ logins ;
74
79
$ this ->instances = $ instances ;
75
80
$ this ->emailVerificationHelper = $ emailVerificationHelper ;
76
81
$ this ->failureHelper = $ failureHelper ;
82
+ $ this ->logger = $ logger ;
77
83
78
84
foreach ($ authenticators as $ auth ) {
79
85
if (!empty ($ auth ['name ' ] && !empty ($ auth ['jwtSecret ' ]))) {
@@ -89,6 +95,18 @@ public function __construct(
89
95
}
90
96
}
91
97
98
+ private function log ($ level , $ msg , ...$ args )
99
+ {
100
+ if (!$ this ->logger ) {
101
+ return ;
102
+ }
103
+
104
+ if ($ args ) {
105
+ $ msg = sprintf ($ msg , ...$ args );
106
+ }
107
+ $ this ->logger ->log ($ msg , $ level );
108
+ }
109
+
92
110
/**
93
111
* Verify that given authenticator exists.
94
112
* @param string $name of the external authenticator
@@ -129,6 +147,15 @@ public function authenticate(string $authName, string $token, string $instanceId
129
147
// try to match existing local user by email address
130
148
if ($ user === null ) {
131
149
$ user = $ this ->tryConnect ($ authName , $ userData );
150
+ if ($ user ) {
151
+ $ this ->log (
152
+ ILogger::INFO ,
153
+ "User '%s' was paired with external ID='%s' (%s) " ,
154
+ $ user ->getId (),
155
+ $ userData ->getId (),
156
+ $ authName
157
+ );
158
+ }
132
159
}
133
160
134
161
// try to register a new user
@@ -148,6 +175,13 @@ public function authenticate(string $authName, string $token, string $instanceId
148
175
// connect the account to the login method
149
176
$ this ->externalLogins ->connect ($ authName , $ user , $ userData ->getId ());
150
177
$ this ->emailVerificationHelper ->process ($ user , true ); // true = just created
178
+ $ this ->log (
179
+ ILogger::INFO ,
180
+ "User '%s' just registered via external auth '%s' (ID='%s') " ,
181
+ $ user ->getId (),
182
+ $ authName ,
183
+ $ userData ->getId ()
184
+ );
151
185
}
152
186
}
153
187
@@ -259,13 +293,23 @@ private function handleExtraIds(User $user, $decodedToken, array $allowedService
259
293
return ;
260
294
}
261
295
296
+ $ this ->log (ILogger::DEBUG , "User '%s' got extra IDs: %s " , $ user ->getId (), json_encode ($ decodedToken ->extId ));
297
+
262
298
foreach ($ decodedToken ->extId as $ service => $ eid ) {
263
299
if (!in_array ($ service , $ allowedServices )) {
300
+ $ this ->log (
301
+ ILogger::DEBUG ,
302
+ "User '%s' got new [%s] ID='%s', but this auth service is not allowed " ,
303
+ $ user ->getId (),
304
+ $ service ,
305
+ $ eid
306
+ );
307
+
264
308
continue ; // skip services that are not allowed
265
309
}
266
310
267
311
$ extUser = $ this ->externalLogins ->getUser ($ service , $ eid );
268
- if ($ extUser ) {
312
+ if ($ extUser ) { // a user with given ID exists
269
313
if ($ extUser ->getId () !== $ user ->getId ()) {
270
314
// Identity crysis! ID belongs to another user...
271
315
$ this ->failureHelper ->report (
@@ -285,14 +329,26 @@ private function handleExtraIds(User $user, $decodedToken, array $allowedService
285
329
}
286
330
287
331
$ login = $ this ->externalLogins ->findByUser ($ user , $ service );
288
- if ($ login ->getExternalId () !== $ eid ) {
289
- // extra ID has changed (strange, but possible)
290
- $ login ->setExternalId ($ eid );
291
- $ this ->externalLogins ->persist ($ login );
292
- continue ;
332
+ if ($ login ) { // a connected external login record for the auth service already exist
333
+ if ($ login ->getExternalId () !== $ eid ) {
334
+ // extra ID has changed (strange, but possible)
335
+ $ this ->log (
336
+ ILogger::INFO ,
337
+ "User '%s' got new [%s] ID='%s', but already had different ID='%s' " ,
338
+ $ user ->getId (),
339
+ $ service ,
340
+ $ eid ,
341
+ $ login ->getExternalId ()
342
+ );
343
+ $ login ->setExternalId ($ eid );
344
+ $ this ->externalLogins ->persist ($ login );
345
+ }
346
+
347
+ continue ; // either already exist or was duly updated
293
348
}
294
349
295
350
$ this ->externalLogins ->connect ($ service , $ user , $ eid );
351
+ $ this ->log (ILogger::INFO , "User '%s' got new extra ID='%s' [%s] " , $ user ->getId (), $ eid , $ service );
296
352
}
297
353
}
298
354
}
0 commit comments