diff --git a/appinfo/info.xml b/appinfo/info.xml
index c7b72b333..e9dd9bfac 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -20,6 +20,7 @@
https://www.arawa.fr/contact/
+
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index 216b74427..b70790cb8 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -31,7 +31,6 @@
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
-use OCP\AppFramework\Utility\IControllerMethodReflector;
use OCP\IRequest;
use OCP\IURLGenerator;
@@ -52,7 +51,6 @@ public function register(IRegistrationContext $context): void {
$context->registerService(IsSpaceAdminMiddleware::class, function ($c) {
return new IsSpaceAdminMiddleware(
- $c->query(IControllerMethodReflector::class),
$c->query(IRequest::class),
$c->query(UserService::class),
$c->query(SpaceService::class)
@@ -61,8 +59,6 @@ public function register(IRegistrationContext $context): void {
$context->registerService(IsGeneralManagerMiddleware::class, function ($c) {
return new IsGeneralManagerMiddleware(
- $c->query(IControllerMethodReflector::class),
- $c->query(IRequest::class),
$c->query(UserService::class)
);
});
diff --git a/lib/Controller/FileCSVController.php b/lib/Controller/FileCSVController.php
index 2dce3ea4e..110269b99 100644
--- a/lib/Controller/FileCSVController.php
+++ b/lib/Controller/FileCSVController.php
@@ -28,10 +28,12 @@
use OCA\Workspace\Files\Csv;
use OCA\Workspace\Files\InternalFile;
use OCA\Workspace\Files\LocalFile;
+use OCA\Workspace\Middleware\Attribute\SpaceAdminRequired;
use OCA\Workspace\Service\UserService;
use OCA\Workspace\Service\WorkspaceService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\JSONResponse;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
@@ -57,11 +59,10 @@ public function __construct(
}
/**
- * @NoAdminRequired
- * @SpaceAdminRequired
* Returns formatted list of existing users of the instance.
- *
*/
+ #[NoAdminRequired]
+ #[SpaceAdminRequired]
public function import(): JSONResponse {
$params = $this->request->getParams();
$spaceObj = $params['space'];
@@ -116,11 +117,10 @@ public function import(): JSONResponse {
}
/**
- * @NoAdminRequired
- * @SpaceAdminRequired
* Returns formatted list of existing users of the instance.
- *
*/
+ #[NoAdminRequired]
+ #[SpaceAdminRequired]
public function getFromFiles():JSONResponse {
$params = $this->request->getParams();
$path = $params['path'];
diff --git a/lib/Controller/GroupController.php b/lib/Controller/GroupController.php
index f9493e8fe..ff48a703e 100644
--- a/lib/Controller/GroupController.php
+++ b/lib/Controller/GroupController.php
@@ -25,6 +25,8 @@
namespace OCA\Workspace\Controller;
+use OCA\Workspace\Middleware\Attribute\GeneralManagerRequired;
+use OCA\Workspace\Middleware\Attribute\SpaceAdminRequired;
use OCA\Workspace\Service\Group\GroupFolder\GroupFolderManage;
use OCA\Workspace\Service\Group\GroupFormatter;
use OCA\Workspace\Service\Group\GroupsWorkspaceService;
@@ -36,6 +38,7 @@
use OCA\Workspace\Service\UserService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IGroupManager;
use OCP\IRequest;
@@ -60,9 +63,6 @@ public function __construct(
}
/**
- * @NoAdminRequired
- * @SpaceAdminRequired
- *
* Creates a group
* NB: This function could probably be abused by space managers to create arbitrary group. But, do we really care?
*
@@ -73,6 +73,8 @@ public function __construct(
* @var string $spaceId for Middleware
*
*/
+ #[NoAdminRequired]
+ #[SpaceAdminRequired]
public function create(array $data = []): JSONResponse {
$data = array_merge(self::DEFAULT, $data);
@@ -100,9 +102,6 @@ public function create(array $data = []): JSONResponse {
}
/**
- * @NoAdminRequired
- * @SpaceAdminRequired
- *
* Deletes a group
* Cannot delete GE- and U- groups (This is on-purpose)
*
@@ -110,6 +109,8 @@ public function create(array $data = []): JSONResponse {
* @var int $spaceId
*
*/
+ #[NoAdminRequired]
+ #[SpaceAdminRequired]
public function delete(string $gid, int $spaceId): JSONResponse {
// TODO Use groupfolder api to retrieve workspace group.
if (substr($gid, -strlen($spaceId)) != $spaceId) {
@@ -132,9 +133,6 @@ public function delete(string $gid, int $spaceId): JSONResponse {
}
/**
- * @NoAdminRequired
- * @SpaceAdminRequired
- *
* Renames a group
* Cannot rename GE- and U- groups (This is on-purpose)
*
@@ -143,6 +141,8 @@ public function delete(string $gid, int $spaceId): JSONResponse {
* @var int $spaceId
*
*/
+ #[NoAdminRequired]
+ #[SpaceAdminRequired]
public function rename(string $newGroupName,
string $gid,
int $spaceId): JSONResponse {
@@ -176,8 +176,6 @@ public function rename(string $newGroupName,
}
/**
- * @NoAdminRequired
- * @SpaceAdminRequired
* Adds a user to a group.
* The function automaticaly adds the user the the corresponding workspace's user group, and to the application
* manager group when we are adding a workspace manager
@@ -187,6 +185,8 @@ public function rename(string $newGroupName,
* @var string $user
*
*/
+ #[NoAdminRequired]
+ #[SpaceAdminRequired]
public function addUser(string $spaceId, string $gid, string $user): JSONResponse {
// Makes sure group exist
$NCGroup = $this->groupManager->get($gid);
@@ -226,14 +226,13 @@ public function addUser(string $spaceId, string $gid, string $user): JSONRespons
/**
* Remove a user from a workspace.
*
- * @NoAdminRequired
- * @SpaceAdminRequired
- *
* @param array|string $space
* @param string $gid
* @param string $user
* @return JSONResponse
*/
+ #[NoAdminRequired]
+ #[SpaceAdminRequired]
public function removeUserFromWorkspace(
array|string $space,
string $gid,
@@ -283,9 +282,6 @@ public function removeUserFromWorkspace(
}
/**
- * @NoAdminRequired
- * @SpaceAdminRequired
- *
* Removes a user from a group
* The function also remove the user from all workspace 'subgroup when the user is being removed from the U- group
* and from the WorkspacesManagers group when the user is being removed from the GE- group
@@ -295,6 +291,8 @@ public function removeUserFromWorkspace(
* @var string $user
*
*/
+ #[NoAdminRequired]
+ #[SpaceAdminRequired]
public function removeUser(
IRequest $request,
array|string $space,
@@ -370,11 +368,11 @@ public function removeUser(
}
/**
- * @NoAdminRequired
- * @GeneralManagerRequired
+ * @param string $spaceId
* @param string|array $groupfolder
- *
*/
+ #[NoAdminRequired]
+ #[GeneralManagerRequired]
public function transferUsersToGroups(string $spaceId,
string|array $groupfolder): JSONResponse {
if (gettype($groupfolder) === 'string') {
diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php
index df78af9da..c7e6711b3 100644
--- a/lib/Controller/PageController.php
+++ b/lib/Controller/PageController.php
@@ -28,6 +28,8 @@
use OCA\Workspace\AppInfo\Application;
use OCA\Workspace\Service\UserService;
use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
+use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\Util;
@@ -40,9 +42,9 @@ public function __construct(
/**
* Application's main page
*
- * @NoAdminRequired
- * @NOCSRFRequired
*/
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
public function index(): TemplateResponse {
Util::addScript(Application::APP_ID, 'workspace-main'); // js/workspace-main.js
Util::addStyle(Application::APP_ID, 'workspace-style'); // css/workspace-style.css
diff --git a/lib/Controller/SpaceController.php b/lib/Controller/SpaceController.php
index be73c7364..95f739492 100644
--- a/lib/Controller/SpaceController.php
+++ b/lib/Controller/SpaceController.php
@@ -26,8 +26,10 @@
namespace OCA\Workspace\Controller;
use OCA\Workspace\Db\SpaceMapper;
+use OCA\Workspace\Middleware\Attribute\SpaceAdminRequired;
use OCA\Workspace\Service\SpaceService;
use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\DataResponse;
use OCP\IRequest;
@@ -42,23 +44,24 @@ public function __construct(
}
/**
- * @NoAdminRequired
+ * @param $id - The space id to get a space - OCA\Workspace\Db\Space .
+ * @return DataResponse - The space serialized
*/
+ #[NoAdminRequired]
public function find(int $id): DataResponse {
return new DataResponse($this->spaceService->find($id));
}
- /**
- * @NoAdminRequired
- */
+ #[NoAdminRequired]
public function findAll(): DataResponse {
return new DataResponse($this->spaceService->findAll());
}
/**
- * @NoAdminRequired
- * @SpaceAdminRequired
+ * @return DataResponse - The space serialized
*/
+ #[NoAdminRequired]
+ #[SpaceAdminRequired]
public function updateColorCode(string $colorCode, int $spaceId): DataResponse {
return new DataResponse($this->spaceService->updateColorCode($colorCode, (int)$spaceId));
}
diff --git a/lib/Controller/WorkspaceController.php b/lib/Controller/WorkspaceController.php
index e9a0f2d3b..3c3e270a1 100644
--- a/lib/Controller/WorkspaceController.php
+++ b/lib/Controller/WorkspaceController.php
@@ -33,6 +33,8 @@
use OCA\Workspace\Exceptions\WorkspaceNameExistException;
use OCA\Workspace\Folder\RootFolder;
use OCA\Workspace\Helper\GroupfolderHelper;
+use OCA\Workspace\Middleware\Attribute\GeneralManagerRequired;
+use OCA\Workspace\Middleware\Attribute\SpaceAdminRequired;
use OCA\Workspace\Service\Group\GroupFormatter;
use OCA\Workspace\Service\Group\ManagersWorkspace;
use OCA\Workspace\Service\Group\UserGroup;
@@ -43,6 +45,7 @@
use OCA\Workspace\Service\WorkspaceService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IGroupManager;
use OCP\IRequest;
@@ -79,14 +82,14 @@ private function deleteBlankSpaceName(string $spaceName): string {
}
/**
- * @NoAdminRequired
- * @GeneralManagerRequired
* @param string $spaceName
* @param int $folderId
* @throws BadRequestException
* @throws CreateWorkspaceException
* @throws CreateGroupException
*/
+ #[NoAdminRequired]
+ #[GeneralManagerRequired]
public function createWorkspace(string $spaceName,
int $folderId): JSONResponse {
if ($spaceName === false ||
@@ -138,11 +141,11 @@ public function createWorkspace(string $spaceName,
*
* Deletes the workspace, and the corresponding groupfolder and groups
*
- * @NoAdminRequired
- * @GeneralManagerRequired
* @param array $workspace
*
*/
+ #[NoAdminRequired]
+ #[SpaceAdminRequired]
public function destroy(array $workspace): JSONResponse {
$this->logger->debug('Removing GE users from the WorkspacesManagers group if needed.');
$GEGroup = $this->groupManager->get(WorkspaceManagerGroup::get($workspace['id']));
@@ -179,9 +182,8 @@ public function destroy(array $workspace): JSONResponse {
*
* Returns a list of all the workspaces that the connected user may use.
*
- * @NoAdminRequired
- *
*/
+ #[NoAdminRequired]
public function findAll(): JSONResponse {
$workspaces = $this->workspaceService->getAll();
$spaces = [];
@@ -215,17 +217,17 @@ public function findAll(): JSONResponse {
}
/**
- * @NoAdminRequired
* @param string|array $workspace
*/
+ #[NoAdminRequired]
public function addGroupsInfo(string|array $workspace): JSONResponse {
return new JSONResponse($this->workspaceService->addGroupsInfo($workspace));
}
/**
- * @NoAdminRequired
* @param string|array $workspace
*/
+ #[NoAdminRequired]
public function addUsersInfo(string|array $workspace): JSONResponse {
if (gettype($workspace) === 'string') {
$workspace = json_decode($workspace, true);
@@ -236,12 +238,12 @@ public function addUsersInfo(string|array $workspace): JSONResponse {
/**
* Returns a list of users whose name matches $term
*
- * @NoAdminRequired
* @param string $term
* @param string $spaceId
* @param string|array $space
*
*/
+ #[NoAdminRequired]
public function lookupUsers(string $term,
string $spaceId,
string|array $space): JSONResponse {
@@ -256,13 +258,13 @@ public function lookupUsers(string $term,
*
* Change a user's role in a workspace
*
- * @NoAdminRequired
- * @SpaceAdminRequired
*
* @param array|string $space
* @param string $userId
*
*/
+ #[NoAdminRequired]
+ #[SpaceAdminRequired]
public function changeUserRole(array|string $space,
string $userId): JSONResponse {
if (gettype($space) === 'string') {
@@ -289,13 +291,13 @@ public function changeUserRole(array|string $space,
/**
*
- * @NoAdminRequired
- * @SpaceAdminRequired
* @param array|string $workspace
* @param string $newSpaceName
*
* @todo Manage errors
*/
+ #[NoAdminRequired]
+ #[SpaceAdminRequired]
public function renameSpace(array|string $workspace,
string $newSpaceName): JSONResponse {
if (gettype($workspace) === 'string') {
diff --git a/lib/Middleware/Attribute/GeneralManagerRequired.php b/lib/Middleware/Attribute/GeneralManagerRequired.php
new file mode 100644
index 000000000..53f8af0a2
--- /dev/null
+++ b/lib/Middleware/Attribute/GeneralManagerRequired.php
@@ -0,0 +1,29 @@
+
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+namespace OCA\Workspace\Middleware\Attribute;
+
+use Attribute;
+
+#[Attribute(Attribute::TARGET_METHOD)]
+class GeneralManagerRequired {
+}
diff --git a/lib/Middleware/Attribute/SapceAdminRequired.php b/lib/Middleware/Attribute/SapceAdminRequired.php
new file mode 100644
index 000000000..22674d409
--- /dev/null
+++ b/lib/Middleware/Attribute/SapceAdminRequired.php
@@ -0,0 +1,29 @@
+
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+namespace OCA\Workspace\Middleware\Attribute;
+
+use Attribute;
+
+#[Attribute(Attribute::TARGET_METHOD)]
+class SpaceAdminRequired {
+}
diff --git a/lib/Middleware/IsGeneralManagerMiddleware.php b/lib/Middleware/IsGeneralManagerMiddleware.php
index 346899770..22e18b4d6 100644
--- a/lib/Middleware/IsGeneralManagerMiddleware.php
+++ b/lib/Middleware/IsGeneralManagerMiddleware.php
@@ -26,24 +26,24 @@
namespace OCA\Workspace\Middleware;
use Exception;
+use OCA\Workspace\Middleware\Attribute\GeneralManagerRequired;
use OCA\Workspace\Middleware\Exceptions\AccessDeniedException;
use OCA\Workspace\Service\UserService;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Middleware;
-use OCP\AppFramework\Utility\IControllerMethodReflector;
-use OCP\IRequest;
class IsGeneralManagerMiddleware extends Middleware {
+
public function __construct(
- private IControllerMethodReflector $reflector,
- private IRequest $request,
private UserService $userService
) {
}
public function beforeController($controller, $methodName): void {
- if ($this->reflector->hasAnnotation('GeneralManagerRequired')) {
+ $reflectionMethod = new \ReflectionMethod($controller, $methodName);
+ $hasAttribute = !empty($reflectionMethod->getAttributes(GeneralManagerRequired::class));
+ if ($hasAttribute) {
if (!$this->userService->isUserGeneralAdmin()) {
throw new AccessDeniedException();
}
@@ -59,5 +59,14 @@ public function afterException($controller, $methodName, Exception $exception):
'msg' => 'You are not allowed to perform this action'
], Http::STATUS_FORBIDDEN);
}
+
+ return new JSONResponse([
+ 'message' => 'Impossible to catch the exception from the ' . $this::class,
+ 'exception' => [
+ 'class' => $exception::class,
+ 'message' => $exception->getMessage(),
+ 'trace' => $exception->getTrace()
+ ]
+ ]);
}
}
diff --git a/lib/Middleware/IsSpaceAdminMiddleware.php b/lib/Middleware/IsSpaceAdminMiddleware.php
index 269a04068..0d78e39c1 100644
--- a/lib/Middleware/IsSpaceAdminMiddleware.php
+++ b/lib/Middleware/IsSpaceAdminMiddleware.php
@@ -25,18 +25,18 @@
namespace OCA\Workspace\Middleware;
+use OCA\Workspace\Middleware\Attribute\SpaceAdminRequired;
use OCA\Workspace\Middleware\Exceptions\AccessDeniedException;
use OCA\Workspace\Service\SpaceService;
use OCA\Workspace\Service\UserService;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Middleware;
-use OCP\AppFramework\Utility\IControllerMethodReflector;
use OCP\IRequest;
class IsSpaceAdminMiddleware extends Middleware {
+
public function __construct(
- private IControllerMethodReflector $reflector,
private IRequest $request,
private UserService $userService,
private SpaceService $spaceService
@@ -44,7 +44,9 @@ public function __construct(
}
public function beforeController($controller, $methodName): void {
- if ($this->reflector->hasAnnotation('SpaceAdminRequired')) {
+ $reflectionMethod = new \ReflectionMethod($controller, $methodName);
+ $hasAttribute = !empty($reflectionMethod->getAttributes(SpaceAdminRequired::class));
+ if ($hasAttribute) {
$spaceId = $this->request->getParam('spaceId');
$space = $this->spaceService->find($spaceId);
if (!$this->userService->isSpaceManagerOfSpace($space->jsonSerialize()) && !$this->userService->isUserGeneralAdmin()) {
@@ -61,6 +63,13 @@ public function afterException($controller, $methodName, \Exception $exception):
], Http::STATUS_FORBIDDEN);
}
- return new JSONResponse([]);
+ return new JSONResponse([
+ 'message' => 'Impossible to catch the exception from the ' . $this::class,
+ 'exception' => [
+ 'class' => $exception::class,
+ 'message' => $exception->getMessage(),
+ 'trace' => $exception->getTrace()
+ ]
+ ]);
}
}