Skip to content

Instantly share code, notes, and snippets.

@drzraf
Last active September 4, 2021 02:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drzraf/09fe3b732cc6d538ce8fc37db763d542 to your computer and use it in GitHub Desktop.
Save drzraf/09fe3b732cc6d538ce8fc37db763d542 to your computer and use it in GitHub Desktop.
diff --git a/src/Provider/Google.php b/src/Provider/Google.php
index 66c9db6..ba5ccf9 100644
--- a/src/Provider/Google.php
+++ b/src/Provider/Google.php
@@ -20,6 +20,9 @@ class Google extends AbstractProvider
/**
* @var string If set, this will be sent to google as the "hd" parameter.
+ * Extra-feature: Also accept a comma-separated list of domains or domain regular expressions.
+ * In that case, Google connection screen is not bound to a specific hosted domain
+ * because no "hd" parameter is sent to Google, but domain matching is still done by this library.
* @link https://developers.google.com/identity/protocols/OpenIDConnect#authenticationuriparameters
*/
protected $hostedDomain;
@@ -53,7 +56,7 @@ public function getResourceOwnerDetailsUrl(AccessToken $token)
protected function getAuthorizationParameters(array $options)
{
- if (empty($options['hd']) && $this->hostedDomain) {
+ if (empty($options['hd']) && $this->hostedDomain && !$this->isHostedDomainMultiple()) {
$options['hd'] = $this->hostedDomain;
}
@@ -121,31 +124,64 @@ protected function createResourceOwner(array $response, AccessToken $token)
{
$user = new GoogleUser($response);
- $this->assertMatchingDomain($user->getHostedDomain());
+ $this->assertMatchingDomains($user->getHostedDomain());
return $user;
}
+ protected function isDomainExpression($str)
+ {
+ return preg_match('/[\(\|\*]/', $str) && !preg_match('!/!', $str);
+ }
+
+ protected function isHostedDomainMultiple()
+ {
+ return strpos($this->hostedDomain, ',') !== FALSE || $this->isDomainExpression($this->hostedDomain);
+ }
+
/**
* @throws HostedDomainException If the domain does not match the configured domain.
*/
- protected function assertMatchingDomain($hostedDomain)
+ protected function assertMatchingDomains($hostedDomain)
{
if ($this->hostedDomain === null) {
// No hosted domain configured.
return;
}
- if ($this->hostedDomain === '*' && $hostedDomain) {
- // Any hosted domain is allowed.
+ $domains = array_filter(explode(',', $this->hostedDomain));
+ if (empty($domains)) {
+ // No hosted domains configured.
return;
}
- if ($this->hostedDomain === $hostedDomain) {
- // Hosted domain is correct.
- return;
+ foreach ($domains as $whiteListedDomain) {
+ if ($this->assertMatchingDomain($whiteListedDomain, $hostedDomain)) {
+ return;
+ }
}
throw HostedDomainException::notMatchingDomain($this->hostedDomain);
}
+
+ /**
+ * @return bool Whether user-originating domain equals or matches $reference.
+ */
+ protected function assertMatchingDomain($reference, $hostedDomain)
+ {
+ if ($reference === '*' && $hostedDomain) {
+ // Any hosted domain is allowed.
+ return true;
+ }
+
+ if ($reference === $hostedDomain) {
+ // Hosted domain is correct.
+ return true;
+ }
+
+ if ($this->isDomainExpression($reference) && @preg_match('/' . $reference . '/', $hostedDomain)) {
+ // Hosted domain is correct.
+ return true;
+ }
+ }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment