Skip to content

Commit 8e57889

Browse files
committed
Fix triggering a missing attribute violation
1 parent 50f0f48 commit 8e57889

File tree

2 files changed

+37
-14
lines changed

2 files changed

+37
-14
lines changed

src/Sentry/Laravel/EventHandler.php

+22-3
Original file line numberDiff line numberDiff line change
@@ -274,14 +274,24 @@ private function configureUserScopeFromModel($authUser): void
274274

275275
// If the user is a Laravel Eloquent model we try to extract some common fields from it
276276
if ($authUser instanceof Model) {
277-
$username = $authUser->getAttribute('username');
277+
$email = null;
278+
279+
if ($this->modelHasAttribute($authUser, 'email')) {
280+
$email = $authUser->getAttribute('email');
281+
} elseif ($this->modelHasAttribute($authUser, 'mail')) {
282+
$email = $authUser->getAttribute('mail');
283+
}
284+
285+
$username = $this->modelHasAttribute($authUser, 'username')
286+
? (string)$authUser->getAttribute('username')
287+
: null;
278288

279289
$userData = [
280290
'id' => $authUser instanceof Authenticatable
281291
? $authUser->getAuthIdentifier()
282292
: $authUser->getKey(),
283-
'email' => $authUser->getAttribute('email') ?? $authUser->getAttribute('mail'),
284-
'username' => $username === null ? $username : (string)$username,
293+
'email' => $email,
294+
'username' => $username,
285295
];
286296
}
287297

@@ -305,6 +315,15 @@ private function configureUserScopeFromModel($authUser): void
305315
});
306316
}
307317

318+
private function modelHasAttribute(Model $model, string $key): bool
319+
{
320+
// Taken from: https://github.com/laravel/framework/blob/v11.41.3/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php#L445
321+
// Laravel 11 introduced the `hasAttribute` method we are (almost) mirroring here since it's not available in earlier Laravel versions we support
322+
return array_key_exists($key, $model->getAttributes()) ||
323+
$model->hasGetMutator($key) ||
324+
(method_exists($model, 'hasAttributeMutator') && $model->hasAttributeMutator($key));
325+
}
326+
308327
protected function octaneRequestReceivedHandler(Octane\RequestReceived $event): void
309328
{
310329
$this->prepareScopeForOctane();

test/Sentry/EventHandler/AuthEventsTest.php

+15-11
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ class AuthEventsTest extends TestCase
1515

1616
public function testAuthenticatedEventFillsUserOnScope(): void
1717
{
18-
$user = new AuthEventsTestUserModel();
18+
$user = new AuthEventsTestUserModel;
1919

20-
$user->id = 123;
21-
$user->username = 'username';
22-
$user->email = '[email protected]';
20+
$user->forceFill([
21+
'id' => 123,
22+
'username' => 'username',
23+
'email' => '[email protected]',
24+
]);
2325

2426
$scope = $this->getCurrentSentryScope();
2527

@@ -29,17 +31,19 @@ public function testAuthenticatedEventFillsUserOnScope(): void
2931

3032
$this->assertNotNull($scope->getUser());
3133

32-
$this->assertEquals($scope->getUser()->getId(), 123);
33-
$this->assertEquals($scope->getUser()->getUsername(), 'username');
34-
$this->assertEquals($scope->getUser()->getEmail(), '[email protected]');
34+
$this->assertEquals(123, $scope->getUser()->getId());
35+
$this->assertEquals('username', $scope->getUser()->getUsername());
36+
$this->assertEquals('[email protected]', $scope->getUser()->getEmail());
3537
}
3638

3739
public function testAuthenticatedEventFillsUserOnScopeWhenUsernameIsNotAString(): void
3840
{
3941
$user = new AuthEventsTestUserModel();
4042

41-
$user->id = 123;
42-
$user->username = 456;
43+
$user->forceFill([
44+
'id' => 123,
45+
'username' => 456,
46+
]);
4347

4448
$scope = $this->getCurrentSentryScope();
4549

@@ -49,8 +53,8 @@ public function testAuthenticatedEventFillsUserOnScopeWhenUsernameIsNotAString()
4953

5054
$this->assertNotNull($scope->getUser());
5155

52-
$this->assertEquals($scope->getUser()->getId(), 123);
53-
$this->assertEquals($scope->getUser()->getUsername(), '456');
56+
$this->assertEquals(123, $scope->getUser()->getId());
57+
$this->assertEquals('456', $scope->getUser()->getUsername());
5458
}
5559

5660
public function testAuthenticatedEventDoesNotFillUserOnScopeWhenPIIShouldNotBeSent(): void

0 commit comments

Comments
 (0)