Browse Source

Improve authorization middleware

Maurits van der Schee 5 years ago
parent
commit
d98c92ba1b

+ 22
- 15
api.php View File

@@ -667,7 +667,7 @@ class DefinitionService
667 667
 
668 668
     public function updateTable(String $tableName, /* object */ $changes): bool
669 669
     {
670
-        $table = $this->reflection->getTable($tableName);
670
+        $table = $database->get($tableName);
671 671
         $newTable = ReflectedTable::fromJson((object) array_merge((array) $table->jsonSerialize(), (array) $changes));
672 672
         if ($table->getName() != $newTable->getName()) {
673 673
             if (!$this->db->definition()->renameTable($table->getName(), $newTable->getName())) {
@@ -679,7 +679,7 @@ class DefinitionService
679 679
 
680 680
     public function updateColumn(String $tableName, String $columnName, /* object */ $changes): bool
681 681
     {
682
-        $table = $this->reflection->getTable($tableName);
682
+        $table = $database->get($tableName);
683 683
         $column = $table->get($columnName);
684 684
 
685 685
         $newColumn = ReflectedColumn::fromJson((object) array_merge((array) $column->jsonSerialize(), (array) $changes));
@@ -780,7 +780,7 @@ class DefinitionService
780 780
 
781 781
     public function removeColumn(String $tableName, String $columnName)
782 782
     {
783
-        $table = $this->reflection->getTable($tableName);
783
+        $table = $database->get($tableName);
784 784
         $newColumn = $table->get($columnName);
785 785
         if ($newColumn->getPk()) {
786 786
             $newColumn->setPk(false);
@@ -901,10 +901,11 @@ class ColumnController
901 901
     public function getTable(Request $request): Response
902 902
     {
903 903
         $tableName = $request->getPathSegment(2);
904
-        if (!$this->reflection->hasTable($tableName)) {
904
+        $database = $this->reflection->getDatabase();
905
+        if (!$database->exists($tableName)) {
905 906
             return $this->responder->error(ErrorCode::TABLE_NOT_FOUND, $tableName);
906 907
         }
907
-        $table = $this->reflection->getTable($tableName);
908
+        $table = $database->get($tableName);
908 909
         return $this->responder->success($table);
909 910
     }
910 911
 
@@ -912,10 +913,11 @@ class ColumnController
912 913
     {
913 914
         $tableName = $request->getPathSegment(2);
914 915
         $columnName = $request->getPathSegment(3);
915
-        if (!$this->reflection->hasTable($tableName)) {
916
+        $database = $this->reflection->getDatabase();
917
+        if (!$database->exists($tableName)) {
916 918
             return $this->responder->error(ErrorCode::TABLE_NOT_FOUND, $tableName);
917 919
         }
918
-        $table = $this->reflection->getTable($tableName);
920
+        $table = $database->get($tableName);
919 921
         if (!$table->exists($columnName)) {
920 922
             return $this->responder->error(ErrorCode::COLUMN_NOT_FOUND, $columnName);
921 923
         }
@@ -926,7 +928,8 @@ class ColumnController
926 928
     public function updateTable(Request $request): Response
927 929
     {
928 930
         $tableName = $request->getPathSegment(2);
929
-        if (!$this->reflection->hasTable($tableName)) {
931
+        $database = $this->reflection->getDatabase();
932
+        if (!$database->exists($tableName)) {
930 933
             return $this->responder->error(ErrorCode::TABLE_NOT_FOUND, $tableName);
931 934
         }
932 935
         $success = $this->definition->updateTable($tableName, $request->getBody());
@@ -940,10 +943,11 @@ class ColumnController
940 943
     {
941 944
         $tableName = $request->getPathSegment(2);
942 945
         $columnName = $request->getPathSegment(3);
943
-        if (!$this->reflection->hasTable($tableName)) {
946
+        $database = $this->reflection->getDatabase();
947
+        if (!$database->exists($tableName)) {
944 948
             return $this->responder->error(ErrorCode::TABLE_NOT_FOUND, $tableName);
945 949
         }
946
-        $table = $this->reflection->getTable($tableName);
950
+        $table = $database->get($tableName);
947 951
         if (!$table->exists($columnName)) {
948 952
             return $this->responder->error(ErrorCode::COLUMN_NOT_FOUND, $columnName);
949 953
         }
@@ -970,11 +974,12 @@ class ColumnController
970 974
     public function addColumn(Request $request): Response
971 975
     {
972 976
         $tableName = $request->getPathSegment(2);
973
-        if (!$this->reflection->hasTable($tableName)) {
977
+        $database = $this->reflection->getDatabase();
978
+        if (!$database->exists($tableName)) {
974 979
             return $this->responder->error(ErrorCode::TABLE_NOT_FOUND, $tableName);
975 980
         }
976 981
         $columnName = $request->getBody()->name;
977
-        $table = $this->reflection->getTable($tableName);
982
+        $table = $database->get($tableName);
978 983
         if ($table->exists($columnName)) {
979 984
             return $this->responder->error(ErrorCode::COLUMN_ALREADY_EXISTS, $columnName);
980 985
         }
@@ -988,7 +993,8 @@ class ColumnController
988 993
     public function removeTable(Request $request): Response
989 994
     {
990 995
         $tableName = $request->getPathSegment(2);
991
-        if (!$this->reflection->hasTable($tableName)) {
996
+        $database = $this->reflection->getDatabase();
997
+        if (!$database->exists($tableName)) {
992 998
             return $this->responder->error(ErrorCode::TABLE_NOT_FOUND, $tableName);
993 999
         }
994 1000
         $success = $this->definition->removeTable($tableName);
@@ -1002,10 +1008,11 @@ class ColumnController
1002 1008
     {
1003 1009
         $tableName = $request->getPathSegment(2);
1004 1010
         $columnName = $request->getPathSegment(3);
1005
-        if (!$this->reflection->hasTable($tableName)) {
1011
+        $database = $this->reflection->getDatabase();
1012
+        if (!$database->exists($tableName)) {
1006 1013
             return $this->responder->error(ErrorCode::TABLE_NOT_FOUND, $tableName);
1007 1014
         }
1008
-        $table = $this->reflection->getTable($tableName);
1015
+        $table = $database->get($tableName);
1009 1016
         if (!$table->exists($columnName)) {
1010 1017
             return $this->responder->error(ErrorCode::COLUMN_NOT_FOUND, $columnName);
1011 1018
         }

+ 3
- 0
src/Tqdev/PhpCrudApi/Api.php View File

@@ -57,6 +57,9 @@ class Api
57 57
                 case 'sanitation':
58 58
                     new SanitationMiddleware($router, $responder, $properties, $reflection);
59 59
                     break;
60
+                case 'authorization':
61
+                    new AuthorizationMiddleware($router, $responder, $properties, $reflection);
62
+                    break;
60 63
             }
61 64
         }
62 65
         $data = new RecordService($db, $reflection);

+ 1
- 1
src/Tqdev/PhpCrudApi/Column/DefinitionService.php View File

@@ -1,9 +1,9 @@
1 1
 <?php
2 2
 namespace Tqdev\PhpCrudApi\Column;
3 3
 
4
-use Tqdev\PhpCrudApi\Database\GenericDB;
5 4
 use Tqdev\PhpCrudApi\Column\Reflection\ReflectedColumn;
6 5
 use Tqdev\PhpCrudApi\Column\Reflection\ReflectedTable;
6
+use Tqdev\PhpCrudApi\Database\GenericDB;
7 7
 
8 8
 class DefinitionService
9 9
 {

+ 21
- 12
src/Tqdev/PhpCrudApi/Middleware/AuthorizationMiddleware.php View File

@@ -19,24 +19,33 @@ class AuthorizationMiddleware extends Middleware
19 19
         $this->reflection = $reflection;
20 20
     }
21 21
 
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
+
22 35
     public function handle(Request $request): Response
23 36
     {
24 37
         $path = $request->getPathSegment(1);
25 38
         $tableName = $request->getPathSegment(2);
26 39
         $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)) {
29 42
             $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, '');
40 49
             }
41 50
         }
42 51
         return $this->next->handle($request);

+ 3
- 3
src/Tqdev/PhpCrudApi/Middleware/SanitationMiddleware.php View File

@@ -1,13 +1,13 @@
1 1
 <?php
2 2
 namespace Tqdev\PhpCrudApi\Middleware;
3 3
 
4
-use Tqdev\PhpCrudApi\Controller\Responder;
5 4
 use Tqdev\PhpCrudApi\Column\ReflectionService;
6 5
 use Tqdev\PhpCrudApi\Column\Reflection\ReflectedTable;
7
-use Tqdev\PhpCrudApi\Request;
8
-use Tqdev\PhpCrudApi\Response;
6
+use Tqdev\PhpCrudApi\Controller\Responder;
9 7
 use Tqdev\PhpCrudApi\Middleware\Base\Middleware;
10 8
 use Tqdev\PhpCrudApi\Middleware\Router\Router;
9
+use Tqdev\PhpCrudApi\Request;
10
+use Tqdev\PhpCrudApi\Response;
11 11
 
12 12
 class SanitationMiddleware extends Middleware
13 13
 {

+ 2
- 0
src/Tqdev/PhpCrudApi/Record/ErrorCode.php View File

@@ -25,6 +25,7 @@ class ErrorCode
25 25
     const AUTHORIZATION_REQUIRED = 1011;
26 26
     const ACCESS_DENIED = 1012;
27 27
     const INPUT_VALIDATION_FAILED = 1013;
28
+    const OPERATION_FORBIDDEN = 1014;
28 29
 
29 30
     private $values = [
30 31
         9999 => ["%s", Response::INTERNAL_SERVER_ERROR],
@@ -42,6 +43,7 @@ class ErrorCode
42 43
         1011 => ["Authorization required", Response::UNAUTHORIZED],
43 44
         1012 => ["Access denied for '%s'", Response::FORBIDDEN],
44 45
         1013 => ["Input validation failed for '%s'", Response::UNPROCESSABLE_ENTITY],
46
+        1014 => ["Operation forbidden", Response::FORBIDDEN],
45 47
     ];
46 48
 
47 49
     public function __construct(int $code)

Loading…
Cancel
Save