diff --git a/src/Integrations/Bitbucket/BitbucketIntegration.php b/src/Integrations/Bitbucket/BitbucketIntegration.php index 200debf5..1bf23bf4 100644 --- a/src/Integrations/Bitbucket/BitbucketIntegration.php +++ b/src/Integrations/Bitbucket/BitbucketIntegration.php @@ -378,6 +378,7 @@ public function fetchUser(array|Request $request, array $options = [], array &$a $response['user_name'] = $response['username'] ?? null; $response['user_identifier'] = $response['username'] ?? null; $response['external_id'] = isset($response['uuid']) ? "{$this->name}:{$response['uuid']}" : null; + $response['_type'] = self::LOGIN_USERNAME; return $response; } diff --git a/src/Integrations/Github/GitHubIntegration.php b/src/Integrations/Github/GitHubIntegration.php index 9b90abb7..57bfe27d 100644 --- a/src/Integrations/Github/GitHubIntegration.php +++ b/src/Integrations/Github/GitHubIntegration.php @@ -456,6 +456,7 @@ public function fetchUser(Request|array $requestOrToken, array $options = [], ar $response['user_name'] = $response['login'] ?? null; $response['user_identifier'] = $response['email'] ?? $response['login']; $response['external_id'] = isset($response['id']) ? $this->getConfig()->getName() . ':' . $response['id'] : null; + $response['_type'] = isset($response['email']) ? self::LOGIN_EMAIL : self::LOGIN_USERNAME; return $response; } diff --git a/src/Integrations/Gitlab/GitLabIntegration.php b/src/Integrations/Gitlab/GitLabIntegration.php index 572166dc..c4e8d41f 100644 --- a/src/Integrations/Gitlab/GitLabIntegration.php +++ b/src/Integrations/Gitlab/GitLabIntegration.php @@ -157,6 +157,7 @@ public function fetchUser(Request|array $request, array $options = [], array &$a $response['user_name'] = $response['username'] ?? null; $response['user_identifier'] = $response['email']; $response['external_id'] = isset($response['id']) ? "{$this->name}:{$response['id']}" : null; + $response['_type'] = self::LOGIN_EMAIL; return $response; } diff --git a/src/Integrations/Google/GoogleOAuth2Login.php b/src/Integrations/Google/GoogleOAuth2Login.php index 0a2af930..f616a989 100644 --- a/src/Integrations/Google/GoogleOAuth2Login.php +++ b/src/Integrations/Google/GoogleOAuth2Login.php @@ -85,6 +85,7 @@ public function fetchUser(array|Request $request, array $options = [], array &$a $response['user_name'] = explode('@', $response['email'])[0]; $response['user_identifier'] = $response['email']; $response['external_id'] = isset($response['sub']) ? $this->name . ':' . $response['sub'] : null; + $response['_type'] = self::LOGIN_EMAIL; return $response; } diff --git a/src/Integrations/LoginInterface.php b/src/Integrations/LoginInterface.php index 9a1de706..1e326bdc 100644 --- a/src/Integrations/LoginInterface.php +++ b/src/Integrations/LoginInterface.php @@ -11,6 +11,9 @@ interface LoginInterface extends IntegrationInterface { + public const LOGIN_EMAIL = 'email'; + public const LOGIN_USERNAME = 'username'; + /** * @param Request|null $request * @param array $options diff --git a/src/Integrations/Security/OAuth2Authenticator.php b/src/Integrations/Security/OAuth2Authenticator.php index 32e7d127..93784664 100644 --- a/src/Integrations/Security/OAuth2Authenticator.php +++ b/src/Integrations/Security/OAuth2Authenticator.php @@ -70,6 +70,11 @@ public function authenticate(Request $request): Passport throw new CustomUserMessageAuthenticationException('Unable to fetch oauth data'); } + if (empty($data['_type'])) { + $this->logger->error("oauth2 authenticator error, client response must contains _type of user_identifier field.", ['user' => $data]); + throw new CustomUserMessageAuthenticationException('Invalid oauth user data. Client response must contains _type of user identifier'); + } + $badges = []; if (filter_var($request->cookies->get('_remember_me_flag'), FILTER_VALIDATE_BOOL)) { $badges[] = new RememberMeBadge(); diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index b5eb0ad7..98d46c14 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -16,6 +16,7 @@ use Packeton\Entity\Group; use Packeton\Entity\Package; use Packeton\Entity\User; +use Packeton\Integrations\LoginInterface; /** * @author Jordi Boggiano @@ -32,8 +33,10 @@ public function findUsersMissingApiToken() public function findByOAuth2Data(array $data): ?User { $user = null; - if (isset($data['user_identifier'])) { - $user = $this->findOneByUsernameOrEmail($data['user_identifier']); + if ($identifier = ($data['user_identifier'] ?? null)) { + $user = ($data['_type'] ?? null) === LoginInterface::LOGIN_USERNAME ? + $this->findOneBy(['usernameCanonical' => mb_strtolower($identifier)]) + : $this->findOneBy(['emailCanonical' => $identifier]); } if (null === $user && isset($data['external_id'])) {