Skip to content

Commit fad8c41

Browse files
authored
Release v1.11.1
2 parents 3507835 + 9f43ad1 commit fad8c41

File tree

22 files changed

+942
-31
lines changed

22 files changed

+942
-31
lines changed

BugsnagBundle.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ class BugsnagBundle extends Bundle
1111
*
1212
* @return string
1313
*/
14-
const VERSION = '1.11.0';
14+
const VERSION = '1.11.1';
1515
}

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
Changelog
22
=========
33

4+
## 1.11.1 (2022-01-19)
5+
6+
### Bug Fixes
7+
8+
* Call `getUserIdentifier` instead of `getUsername` on Symfony 6
9+
[#145](https://github.com/bugsnag/bugsnag-symfony/pull/145)
10+
411
## 1.11.0 (2021-12-13)
512

613
### Enhancements

DependencyInjection/ClientFactory.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,21 @@ protected function setupUserDetection(Client $client, TokenStorageInterface $tok
389389
$user = $token->getUser();
390390

391391
if ($user instanceof UserInterface) {
392-
return ['id' => $user->getUsername()];
392+
// Symfony 5.3 introduced 'getUserIdentifier' to replace 'getUsername'
393+
// Symfony 6.0 removed 'getUsername'
394+
if (method_exists(UserInterface::class, 'getUserIdentifier')) {
395+
return ['id' => $user->getUserIdentifier()];
396+
}
397+
398+
// Symfony 5.4 and below use 'getUsername' ('getUserIdentifier'
399+
// wasn't added to the interface until Symfony 6.0 for BC)
400+
if (method_exists(UserInterface::class, 'getUsername')) {
401+
return ['id' => $user->getUsername()];
402+
}
403+
404+
// if neither method exists then we don't know how to deal with
405+
// this version of Symfony's UserInterface, so can't get an ID
406+
return;
393407
}
394408

395409
return ['id' => (string) $user];

features/fixtures/symfony-2/app/config/security.yml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ security:
44

55
# https://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
66
providers:
7-
in_memory:
8-
memory: ~
7+
app_user_provider:
8+
id: app.user_provider
99

1010
firewalls:
1111
# disables authentication for assets and the profiler, adapt it according to your needs
@@ -15,10 +15,8 @@ security:
1515

1616
main:
1717
anonymous: ~
18-
# activate different ways to authenticate
18+
provider: app_user_provider
1919

20-
# https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
21-
#http_basic: ~
22-
23-
# https://symfony.com/doc/current/security/form_login_setup.html
24-
#form_login: ~
20+
guard:
21+
authenticators:
22+
- app.query_string_authenticator

features/fixtures/symfony-2/app/config/services.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,9 @@ services:
1414
arguments: ['@bugsnag']
1515
tags:
1616
- { name: twig.extension }
17+
18+
app.query_string_authenticator:
19+
class: AppBundle\Security\QueryStringAuthenticator
20+
21+
app.user_provider:
22+
class: AppBundle\Security\UserProvider
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
namespace AppBundle\Security;
4+
5+
use Symfony\Component\HttpFoundation\JsonResponse;
6+
use Symfony\Component\HttpFoundation\Request;
7+
use Symfony\Component\HttpFoundation\Response;
8+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
9+
use Symfony\Component\Security\Core\Exception\AuthenticationException;
10+
use Symfony\Component\Security\Core\User\UserInterface;
11+
use Symfony\Component\Security\Core\User\UserProviderInterface;
12+
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
13+
14+
class QueryStringAuthenticator extends AbstractGuardAuthenticator
15+
{
16+
/**
17+
* Called on every request to decide if this authenticator should be
18+
* used for the request. Returning `false` will cause this authenticator
19+
* to be skipped.
20+
*/
21+
public function supports(Request $request): bool
22+
{
23+
return $request->query->has('name');
24+
}
25+
26+
/**
27+
* Called on every request. Return whatever credentials you want to
28+
* be passed to getUser() as $credentials.
29+
*/
30+
public function getCredentials(Request $request)
31+
{
32+
return $request->query->get('name');
33+
}
34+
35+
public function getUser($credentials, UserProviderInterface $userProvider): ?UserInterface
36+
{
37+
if (null === $credentials) {
38+
return null;
39+
}
40+
41+
return $userProvider->loadUserByUsername($credentials);
42+
}
43+
44+
public function checkCredentials($credentials, UserInterface $user): bool
45+
{
46+
return true;
47+
}
48+
49+
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey): ?Response
50+
{
51+
// on success, let the request continue
52+
return null;
53+
}
54+
55+
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
56+
{
57+
$data = [
58+
'message' => strtr($exception->getMessageKey(), $exception->getMessageData())
59+
];
60+
61+
return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
62+
}
63+
64+
/**
65+
* Called when authentication is needed, but it's not sent
66+
*/
67+
public function start(Request $request, AuthenticationException $authException = null): Response
68+
{
69+
$data = [
70+
'message' => 'Authentication Required'
71+
];
72+
73+
return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
74+
}
75+
76+
public function supportsRememberMe(): bool
77+
{
78+
return false;
79+
}
80+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
3+
namespace AppBundle\Security;
4+
5+
use Symfony\Component\Security\Core\User\UserInterface;
6+
7+
class User implements UserInterface
8+
{
9+
private $id;
10+
11+
private $roles = [];
12+
13+
public function __construct(string $id)
14+
{
15+
$this->id = $id;
16+
}
17+
18+
/**
19+
* A visual identifier that represents this user.
20+
*
21+
* @see UserInterface
22+
*/
23+
public function getUsername(): string
24+
{
25+
return $this->id;
26+
}
27+
28+
/**
29+
* @see UserInterface
30+
*/
31+
public function getRoles(): array
32+
{
33+
$roles = $this->roles;
34+
35+
// guarantee every user at least has ROLE_USER
36+
$roles[] = 'ROLE_USER';
37+
38+
return array_unique($roles);
39+
}
40+
41+
public function setRoles(array $roles): self
42+
{
43+
$this->roles = $roles;
44+
45+
return $this;
46+
}
47+
48+
/**
49+
* This method can be removed in Symfony 6.0 - is not needed for apps that do not check user passwords.
50+
*
51+
* @see UserInterface
52+
*/
53+
public function getPassword(): ?string
54+
{
55+
return null;
56+
}
57+
58+
/**
59+
* This method can be removed in Symfony 6.0 - is not needed for apps that do not check user passwords.
60+
*
61+
* @see UserInterface
62+
*/
63+
public function getSalt(): ?string
64+
{
65+
return null;
66+
}
67+
68+
/**
69+
* @see UserInterface
70+
*/
71+
public function eraseCredentials()
72+
{
73+
// If you store any temporary, sensitive data on the user, clear it here
74+
}
75+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
namespace AppBundle\Security;
4+
5+
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
6+
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
7+
use Symfony\Component\Security\Core\User\UserInterface;
8+
use Symfony\Component\Security\Core\User\UserProviderInterface;
9+
10+
class UserProvider implements UserProviderInterface
11+
{
12+
/**
13+
* Symfony calls this method if you use features like switch_user
14+
* or remember_me.
15+
*
16+
* If you're not using these features, you do not need to implement
17+
* this method.
18+
*
19+
* @throws UsernameNotFoundException if the user is not found
20+
*/
21+
public function loadUserByUsername($username): UserInterface
22+
{
23+
switch ($username) {
24+
case 'abc':
25+
return new User('abc-123');
26+
27+
case 'xyz':
28+
return new User('xyz-789');
29+
30+
default:
31+
throw new UsernameNotFoundException("No user exists with the name '{$username}'");
32+
}
33+
}
34+
35+
/**
36+
* Refreshes the user after being reloaded from the session.
37+
*
38+
* When a user is logged in, at the beginning of each request, the
39+
* User object is loaded from the session and then this method is
40+
* called. Your job is to make sure the user's data is still fresh by,
41+
* for example, re-querying for fresh User data.
42+
*
43+
* If your firewall is "stateless: true" (for a pure API), this
44+
* method is not called.
45+
*/
46+
public function refreshUser(UserInterface $user): UserInterface
47+
{
48+
if (!$user instanceof User) {
49+
throw new UnsupportedUserException(sprintf('Invalid user class "%s".', get_class($user)));
50+
}
51+
52+
// Return a User object after making sure its data is "fresh".
53+
// Or throw a UsernameNotFoundException if the user no longer exists.
54+
return $user;
55+
}
56+
57+
/**
58+
* Tells Symfony to use this provider for this User class.
59+
*/
60+
public function supportsClass($class): bool
61+
{
62+
return User::class === $class || is_subclass_of($class, User::class);
63+
}
64+
}

features/fixtures/symfony-4/config/packages/security.yaml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
security:
22
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
33
providers:
4-
users_in_memory: { memory: null }
4+
# used to reload user from session & other features (e.g. switch_user)
5+
app_user_provider:
6+
id: App\Security\UserProvider
57
firewalls:
68
dev:
79
pattern: ^/(_(profiler|wdt)|css|images|js)/
810
security: false
911
main:
1012
anonymous: lazy
11-
provider: users_in_memory
13+
provider: app_user_provider
1214

13-
# activate different ways to authenticate
14-
# https://symfony.com/doc/current/security.html#firewalls-authentication
15-
16-
# https://symfony.com/doc/current/security/impersonating_user.html
17-
# switch_user: true
15+
guard:
16+
authenticators:
17+
- App\Security\QueryStringAuthenticator
1818

1919
# Easy way to control access for large sections of your site
2020
# Note: Only the *first* access control that matches will be used

features/fixtures/symfony-4/src/Controller/.gitignore

Whitespace-only changes.

0 commit comments

Comments
 (0)