Skip to content

Commit d98c92b

Browse files
committed
Improve authorization middleware
1 parent 8e11531 commit d98c92b

File tree

6 files changed

+52
-31
lines changed

6 files changed

+52
-31
lines changed

api.php

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ public function __construct(GenericDB $db, ReflectionService $reflection)
667667

668668
public function updateTable(String $tableName, /* object */ $changes): bool
669669
{
670-
$table = $this->reflection->getTable($tableName);
670+
$table = $database->get($tableName);
671671
$newTable = ReflectedTable::fromJson((object) array_merge((array) $table->jsonSerialize(), (array) $changes));
672672
if ($table->getName() != $newTable->getName()) {
673673
if (!$this->db->definition()->renameTable($table->getName(), $newTable->getName())) {
@@ -679,7 +679,7 @@ public function updateTable(String $tableName, /* object */ $changes): bool
679679

680680
public function updateColumn(String $tableName, String $columnName, /* object */ $changes): bool
681681
{
682-
$table = $this->reflection->getTable($tableName);
682+
$table = $database->get($tableName);
683683
$column = $table->get($columnName);
684684

685685
$newColumn = ReflectedColumn::fromJson((object) array_merge((array) $column->jsonSerialize(), (array) $changes));
@@ -780,7 +780,7 @@ public function removeTable(String $tableName)
780780

781781
public function removeColumn(String $tableName, String $columnName)
782782
{
783-
$table = $this->reflection->getTable($tableName);
783+
$table = $database->get($tableName);
784784
$newColumn = $table->get($columnName);
785785
if ($newColumn->getPk()) {
786786
$newColumn->setPk(false);
@@ -901,21 +901,23 @@ public function getDatabase(Request $request): Response
901901
public function getTable(Request $request): Response
902902
{
903903
$tableName = $request->getPathSegment(2);
904-
if (!$this->reflection->hasTable($tableName)) {
904+
$database = $this->reflection->getDatabase();
905+
if (!$database->exists($tableName)) {
905906
return $this->responder->error(ErrorCode::TABLE_NOT_FOUND, $tableName);
906907
}
907-
$table = $this->reflection->getTable($tableName);
908+
$table = $database->get($tableName);
908909
return $this->responder->success($table);
909910
}
910911

911912
public function getColumn(Request $request): Response
912913
{
913914
$tableName = $request->getPathSegment(2);
914915
$columnName = $request->getPathSegment(3);
915-
if (!$this->reflection->hasTable($tableName)) {
916+
$database = $this->reflection->getDatabase();
917+
if (!$database->exists($tableName)) {
916918
return $this->responder->error(ErrorCode::TABLE_NOT_FOUND, $tableName);
917919
}
918-
$table = $this->reflection->getTable($tableName);
920+
$table = $database->get($tableName);
919921
if (!$table->exists($columnName)) {
920922
return $this->responder->error(ErrorCode::COLUMN_NOT_FOUND, $columnName);
921923
}
@@ -926,7 +928,8 @@ public function getColumn(Request $request): Response
926928
public function updateTable(Request $request): Response
927929
{
928930
$tableName = $request->getPathSegment(2);
929-
if (!$this->reflection->hasTable($tableName)) {
931+
$database = $this->reflection->getDatabase();
932+
if (!$database->exists($tableName)) {
930933
return $this->responder->error(ErrorCode::TABLE_NOT_FOUND, $tableName);
931934
}
932935
$success = $this->definition->updateTable($tableName, $request->getBody());
@@ -940,10 +943,11 @@ public function updateColumn(Request $request): Response
940943
{
941944
$tableName = $request->getPathSegment(2);
942945
$columnName = $request->getPathSegment(3);
943-
if (!$this->reflection->hasTable($tableName)) {
946+
$database = $this->reflection->getDatabase();
947+
if (!$database->exists($tableName)) {
944948
return $this->responder->error(ErrorCode::TABLE_NOT_FOUND, $tableName);
945949
}
946-
$table = $this->reflection->getTable($tableName);
950+
$table = $database->get($tableName);
947951
if (!$table->exists($columnName)) {
948952
return $this->responder->error(ErrorCode::COLUMN_NOT_FOUND, $columnName);
949953
}
@@ -970,11 +974,12 @@ public function addTable(Request $request): Response
970974
public function addColumn(Request $request): Response
971975
{
972976
$tableName = $request->getPathSegment(2);
973-
if (!$this->reflection->hasTable($tableName)) {
977+
$database = $this->reflection->getDatabase();
978+
if (!$database->exists($tableName)) {
974979
return $this->responder->error(ErrorCode::TABLE_NOT_FOUND, $tableName);
975980
}
976981
$columnName = $request->getBody()->name;
977-
$table = $this->reflection->getTable($tableName);
982+
$table = $database->get($tableName);
978983
if ($table->exists($columnName)) {
979984
return $this->responder->error(ErrorCode::COLUMN_ALREADY_EXISTS, $columnName);
980985
}
@@ -988,7 +993,8 @@ public function addColumn(Request $request): Response
988993
public function removeTable(Request $request): Response
989994
{
990995
$tableName = $request->getPathSegment(2);
991-
if (!$this->reflection->hasTable($tableName)) {
996+
$database = $this->reflection->getDatabase();
997+
if (!$database->exists($tableName)) {
992998
return $this->responder->error(ErrorCode::TABLE_NOT_FOUND, $tableName);
993999
}
9941000
$success = $this->definition->removeTable($tableName);
@@ -1002,10 +1008,11 @@ public function removeColumn(Request $request): Response
10021008
{
10031009
$tableName = $request->getPathSegment(2);
10041010
$columnName = $request->getPathSegment(3);
1005-
if (!$this->reflection->hasTable($tableName)) {
1011+
$database = $this->reflection->getDatabase();
1012+
if (!$database->exists($tableName)) {
10061013
return $this->responder->error(ErrorCode::TABLE_NOT_FOUND, $tableName);
10071014
}
1008-
$table = $this->reflection->getTable($tableName);
1015+
$table = $database->get($tableName);
10091016
if (!$table->exists($columnName)) {
10101017
return $this->responder->error(ErrorCode::COLUMN_NOT_FOUND, $columnName);
10111018
}

src/Tqdev/PhpCrudApi/Api.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ public function __construct(Config $config)
5757
case 'sanitation':
5858
new SanitationMiddleware($router, $responder, $properties, $reflection);
5959
break;
60+
case 'authorization':
61+
new AuthorizationMiddleware($router, $responder, $properties, $reflection);
62+
break;
6063
}
6164
}
6265
$data = new RecordService($db, $reflection);

src/Tqdev/PhpCrudApi/Column/DefinitionService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<?php
22
namespace Tqdev\PhpCrudApi\Column;
33

4-
use Tqdev\PhpCrudApi\Database\GenericDB;
54
use Tqdev\PhpCrudApi\Column\Reflection\ReflectedColumn;
65
use Tqdev\PhpCrudApi\Column\Reflection\ReflectedTable;
6+
use Tqdev\PhpCrudApi\Database\GenericDB;
77

88
class DefinitionService
99
{

src/Tqdev/PhpCrudApi/Middleware/AuthorizationMiddleware.php

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,33 @@ public function __construct(Router $router, Responder $responder, array $propert
1919
$this->reflection = $reflection;
2020
}
2121

22+
private function getIncludes($all, $list)
23+
{
24+
$result = array_fill_keys($all, false);
25+
foreach ($lists as $items) {
26+
foreach (explode(',', $items) as $item) {
27+
if (isset($result[$item])) {
28+
$result[$item] = true;
29+
}
30+
}
31+
}
32+
return $result;
33+
}
34+
2235
public function handle(Request $request): Response
2336
{
2437
$path = $request->getPathSegment(1);
2538
$tableName = $request->getPathSegment(2);
2639
$database = $this->reflection->getDatabase();
27-
if ($path == 'records' && $database->exists($tableName)) {
28-
$table = $database->get($tableName);
40+
$handler = $this->getProperty('handler', '');
41+
if ($handler !== '' && $path == 'records' && $database->exists($tableName)) {
2942
$method = $request->getMethod();
30-
$tableHandler = $this->getProperty('tableHandler', '');
31-
if ($tableHandler !== '') {
32-
$valid = call_user_func($handler, $method, $tableName);
33-
if ($valid !== true && $valid !== '') {
34-
$details[$columnName] = $valid;
35-
}
36-
if (count($details) > 0) {
37-
return $this->responder->error(ErrorCode::INPUT_VALIDATION_FAILED, $tableName, $details);
38-
}
39-
43+
$tableNames = $database->getTableNames();
44+
$params = $request->getParams();
45+
$includes = $this->getIncludes($tableNames, $params['include']);
46+
$allowed = call_user_func($handler, $method, $tableName, $includes);
47+
if (!$allowed) {
48+
return $this->responder->error(ErrorCode::OPERATION_FORBIDDEN, '');
4049
}
4150
}
4251
return $this->next->handle($request);

src/Tqdev/PhpCrudApi/Middleware/SanitationMiddleware.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
<?php
22
namespace Tqdev\PhpCrudApi\Middleware;
33

4-
use Tqdev\PhpCrudApi\Controller\Responder;
54
use Tqdev\PhpCrudApi\Column\ReflectionService;
65
use Tqdev\PhpCrudApi\Column\Reflection\ReflectedTable;
7-
use Tqdev\PhpCrudApi\Request;
8-
use Tqdev\PhpCrudApi\Response;
6+
use Tqdev\PhpCrudApi\Controller\Responder;
97
use Tqdev\PhpCrudApi\Middleware\Base\Middleware;
108
use Tqdev\PhpCrudApi\Middleware\Router\Router;
9+
use Tqdev\PhpCrudApi\Request;
10+
use Tqdev\PhpCrudApi\Response;
1111

1212
class SanitationMiddleware extends Middleware
1313
{

src/Tqdev/PhpCrudApi/Record/ErrorCode.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class ErrorCode
2525
const AUTHORIZATION_REQUIRED = 1011;
2626
const ACCESS_DENIED = 1012;
2727
const INPUT_VALIDATION_FAILED = 1013;
28+
const OPERATION_FORBIDDEN = 1014;
2829

2930
private $values = [
3031
9999 => ["%s", Response::INTERNAL_SERVER_ERROR],
@@ -42,6 +43,7 @@ class ErrorCode
4243
1011 => ["Authorization required", Response::UNAUTHORIZED],
4344
1012 => ["Access denied for '%s'", Response::FORBIDDEN],
4445
1013 => ["Input validation failed for '%s'", Response::UNPROCESSABLE_ENTITY],
46+
1014 => ["Operation forbidden", Response::FORBIDDEN],
4547
];
4648

4749
public function __construct(int $code)

0 commit comments

Comments
 (0)