Passed
Pull Request — master (#7215)
by Angel Fernando Quiroz
19:05 queued 07:41
created

UserCollectionController::listUsers()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 42
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 27
c 1
b 0
f 0
nc 8
nop 1
dl 0
loc 42
rs 9.1768
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\Controller\Scim;
8
9
use Chamilo\CoreBundle\Entity\User;
10
use Chamilo\CoreBundle\Helpers\AccessUrlHelper;
11
use Chamilo\CoreBundle\Repository\Node\UserRepository;
12
use Chamilo\CoreBundle\Serializer\Normalizer\Scim\UserNormalizer;
13
use Doctrine\ORM\EntityManagerInterface;
14
use Doctrine\ORM\NonUniqueResultException;
15
use Doctrine\ORM\NoResultException;
16
use Symfony\Component\HttpFoundation\JsonResponse;
17
use Symfony\Component\HttpFoundation\Request;
18
use Symfony\Component\HttpFoundation\Response;
19
use Symfony\Component\Routing\Attribute\Route;
20
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
21
use Symfony\Component\Serializer\SerializerInterface;
22
23
#[Route('/scim/v2/Users', methods: ['GET', 'POST'])]
24
class UserCollectionController extends AbstractScimController
25
{
26
    public function __construct(
27
        private readonly UserRepository $userRepository,
28
        private readonly SerializerInterface $serializer,
29
        private readonly AccessUrlHelper $accessUrlHelper,
30
        private readonly EntityManagerInterface $entityManager,
31
    ) {}
32
33
    public function __invoke(Request $request): JsonResponse
34
    {
35
        return $request->isMethod('POST')
36
            ? $this->createUser($request)
37
            : $this->listUsers($request);
38
    }
39
40
    private function listUsers(Request $request): JsonResponse
41
    {
42
        $startIndex = max(1, $request->query->getInt('startIndex', 1));
43
        $count = min(100, $request->query->getInt('count', 30));
44
        $filter = $request->query->get('filter');
45
46
        $qb = $this->userRepository->createQueryBuilder('u');
47
48
        if ($filter && preg_match('/userName\s+eq\s+"([^"]+)"/i', $filter, $matches)) {
49
            $qb
50
                ->andWhere('u.username = :username')
51
                ->setParameter('username', $matches[1])
52
            ;
53
        }
54
55
        try {
56
            $total = (clone $qb)->select('COUNT(u.id)')->getQuery()->getSingleScalarResult();
57
        } catch (NoResultException|NonUniqueResultException) {
58
            $total = 0;
59
        }
60
61
        $users = $qb
62
            ->setFirstResult($startIndex - 1)
63
            ->setMaxResults($count)
64
            ->getQuery()
65
            ->getResult();
66
67
        $resources = [];
68
69
        foreach ($users as $user) {
70
            $resources[] = $this->serializer->normalize($user, UserNormalizer::FORMAT);
71
        }
72
73
        $response = [
74
            'schemas' => ['urn:ietf:params:scim:api:messages:2.0:ListResponse'],
75
            'totalResults' => (int) $total,
76
            'itemsPerPage' => count($resources),
77
            'startIndex' => $startIndex,
78
            'Resources' => $resources,
79
        ];
80
81
        return new JsonResponse($response, Response::HTTP_OK, ['Content-Type' => parent::SCIM_CONTENT_TYPE]);
82
    }
83
84
    private function createUser(Request $request): JsonResponse
85
    {
86
        $data = $this->getAndValidateJson($request);
87
88
        $user = new User();
89
90
        $this->serializer->denormalize($data, User::class, 'json', ['object_to_populate' => $user]);
91
92
        $this->userRepository->updateUser($user);
93
94
        $this->accessUrlHelper->getCurrent()?->addUser($user);
95
96
        $this->entityManager->flush();
97
98
        $normalized = $this->serializer->normalize($user, 'json');
99
100
        $headers = [];
101
        $headers['Content-Type'] = parent::SCIM_CONTENT_TYPE;
102
        $headers['Location'] = $this->generateUrl(
103
            'scim_user_item',
104
            ['id' => $user->getResourceNode()->getUuid()],
105
            UrlGeneratorInterface::ABSOLUTE_URL
106
        );
107
108
        return new JsonResponse($normalized, Response::HTTP_CREATED, $headers);
109
    }
110
}
111