These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | /** |
||
6 | * balloon |
||
7 | * |
||
8 | * @copyright Copryright (c) 2012-2019 gyselroth GmbH (https://gyselroth.com) |
||
9 | * @license GPL-3.0 https://opensource.org/licenses/GPL-3.0 |
||
10 | */ |
||
11 | |||
12 | namespace Balloon\App\Api\v2; |
||
13 | |||
14 | use Balloon\AttributeDecorator\Pager; |
||
15 | use Balloon\Server; |
||
16 | use Balloon\Server\AttributeDecorator; |
||
17 | use Balloon\Server\Group; |
||
18 | use Balloon\Server\User; |
||
19 | use Balloon\Server\User\Exception; |
||
0 ignored issues
–
show
|
|||
20 | use Micro\Http\Response; |
||
21 | use function MongoDB\BSON\fromJSON; |
||
22 | use MongoDB\BSON\ObjectId; |
||
23 | use function MongoDB\BSON\toPHP; |
||
24 | |||
25 | class Groups |
||
26 | { |
||
27 | /** |
||
28 | * User. |
||
29 | * |
||
30 | * @var User |
||
31 | */ |
||
32 | protected $user; |
||
33 | |||
34 | /** |
||
35 | * Server. |
||
36 | * |
||
37 | * @var Server |
||
38 | */ |
||
39 | protected $server; |
||
40 | |||
41 | /** |
||
42 | * Attribute decorator. |
||
43 | * |
||
44 | * @var AttributeDecorator |
||
45 | */ |
||
46 | protected $decorator; |
||
47 | |||
48 | /** |
||
49 | * Initialize. |
||
50 | * |
||
51 | * @param AttributeDecorator |
||
52 | */ |
||
53 | public function __construct(Server $server, AttributeDecorator $decorator) |
||
54 | { |
||
55 | $this->user = $server->getIdentity(); |
||
56 | $this->server = $server; |
||
57 | $this->decorator = $decorator; |
||
58 | } |
||
59 | |||
60 | /** |
||
61 | * @apiDefine _getGroup |
||
62 | * |
||
63 | * @apiParam (GET Parameter) {string[]} id Either a single id (group id) or a name (groupname) must be given (admin privilege required). |
||
64 | * @apiParam (GET Parameter) {string[]} name Either a single id (group id) or a name (groupname) must be given (admin privilege required). |
||
65 | * |
||
66 | * @apiErrorExample {json} Error-Response (No admin privileges): |
||
67 | * HTTP/1.1 403 Forbidden |
||
68 | * { |
||
69 | * "status": 403, |
||
70 | * "data": { |
||
71 | * "error": "Balloon\\Exception\\Forbidden", |
||
72 | * "message": "submitted parameters require to have admin privileges", |
||
73 | * "code": 41 |
||
74 | * } |
||
75 | * } |
||
76 | * |
||
77 | * @apiErrorExample {json} Error-Response (Group not found): |
||
78 | * HTTP/1.1 404 Not Found |
||
79 | * { |
||
80 | * "status": 404, |
||
81 | * "data": { |
||
82 | * "error": "Balloon\\Exception\\NotFound", |
||
83 | * "message": "requested group was not found", |
||
84 | * "code": 53 |
||
85 | * } |
||
86 | * } |
||
87 | * |
||
88 | * @apiErrorExample {json} Error-Response (Invalid argument): |
||
89 | * HTTP/1.1 400 Bad Request |
||
90 | * { |
||
91 | * "status": 400, |
||
92 | * "data": { |
||
93 | * "error": "Balloon\\Exception\\InvalidArgument", |
||
94 | * "message": "provide either id (group id) or name (groupname)", |
||
95 | * "Code": 0 |
||
96 | * } |
||
97 | * } |
||
98 | */ |
||
99 | |||
100 | /** |
||
101 | * @apiDefine _getGroups |
||
102 | * |
||
103 | * @apiParam (GET Parameter) {string[]} id Either a single id (group id) as string or multiple as an array or a single name (groupname) as string or multiple groupnames as array must be given. |
||
104 | * @apiParam (GET Parameter) {string[]} name Either a single id (groupid) as string or multiple as an array or a single name (groupname) as string or multiple groupnames as array must be given. |
||
105 | */ |
||
106 | |||
107 | /** |
||
108 | * Get group instance. |
||
109 | */ |
||
110 | public function _getGroup(string $id, bool $require_admin = false): Group |
||
111 | { |
||
112 | if (true === $require_admin && !$this->user->isAdmin()) { |
||
113 | throw new Exception\NotAdmin('submitted parameters require admin privileges'); |
||
114 | } |
||
115 | |||
116 | return $this->server->getGroupById(new ObjectId($id)); |
||
117 | } |
||
118 | |||
119 | /** |
||
120 | * @api {get} /api/v2/groups/:id/members Get group member |
||
121 | * @apiVersion 2.0.0 |
||
122 | * @apiName getMember |
||
123 | * @apiUse _getGroup |
||
124 | * @apiGroup Group |
||
125 | * @apiPermission none |
||
126 | * @apiDescription Request all member of a group |
||
127 | * |
||
128 | * @apiExample Example usage: |
||
129 | * curl -XGET "https://SERVER/api/v2/groups/member?pretty" |
||
130 | * curl -XGET "https://SERVER/api/v2/groups/544627ed3c58891f058b4611/member?pretty" |
||
131 | * curl -XGET "https://SERVER/api/v2/groups/member?name=logingroup&pretty" |
||
132 | * |
||
133 | * @apiSuccess {object[]} - List of user |
||
134 | * @apiSuccess {string} -.id User ID |
||
135 | * @apiSuccess {string} -.name Username |
||
136 | * @apiSuccess {string} -.mail Mail address |
||
137 | * @apiSuccessExample {json} Success-Response: |
||
138 | * HTTP/1.1 200 OK |
||
139 | * [ |
||
140 | * { |
||
141 | * "id": "544627ed3c58891f058b4613", |
||
142 | * "name": "ted", |
||
143 | * "mail": "[email protected]" |
||
144 | * } |
||
145 | * ] |
||
146 | */ |
||
147 | public function getMembers(string $id, array $attributes = [], int $offset = 0, int $limit = 20): Response |
||
148 | { |
||
149 | $group = $this->_getGroup($id); |
||
150 | $result = $group->getResolvedMembers($offset, $limit); |
||
151 | $uri = '/api/v2/groups/'.$group->getId().'/members'; |
||
152 | $pager = new Pager($this->decorator, $result, $attributes, $offset, $limit, $uri); |
||
153 | $result = $pager->paging(); |
||
154 | |||
155 | return (new Response())->setCode(200)->setBody($result); |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * @api {get} /api/v2/groups/:id Get group attributes |
||
160 | * @apiVersion 2.0.0 |
||
161 | * @apiName get |
||
162 | * @apiUse _getGroup |
||
163 | * @apiGroup Group |
||
164 | * @apiPermission none |
||
165 | * @apiDescription Get group attributes |
||
166 | * |
||
167 | * @apiExample Example usage: |
||
168 | * curl -XGET "https://SERVER/api/v2/groups/attributes?pretty" |
||
169 | * curl -XGET "https://SERVER/api/v2/groups/544627ed3c58891f058b4611/attributes?pretty" |
||
170 | * curl -XGET "https://SERVER/api/v2/groups/attributes?name=loginser&pretty" |
||
171 | * |
||
172 | * @apiSuccess (200 OK) {string} id group ID |
||
173 | * @apiSuccess (200 OK) {string} name group name |
||
174 | * |
||
175 | * @apiSuccessExample {json} Success-Response: |
||
176 | * HTTP/1.1 200 OK |
||
177 | * { |
||
178 | * "id": "544627ed3c58891f058b46cd", |
||
179 | * "name": "test" |
||
180 | * } |
||
181 | * |
||
182 | * @param string $id |
||
183 | * @param string $attributes |
||
184 | * @param null|mixed $query |
||
185 | */ |
||
186 | public function get(?string $id = null, $query = null, array $attributes = [], int $offset = 0, int $limit = 20): Response |
||
187 | { |
||
188 | if ($id === null) { |
||
189 | if ($query === null) { |
||
190 | $query = []; |
||
191 | } elseif (is_string($query)) { |
||
192 | $query = toPHP(fromJSON($query), [ |
||
193 | 'root' => 'array', |
||
194 | 'document' => 'array', |
||
195 | 'array' => 'array', |
||
196 | ]); |
||
197 | } |
||
198 | |||
199 | $result = $this->server->getGroups($query, $offset, $limit); |
||
200 | $pager = new Pager($this->decorator, $result, $attributes, $offset, $limit, '/api/v2/groups'); |
||
201 | $result = $pager->paging(); |
||
202 | } else { |
||
203 | $result = $this->decorator->decorate($this->_getGroup($id), $attributes); |
||
204 | } |
||
205 | |||
206 | return (new Response())->setCode(200)->setBody($result); |
||
207 | } |
||
208 | |||
209 | /** |
||
210 | * @api {head} /api/v2/groups/:id Group exists |
||
211 | * @apiVersion 2.0.0 |
||
212 | * @apiName postQuota |
||
213 | * @apiUse _getGroup |
||
214 | * @apiGroup Group |
||
215 | * @apiPermission admin |
||
216 | * @apiDescription Check if group account exists |
||
217 | * |
||
218 | * @apiExample Example usage: |
||
219 | * curl -XHEAD "https://SERVER/api/v2/group" |
||
220 | * curl -XHEAD "https://SERVER/api/v2/groups/544627ed3c58891f058b4611" |
||
221 | * curl -XHEAD "https://SERVER/api/v2/group?name=logingroup" |
||
222 | * |
||
223 | * @apiSuccessExample {json} Success-Response: |
||
224 | * HTTP/1.1 204 No Content |
||
225 | */ |
||
226 | public function head(string $id): Response |
||
227 | { |
||
228 | $result = $this->_getGroup($id, true); |
||
0 ignored issues
–
show
$result is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the
Loading history...
|
|||
229 | |||
230 | return (new Response())->setCode(204); |
||
231 | } |
||
232 | |||
233 | /** |
||
234 | * @api {post} /api/v2/groups Create group |
||
235 | * @apiVersion 2.0.0 |
||
236 | * @apiName postGroup |
||
237 | * @apiGroup Group |
||
238 | * @apiPermission admin |
||
239 | * @apiDescription Create group |
||
240 | * |
||
241 | * @apiExample Example usage: |
||
242 | * curl -XPOST "https://SERVER/api/v2/group" |
||
243 | * |
||
244 | * @apiParam (POST Parameter) {string} name group name |
||
245 | * @apiParam (POST Parameter) {string[]} member Array of member id |
||
246 | * @apiParam (POST Parameter) {string} namespace Namespace |
||
247 | * @apiParam (POST Parameter) {string[]} optional Optional attributes |
||
248 | * |
||
249 | * @apiSuccess (200 OK) {string} id group ID |
||
250 | * @apiSuccess (200 OK) {string} name group name |
||
251 | * |
||
252 | * @apiSuccessExample {json} Success-Response: |
||
253 | * HTTP/1.1 201 Created |
||
254 | * { |
||
255 | * "id": "544627ed3c58891f058b46cd", |
||
256 | * "name": "test" |
||
257 | * } |
||
258 | * |
||
259 | * @param array $member |
||
260 | */ |
||
261 | public function post(string $name, ?array $member = null, ?string $namespace = null, ?array $optional = null): Response |
||
262 | { |
||
263 | if (!$this->user->isAdmin()) { |
||
264 | throw new Exception\NotAdmin('submitted parameters require admin privileges'); |
||
265 | } |
||
266 | |||
267 | $attributes = compact('namespace', 'optional'); |
||
268 | $attributes = array_filter($attributes, function ($attribute) {return !is_null($attribute); }); |
||
269 | |||
270 | $id = $this->server->addGroup($name, $member, $attributes); |
||
0 ignored issues
–
show
It seems like
$member defined by parameter $member on line 261 can also be of type null ; however, Balloon\Server::addGroup() does only seem to accept array , maybe add an additional type check?
This check looks at variables that have been passed in as parameters and are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble.
Loading history...
|
|||
271 | $result = $this->decorator->decorate($this->server->getGroupById($id)); |
||
272 | |||
273 | return (new Response())->setBody($result)->setCode(201); |
||
274 | } |
||
275 | |||
276 | /** |
||
277 | * @api {patch} /api/v2/groups/:id Change group attributes |
||
278 | * @apiVersion 2.0.0 |
||
279 | * @apiName patch |
||
280 | * @apiUse _getGroup |
||
281 | * @apiGroup Group |
||
282 | * @apiPermission admin |
||
283 | * @apiDescription Set attributes for group |
||
284 | * |
||
285 | * @apiParam (POST Parameter) {string} name group name |
||
286 | * @apiParam (POST Parameter) {string[]} member Array of member id |
||
287 | * @apiParam (POST Parameter) {string} namespace Namespace |
||
288 | * @apiParam (POST Parameter) {string[]} optional Optional attributes |
||
289 | * |
||
290 | * @apiExample Example usage: |
||
291 | * curl -XPOST "https://SERVER/api/v2/groups/attributes" -d '{"attributes": ["mail": "[email protected]"]}' |
||
292 | * curl -XPOST "https://SERVER/api/v2/groups/attributes?{%22attributes%22:[%22mail%22:%[email protected]%22]}"" |
||
293 | * curl -XPOST "https://SERVER/api/v2/groups/544627ed3c58891f058b4611/attributes" -d '{"attributes": ["admin": "false"]}' |
||
294 | * curl -XPOST "https://SERVER/api/v2/groups/quota?name=logingroup" -d '{"attributes": ["admin": "false"]}' |
||
295 | * |
||
296 | * @apiSuccessExample {json} Success-Response: |
||
297 | * HTTP/1.1 200 OK |
||
298 | */ |
||
299 | public function patch(string $id, ?array $member = null, ?string $namespace = null, ?array $optional = null): Response |
||
300 | { |
||
301 | $attributes = compact('namespace', 'optional', 'name', 'member'); |
||
302 | $attributes = array_filter($attributes, function ($attribute) {return !is_null($attribute); }); |
||
303 | |||
304 | $group = $this->_getGroup($id, true); |
||
305 | $group->setAttributes($attributes); |
||
306 | $result = $this->decorator->decorate($group); |
||
307 | |||
308 | return (new Response())->setCode(200)->setBody($result); |
||
309 | } |
||
310 | |||
311 | /** |
||
312 | * @api {delete} /api/v2/groups/:id Delete group |
||
313 | * @apiVersion 2.0.0 |
||
314 | * @apiName delete |
||
315 | * @apiUse _getGroup |
||
316 | * @apiGroup Group |
||
317 | * @apiPermission admin |
||
318 | * @apiDescription Delete group |
||
319 | * |
||
320 | * @apiExample Example usage: |
||
321 | * curl -XDELETE "https://SERVER/api/v2/groups/544627ed3c58891f058b4611?force=1" |
||
322 | * curl -XDELETE "https://SERVER/api/v2/group?name=logingroup" |
||
323 | * |
||
324 | * @apiParam (GET Parameter) {bool} [force=false] Per default the group gets disabled, if force is set |
||
325 | * the group gets removed completely. |
||
326 | * |
||
327 | * @apiErrorExample {json} Error-Response (Can not delete yourself): |
||
328 | * HTTP/1.1 400 Bad Request |
||
329 | * { |
||
330 | * "status": 400, |
||
331 | * "data": { |
||
332 | * "error": "Balloon\\Exception\\Conflict", |
||
333 | * "message": "requested group was not found" |
||
334 | * } |
||
335 | * } |
||
336 | * |
||
337 | * @apiSuccessExample {json} Success-Response: |
||
338 | * HTTP/1.1 204 No Content |
||
339 | */ |
||
340 | public function delete(string $id, bool $force = false): Response |
||
341 | { |
||
342 | $group = $this->_getGroup($id, true); |
||
343 | $group->delete($force); |
||
344 | |||
345 | return (new Response())->setCode(204); |
||
346 | } |
||
347 | |||
348 | /** |
||
349 | * @api {post} /api/v2/groups/:id/undelete Restore group |
||
350 | * @apiVersion 2.0.0 |
||
351 | * @apiName postUndelete |
||
352 | * @apiUse _getGroup |
||
353 | * @apiGroup Group |
||
354 | * @apiPermission admin |
||
355 | * @apiDescription Restore deleted group |
||
356 | * |
||
357 | * @apiExample Example usage: |
||
358 | * curl -XPOST "https://SERVER/api/v2/groups/544627ed3c58891f058b4611/undelete" |
||
359 | * curl -XPOST "https://SERVER/api/v2/groups/undelete?group=logingroup" |
||
360 | * |
||
361 | * @apiSuccessExample {json} Success-Response: |
||
362 | * HTTP/1.1 204 No Content |
||
363 | */ |
||
364 | public function postUndelete(string $id): Response |
||
365 | { |
||
366 | $this->_getGroup($id, true)->undelete(); |
||
367 | |||
368 | return (new Response())->setCode(204); |
||
369 | } |
||
370 | } |
||
371 |
Let’s assume that you have a directory layout like this:
and let’s assume the following content of
Bar.php
:If both files
OtherDir/Foo.php
andSomeDir/Foo.php
are loaded in the same runtime, you will see a PHP error such as the following:PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php
However, as
OtherDir/Foo.php
does not necessarily have to be loaded and the error is only triggered if it is loaded beforeOtherDir/Bar.php
, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias: