|
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\Controller\Scim\AbstractScimController; |
|
10
|
|
|
use Chamilo\CoreBundle\Entity\User; |
|
11
|
|
|
use Chamilo\CoreBundle\Exception\ScimException; |
|
12
|
|
|
use Doctrine\ORM\EntityManagerInterface; |
|
13
|
|
|
use Symfony\Component\HttpFoundation\JsonResponse; |
|
14
|
|
|
use Symfony\Component\HttpFoundation\Request; |
|
15
|
|
|
use Symfony\Component\HttpFoundation\Response; |
|
16
|
|
|
use Symfony\Component\Routing\Attribute\Route; |
|
17
|
|
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; |
|
18
|
|
|
use Symfony\Component\Serializer\SerializerInterface; |
|
19
|
|
|
|
|
20
|
|
|
#[Route( |
|
21
|
|
|
'/scim/v2/Users/{id}', |
|
22
|
|
|
name: 'scim_user_item', |
|
23
|
|
|
methods: ['GET', 'PUT', 'PATCH', 'DELETE'] |
|
24
|
|
|
)] |
|
25
|
|
|
class UserItemController extends AbstractScimController |
|
26
|
|
|
{ |
|
27
|
|
|
public function __construct( |
|
28
|
|
|
private readonly EntityManagerInterface $entityManager, |
|
29
|
|
|
private readonly SerializerInterface $serializer, |
|
30
|
|
|
) {} |
|
31
|
|
|
|
|
32
|
|
|
public function __invoke(Request $request): JsonResponse |
|
33
|
|
|
{ |
|
34
|
|
|
/** @var User|null $user */ |
|
35
|
|
|
$user = null; |
|
36
|
|
|
|
|
37
|
|
|
return match ($request->getMethod()) { |
|
38
|
|
|
'GET' => $this->findUser($user), |
|
39
|
|
|
'PUT' => $this->replaceUser($request, $user), |
|
40
|
|
|
'PATCH' => $this->patchUser($request, $user), |
|
41
|
|
|
'DELETE'=> $this->deleteUser($user), |
|
42
|
|
|
default => throw new ScimException( |
|
43
|
|
|
Response::$statusTexts[Response::HTTP_METHOD_NOT_ALLOWED], |
|
44
|
|
|
Response::HTTP_METHOD_NOT_ALLOWED |
|
45
|
|
|
), |
|
46
|
|
|
}; |
|
47
|
|
|
} |
|
48
|
|
|
|
|
49
|
|
|
private function findUser(User $user): JsonResponse |
|
50
|
|
|
{ |
|
51
|
|
|
$data = $this->serializer->normalize($user, 'json'); |
|
52
|
|
|
|
|
53
|
|
|
return new JsonResponse($data, Response::HTTP_OK, ['Content-Type' => parent::SCIM_CONTENT_TYPE]); |
|
54
|
|
|
} |
|
55
|
|
|
|
|
56
|
|
|
private function replaceUser(Request $request, User $user): JsonResponse |
|
57
|
|
|
{ |
|
58
|
|
|
$data = $this->getAndValidateJson($request); |
|
59
|
|
|
|
|
60
|
|
|
$this->serializer->denormalize( |
|
61
|
|
|
$data, |
|
62
|
|
|
User::class, |
|
63
|
|
|
'json', |
|
64
|
|
|
['object_to_populate' => $user] |
|
65
|
|
|
); |
|
66
|
|
|
|
|
67
|
|
|
$this->entityManager->flush(); |
|
68
|
|
|
|
|
69
|
|
|
return $this->findUser($user); |
|
70
|
|
|
} |
|
71
|
|
|
|
|
72
|
|
|
private function patchUser(Request $request, User $user): JsonResponse |
|
73
|
|
|
{ |
|
74
|
|
|
// Para PATCH completo, puedes crear un Denormalizer personalizado o manejar Operations manualmente |
|
75
|
|
|
// Por ahora: usamos denormalización parcial (Symfony lo soporta con object_to_populate) |
|
76
|
|
|
$data = $this->getAndValidateJson($request); |
|
77
|
|
|
|
|
78
|
|
|
if (!isset($data['schemas']) || !in_array('urn:ietf:params:scim:api:messages:2.0:PatchOp', $data['schemas'])) { |
|
79
|
|
|
throw new ScimException('Schema PatchOp is required', Response::HTTP_BAD_REQUEST); |
|
80
|
|
|
} |
|
81
|
|
|
|
|
82
|
|
|
// Aquí iría lógica para Operations (replace, add, remove) → puedes extenderlo después |
|
83
|
|
|
// Por simplicidad, usamos denormalización sobre los campos directos |
|
84
|
|
|
$this->serializer->denormalize( |
|
85
|
|
|
$data, |
|
86
|
|
|
User::class, |
|
87
|
|
|
'json', |
|
88
|
|
|
['object_to_populate' => $user] |
|
89
|
|
|
); |
|
90
|
|
|
|
|
91
|
|
|
$this->entityManager->flush(); |
|
92
|
|
|
|
|
93
|
|
|
return $this->findUser($user); |
|
94
|
|
|
} |
|
95
|
|
|
|
|
96
|
|
|
private function deleteUser(User $user): JsonResponse |
|
97
|
|
|
{ |
|
98
|
|
|
\UserManager::delete_user($user->getId()); |
|
99
|
|
|
|
|
100
|
|
|
return new JsonResponse(null, Response::HTTP_NO_CONTENT); |
|
101
|
|
|
} |
|
102
|
|
|
} |