diff --git a/src/Provider/GoogleUser.php b/src/Provider/GoogleUser.php index d004e3c..58f0538 100644 --- a/src/Provider/GoogleUser.php +++ b/src/Provider/GoogleUser.php @@ -72,6 +72,36 @@ public function getEmail(): ?string return $this->getResponseValue('email'); } + /** + * Get email_verified attribute. + * + * @return bool|null + */ + public function getEmailVerified(): ?bool + { + return $this->getResponseValue('email_verified'); + } + + /** + * Returns whether the email is trustable enough to be used for authentication purpose. + * + * @see https://developers.google.com/identity/gsi/web/guides/verify-google-id-token + */ + public function isEmailTrustworthy(): bool + { + $email = $this->getEmail(); + if (! $email) { + return false; + } + if ('@gmail.com' === substr($email, -10)) { + return true; + } + if ($this->getHostedDomain() && $this->getEmailVerified()) { + return true; + } + return false; + } + /** * Get hosted domain. * diff --git a/test/src/Provider/GoogleUserTest.php b/test/src/Provider/GoogleUserTest.php index 756d074..45ee3e0 100644 --- a/test/src/Provider/GoogleUserTest.php +++ b/test/src/Provider/GoogleUserTest.php @@ -13,6 +13,7 @@ public function testUserDefaults(): void $user = new GoogleUser([ 'sub' => '12345', 'email' => 'mock.name@example.com', + 'email_verified' => true, 'name' => 'mock name', 'given_name' => 'mock', 'family_name' => 'name', @@ -29,6 +30,8 @@ public function testUserDefaults(): void self::assertEquals('mock.name@example.com', $user->getEmail()); self::assertEquals('example.com', $user->getHostedDomain()); self::assertEquals('mock_image_url', $user->getAvatar()); + self::assertTrue($user->getEmailVerified()); + self::assertTrue($user->isEmailTrustworthy()); } public function testUserPartialData(): void @@ -44,6 +47,8 @@ public function testUserPartialData(): void self::assertEquals(null, $user->getHostedDomain()); self::assertEquals(null, $user->getAvatar()); self::assertEquals(null, $user->getLocale()); + self::assertNull($user->getEmailVerified()); + self::assertFalse($user->isEmailTrustworthy()); } public function testUserMinimalData(): void @@ -59,5 +64,72 @@ public function testUserMinimalData(): void self::assertEquals(null, $user->getLocale()); self::assertEquals(null, $user->getFirstName()); self::assertEquals(null, $user->getLastName()); + self::assertNull($user->getEmailVerified()); + self::assertFalse($user->isEmailTrustworthy()); + } + + public function testGmailTrustworthy(): void + { + $user = new GoogleUser([ + 'sub' => '12345', + 'name' => 'mock name', + 'email' => 'mock.email@gmail.com', + ]); + + self::assertNull($user->getEmailVerified()); + self::assertTrue($user->isEmailTrustworthy()); + } + + public function testAlmostGmailNotTrustworthy(): void + { + $user = new GoogleUser([ + 'sub' => '12345', + 'name' => 'mock name', + 'email' => 'mock.email@agmail.com', + ]); + + self::assertNull($user->getEmailVerified()); + self::assertFalse($user->isEmailTrustworthy()); + } + + public function testNonGmailWithHostedDomainTrustworthy(): void + { + $user = new GoogleUser([ + 'sub' => '12345', + 'name' => 'mock name', + 'email' => 'mock.email@example.com', + 'email_verified' => true, + 'hd' => 'example.com', + ]); + + self::assertTrue($user->getEmailVerified()); + self::assertTrue($user->isEmailTrustworthy()); + } + + public function testNonGmailNonVerifiedWithHostedDomainNotTrustworthy(): void + { + $user = new GoogleUser([ + 'sub' => '12345', + 'name' => 'mock name', + 'email' => 'mock.email@example.com', + 'email_verified' => false, + 'hd' => 'example.com', + ]); + + self::assertFalse($user->getEmailVerified()); + self::assertFalse($user->isEmailTrustworthy()); + } + + public function testNonGmailVerifiedWithoutHostedDomainNotTrustworthy(): void + { + $user = new GoogleUser([ + 'sub' => '12345', + 'name' => 'mock name', + 'email' => 'mock.email@example.com', + 'email_verified' => true, + ]); + + self::assertTrue($user->getEmailVerified()); + self::assertFalse($user->isEmailTrustworthy()); } }