2023-03-03 11:21:27 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace OCA\SCIMServiceProvider\Service;
|
|
|
|
|
|
|
|
use Exception;
|
2023-03-04 14:49:39 +00:00
|
|
|
use OCA\SCIMServiceProvider\AppInfo\Application;
|
2024-02-06 10:32:35 +00:00
|
|
|
use OCP\IGroup;
|
2023-03-03 11:21:27 +00:00
|
|
|
use OCP\IGroupManager;
|
2024-02-06 10:32:35 +00:00
|
|
|
use OCP\IUserManager;
|
|
|
|
use Opf\Models\SCIM\Standard\Groups\CoreGroup;
|
|
|
|
use Opf\Models\SCIM\Standard\Meta;
|
|
|
|
use Opf\Models\SCIM\Standard\MultiValuedAttribute;
|
2023-03-03 11:21:27 +00:00
|
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
|
2024-02-06 10:32:35 +00:00
|
|
|
class GroupService {
|
|
|
|
|
|
|
|
private LoggerInterface $logger;
|
|
|
|
private IGroupManager $groupManager;
|
|
|
|
private IUserManager $userManager;
|
|
|
|
|
|
|
|
|
|
|
|
public function __construct(LoggerInterface $logger, IGroupManager $groupManager, IUserManager $userManager) {
|
|
|
|
$this->logger = $logger;
|
|
|
|
$this->groupManager = $groupManager;
|
|
|
|
$this->userManager = $userManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private function toSCIM(IGroup $ncGroup): CoreGroup {
|
|
|
|
$scimGroup = new CoreGroup();
|
|
|
|
$scimGroup->setId($ncGroup->getGID());
|
|
|
|
$scimGroup->setDisplayName($ncGroup->getDisplayName());
|
|
|
|
|
|
|
|
$meta = new Meta();
|
|
|
|
$meta->setResourceType("Group");
|
|
|
|
$scimGroup->setMeta($meta);
|
|
|
|
|
|
|
|
return $scimGroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private function getSCIMMembers(IGroup $ncGroup): array {
|
|
|
|
$members = [];
|
|
|
|
foreach ($ncGroup->getUsers() as $ncGroupMember) {
|
|
|
|
$this->logger->info($ncGroupMember->getUID());
|
|
|
|
$member = new MultiValuedAttribute();
|
|
|
|
$member->setType("User");
|
|
|
|
$member->setRef("Users/" . $ncGroupMember->getUID());
|
|
|
|
$member->setValue($ncGroupMember->getUID());
|
|
|
|
$member->setDisplay($ncGroupMember->getDisplayName());
|
|
|
|
|
|
|
|
$members[] = $member;
|
|
|
|
}
|
|
|
|
return $members;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function updateGroup(IGroup $ncGroup, CoreGroup $scimGroup) {
|
|
|
|
$displayName = $scimGroup->getDisplayName();
|
|
|
|
if (isset($displayName)) {
|
|
|
|
$ncGroup->setDisplayName($displayName);
|
|
|
|
}
|
|
|
|
|
|
|
|
$scimMembers = $scimGroup->getMembers();
|
|
|
|
if (isset($scimMembers)) {
|
|
|
|
foreach ($ncGroup->getUsers() as $ncUser) {
|
|
|
|
$found = false;
|
|
|
|
foreach ($scimMembers as $scimMember) {
|
|
|
|
if ($ncUser->getUID() === $scimMember->getValue()) {
|
|
|
|
$found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!$found) {
|
|
|
|
$this->logger->info("remove " . $ncUser->getUID() . " from " . $ncGroup->getGID());
|
|
|
|
$ncGroup->removeUser($ncUser);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
foreach ($scimMembers as $scimMember) {
|
|
|
|
$this->logger->info($scimMember->getValue());
|
|
|
|
$this->logger->info(json_encode($scimMember->jsonSerialize()));
|
|
|
|
$user = $this->userManager->get($scimMember->getValue());
|
|
|
|
if (!isset($user)) {
|
|
|
|
throw new Exception("User " . $scimMember->getValue() . " not found", 404);
|
|
|
|
}
|
|
|
|
if (!$ncGroup->inGroup($user)) {
|
|
|
|
$this->logger->info("add " . $user->getUID() . " from " . $ncGroup->getGID());
|
|
|
|
$ncGroup->addUser($user);
|
|
|
|
$this->logger->info(json_encode($ncGroup->getUsers()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function countAll(): int {
|
|
|
|
$ncGroups = $this->groupManager->search("");
|
|
|
|
return sizeof($ncGroups);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @param string $filter
|
|
|
|
* @return OCP\IGroup\IGroup[]
|
|
|
|
*/
|
|
|
|
public function getAll(int $startIndex, int $count = null): array {
|
|
|
|
$this->logger->info("Reading all groups");
|
|
|
|
|
|
|
|
if ($count === 0) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
$ncGroups = $this->groupManager->search("", $count, $startIndex - 1);
|
|
|
|
|
|
|
|
$scimGroups = [];
|
|
|
|
foreach ($ncGroups as $ncGroup) {
|
|
|
|
$scimGroup = $this->toSCIM($ncGroup);
|
|
|
|
$members = $this->getSCIMMembers($ncGroup);
|
|
|
|
$scimGroup->setMembers($members);
|
|
|
|
$scimGroups[] = $scimGroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $scimGroups;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function get(string $id): CoreGroup {
|
|
|
|
if (!$this->groupManager->groupExists($id)) {
|
|
|
|
throw new Exception("Not found", 404);
|
|
|
|
}
|
|
|
|
|
|
|
|
$ncGroup = $this->groupManager->get($id);
|
|
|
|
$scimGroup = $this->toSCIM($ncGroup);
|
|
|
|
|
|
|
|
|
|
|
|
$members = $this->getSCIMMembers($ncGroup);
|
|
|
|
$scimGroup->setMembers($members);
|
|
|
|
|
|
|
|
return $scimGroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function create(CoreGroup $scimGroup): CoreGroup {
|
|
|
|
// Validate name
|
|
|
|
if (empty($scimGroup->getDisplayName())) {
|
|
|
|
$this->logger->error('Group name not supplied', ['app' => 'provisioning_api']);
|
|
|
|
throw new Exception('Invalid group name', 400);
|
|
|
|
}
|
|
|
|
// Check if it exists
|
|
|
|
if ($this->groupManager->groupExists($scimGroup->getDisplayName())) {
|
|
|
|
$this->logger->error("Group to be created already exists");
|
|
|
|
throw new Exception('Group exists', 409);
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
$this->logger->info("Creating group with displayName: " . $scimGroup->getDisplayName());
|
|
|
|
|
|
|
|
$ncGroup = $this->groupManager->createGroup($scimGroup->getDisplayName());
|
|
|
|
$this->updateGroup($ncGroup, $scimGroup);
|
|
|
|
} catch (Exception $e) {
|
|
|
|
$this->logger->warning('Failed createGroup attempt with SCIMException exception.', ['app' => Application::APP_ID]);
|
|
|
|
throw $e;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->get($ncGroup->getGID());
|
|
|
|
}
|
|
|
|
|
|
|
|
public function update(string $id, CoreGroup $scimGroup): CoreGroup {
|
|
|
|
$this->logger->info("Updating group with ID: " . $id);
|
|
|
|
|
|
|
|
if (!$this->groupManager->groupExists($id)) {
|
|
|
|
throw new Exception('Group not found', 404);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->logger->info($scimGroup->toSCIM());
|
|
|
|
// $this->atomic(function () use ($id, $scimGroup) {
|
|
|
|
$ncGroup = $this->groupManager->get($id);
|
|
|
|
$this->updateGroup($ncGroup, $scimGroup);
|
|
|
|
// }, $this->db);
|
|
|
|
|
|
|
|
|
|
|
|
$this->logger->info(json_encode($ncGroup->getUsers()));
|
|
|
|
|
|
|
|
return $this->get($id);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function destroy(string $id): void {
|
|
|
|
$this->logger->info("Deleting group with ID: " . $id);
|
|
|
|
|
|
|
|
if ($id === 'admin') {
|
|
|
|
// Cannot delete admin group
|
|
|
|
$this->logger->error("Deleting admin group is not allowed");
|
|
|
|
throw new Exception('Can\'t delete admin group', 403);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!$this->groupManager->groupExists($id)) {
|
|
|
|
throw new Exception('Group not found', 404);
|
|
|
|
}
|
|
|
|
$ncGroup = $this->groupManager->get($id);
|
|
|
|
$ncGroup->delete();
|
|
|
|
}
|
2023-03-03 11:21:27 +00:00
|
|
|
}
|