Completed
Push — master ( 1d7572...6dd1d1 )
by Tarmo
20s queued 15s
created

AttachUserGroupController   A

Complexity

Total Complexity 3

Size/Duplication

Total Lines 102
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 65
dl 0
loc 102
ccs 15
cts 15
cp 1
rs 10
c 0
b 0
f 0
wmc 3

2 Methods

Rating   Name   Duplication   Size   Complexity  
B __invoke() 0 87 2
A __construct() 0 5 1
1
<?php
2
declare(strict_types = 1);
3
/**
4
 * /src/Controller/v1/User/AttachUserGroupController.php
5
 *
6
 * @author TLe, Tarmo Leppänen <[email protected]>
7
 */
8
9
namespace App\Controller\v1\User;
10
11
use App\Entity\User;
12
use App\Entity\UserGroup;
13
use App\Enum\Role;
14
use App\Resource\UserGroupResource;
15
use App\Resource\UserResource;
16
use Nelmio\ApiDocBundle\Annotation\Model;
17
use OpenApi\Attributes as OA;
18
use OpenApi\Attributes\JsonContent;
19
use OpenApi\Attributes\Property;
20
use Symfony\Component\HttpFoundation\JsonResponse;
21
use Symfony\Component\HttpFoundation\Request;
22
use Symfony\Component\HttpFoundation\Response;
23
use Symfony\Component\HttpKernel\Attribute\AsController;
24
use Symfony\Component\Routing\Annotation\Route;
25
use Symfony\Component\Routing\Requirement\Requirement;
26
use Symfony\Component\Security\Http\Attribute\IsGranted;
27
use Symfony\Component\Serializer\SerializerInterface;
28
use Throwable;
29
30
/**
31
 * Class AttachUserGroupController
32
 *
33
 * @package App\Controller\v1\User
34
 * @author TLe, Tarmo Leppänen <[email protected]>
35
 */
36
#[AsController]
37
class AttachUserGroupController
38
{
39 6
    public function __construct(
40
        private readonly UserResource $userResource,
41
        private readonly UserGroupResource $userGroupResource,
42
        private readonly SerializerInterface $serializer,
43
    ) {
44 6
    }
45
46
    /**
47
     * Endpoint action to attach specified user group to specified user.
48
     *
49
     * @throws Throwable
50
     */
51 3
    #[Route(
52
        path: '/v1/user/{user}/group/{userGroup}',
53
        requirements: [
54
            'user' => Requirement::UUID_V1,
55
            'userGroup' => Requirement::UUID_V1,
56
        ],
57
        methods: [Request::METHOD_POST],
58
    )]
59
    #[IsGranted(Role::ROOT->value)]
60
    #[OA\Tag(name: 'User Management')]
61
    #[OA\SecurityScheme(
62
        securityScheme: 'bearerAuth',
63
        type: 'http',
64
        description: 'Authorization header',
65
        name: 'bearerAuth',
66
        in: 'header',
67
        bearerFormat: 'JWT',
68
        scheme: 'bearer',
69
    )]
70
    #[OA\Parameter(name: 'user', description: 'User GUID', in: 'path', required: true)]
71
    #[OA\Parameter(name: 'userGroup', description: 'User Group GUID', in: 'path', required: true)]
72
    #[OA\Response(
73
        response: 200,
74
        description: 'User groups (user already belongs to this group)',
75
        content: new JsonContent(
76
            type: 'array',
77
            items: new OA\Items(
78
                ref: new Model(type: UserGroup::class, groups: ['UserGroup', 'UserGroup.role']),
79
            ),
80
        ),
81
    )]
82
    #[OA\Response(
83
        response: 201,
84
        description: 'User groups (user added to this group)',
85
        content: new JsonContent(
86
            type: 'array',
87
            items: new OA\Items(
88
                ref: new Model(type: UserGroup::class, groups: ['UserGroup', 'UserGroup.role']),
89
            ),
90
        ),
91
    )]
92
    #[OA\Response(
93
        response: 401,
94
        description: 'Invalid token',
95
        content: new JsonContent(
96
            properties: [
97
                new Property(property: 'code', type: 'integer'),
98
                new Property(property: 'message', type: 'string'),
99
            ],
100
            type: 'object',
101
            example: [
102
                'Token not found' => "{code: 401, message: 'JWT Token not found'}",
103
                'Expired token' => "{code: 401, message: 'Expired JWT Token'}",
104
            ],
105
        ),
106
    )]
107
    #[OA\Response(
108
        response: 403,
109
        description: 'Access denied',
110
        content: new JsonContent(
111
            properties: [
112
                new Property(property: 'code', type: 'integer'),
113
                new Property(property: 'message', type: 'string'),
114
            ],
115
            type: 'object',
116
            example: [
117
                'Access denied' => "{code: 403, message: 'Access denied'}",
118
            ],
119
        ),
120
    )]
121
    public function __invoke(User $user, UserGroup $userGroup): JsonResponse
122
    {
123 3
        $status = $user->getUserGroups()->contains($userGroup) ? Response::HTTP_OK : Response::HTTP_CREATED;
124
125 3
        $this->userResource->save($user->addUserGroup($userGroup), false);
126 3
        $this->userGroupResource->save($userGroup, true, true);
127
128 3
        $groups = [
129 3
            'groups' => [
130 3
                UserGroup::SET_USER_GROUP_BASIC,
131 3
            ],
132 3
        ];
133
134 3
        return new JsonResponse(
135 3
            $this->serializer->serialize($user->getUserGroups()->getValues(), 'json', $groups),
136 3
            $status,
137 3
            json: true
138 3
        );
139
    }
140
}
141