diff --git a/CHANGELOG.md b/CHANGELOG.md index f8d9e92..093a7ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [Unreleased] - XXXX-xx-xx +### Added + +- []() - feat: provision group membership based on userinfo ## [2.3.0] - 2024-07-10 diff --git a/README.md b/README.md index 05c234e..ea8871e 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,10 @@ $CONFIG = [ 'display-name-claim' => 'given_name', // defines the claim which holds the picture of the user - must be a URL 'picture-claim' => 'picture', + // defines the claim which holds the list of user's group IDs - must be a list of strings + // unknown groups are ignored + // if not set, group membership is not changed + 'groups-claim' => 'groups', // defines a list of groups to which the newly created user will be added automatically 'groups' => ['admin', 'guests', 'employees'], ], diff --git a/lib/Client.php b/lib/Client.php index d8ce4ce..0eb9e20 100644 --- a/lib/Client.php +++ b/lib/Client.php @@ -257,6 +257,11 @@ public function getPictureClaim(): ?string { return $this->getAutoProvisionConfig()['picture-claim'] ?? null; } + public function getGroupsClaim(): ?string + { + return $this->getAutoProvisionConfig()['groups-claim'] ?? null; + } + public function getUserEmail($userInfo): ?string { $email = $this->mode() === 'email' ? $userInfo->{$this->getIdentityClaim()} : null; $emailClaim = $this->getEmailClaim(); @@ -282,6 +287,14 @@ public function getUserPicture($userInfo): ?string { return null; } + public function getUserGroupIds($userInfo): ?string { + $groupsClaim = $this->getGroupsClaim(); + if ($groupsClaim) { + return $userInfo->$groupsClaim; + } + return null; + } + /** * Perform a RFC8693 Token Exchange * https://datatracker.ietf.org/doc/html/rfc8693 diff --git a/lib/Service/AutoProvisioningService.php b/lib/Service/AutoProvisioningService.php index d2e5c96..f246ea3 100644 --- a/lib/Service/AutoProvisioningService.php +++ b/lib/Service/AutoProvisioningService.php @@ -28,6 +28,7 @@ use OC\User\LoginException; use OCP\Http\Client\IClientService; use OCP\IAvatarManager; +use OCP\IGroup; use OCP\IGroupManager; use OCP\ILogger; use OCP\IUser; @@ -180,6 +181,35 @@ public function updateAccountInfo(IUser $user, $userInfo, bool $force = false): $user->setDisplayName($currentDN); } } + + $currentGroupIds = $this->client->getUserGroupIds($userInfo); + if ($currentGroupIds) { + $memberOfGroups = $this->groupManager->getUserGroups($user); + $memberOfGroupIds = array_map( + function (IGroup $group) { + return $group->getGID(); + }, + $memberOfGroups, + ); + + foreach ($memberOfGroups as $group) { + if (array_search($group->getGID(), $currentGroupIds) === false) { + $this->logger->debug('AutoProvisioningService: removing from group ' . $group->getGID()); + $group->removeUser($user); + } + } + + $addToGroupIds = array_diff($currentGroupIds, $memberOfGroupIds); + foreach ($addToGroupIds as $groupId) { + $group = $this->groupManager->get($groupId); + if ($group) { + $group->addUser($user); + $this->logger->debug('AutoProvisioningService: adding to group ' . $group->getGID()); + } else { + $this->logger->debug('AutoProvisioningService: not adding to unknown group ' . $group->getGID()); + } + } + } } public function autoProvisioningEnabled(): bool {