diff --git a/lib/Authentication/AuthTokens/OIDCAuthToken.php b/lib/Authentication/AuthTokens/OIDCAuthToken.php
index a7f84ed24..80555e2ba 100644
--- a/lib/Authentication/AuthTokens/OIDCAuthToken.php
+++ b/lib/Authentication/AuthTokens/OIDCAuthToken.php
@@ -9,6 +9,11 @@ abstract class OIDCAuthToken implements IAuthentication
private $principal;
protected $acceptedIssuers;
protected $authRealm;
+ protected $groupHeader;
+ protected $groupSplitChar;
+ protected $bannedGroups;
+ protected $requiredGroups;
+ protected $helpString;
/**
* {@see IAuthentication::eraseCredentials()}
@@ -99,7 +104,7 @@ public static function isStateless()
}
/**
- * Set principal/User details from the session.
+ * Set principal/User details from the session and check group membership.
*/
protected function setTokenFromSession()
{
@@ -108,6 +113,82 @@ protected function setTokenFromSession()
$this->userDetails = array(
'AuthenticationRealm' => array($this->authRealm)
);
+
+ // Check group membership is acceptable.
+ $this->checkBannedGroups();
+ $this->checkRequiredGroups();
+ }
+ }
+
+ /**
+ * Check the token lists all the required groups.
+ */
+ protected function checkRequiredGroups()
+ {
+ $groupArray = explode(
+ $this->groupSplitChar,
+ $_SERVER[$this->groupHeader]
+ );
+
+ // Build up a list of missing groups.
+ $missingGoodGroups = [];
+ foreach ($this->requiredGroups as $group) {
+ if (!in_array($group, $groupArray)) {
+ $missingGoodGroups[] = $group;
+ }
+ }
+
+ // If the list of missing groups is not empty, reject the user.
+ if (!empty($missingGoodGroups)) {
+ $this->rejectUser(
+ 'You are missing the following group(s):',
+ $missingGoodGroups
+ );
+ }
+ }
+
+ /**
+ * Check the token lists non of the banned groups.
+ */
+ protected function checkBannedGroups()
+ {
+ $groupArray = explode($this->groupSplitChar, $_SERVER[$this->groupHeader]);
+
+ $presentBadGroups = [];
+ foreach ($this->bannedGroups as $group) {
+ if (in_array($group, $groupArray)) {
+ $presentBadGroups[] = $group;
+ }
+ }
+
+ // If the list of present bad groups is not empty, reject the user.
+ if (!empty($presentBadGroups)) {
+ $this->rejectUser(
+ 'We do not grant access to GOCDB to members of the following group(s):',
+ $presentBadGroups
+ );
}
}
+
+ /**
+ * Craft a BadCredentialsException exception.
+ *
+ * Uses the given error message to provide the end user more context.
+ *
+ * @param string $errorContext Context for the error.
+ * @param string[] $groupArray An array of group memberships
+ */
+ protected function rejectUser($errorContext, $groupArray)
+ {
+ // For readability, when listing groups to the user,
+ // start each one on a new line with a '-' character.
+ $prependString = '
- ';
+ $groupString = implode($prependString, $groupArray);
+ throw new BadCredentialsException(
+ null,
+ 'You do not belong to the correct group(s) ' .
+ 'to gain access to this site.
' . $errorContext .
+ $prependString . $groupString . '
' . $this->helpString
+ );
+ }
}