scimserviceprovider/lib/Service/GroupService.php

202 lines
5.4 KiB
PHP
Raw Permalink Normal View History

2023-03-03 11:21:27 +00:00
<?php
declare(strict_types=1);
namespace OCA\SCIMServiceProvider\Service;
use Exception;
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
}