From 33c0d753de9b96359cca27119bc74a14baa65f7d Mon Sep 17 00:00:00 2001 From: "Jeffrey T. Palmer" Date: Tue, 5 Nov 2019 09:54:19 -0500 Subject: [PATCH] Prevent creation of duplicate export requests --- classes/DataWarehouse/Export/QueryHandler.php | 48 ++++++++++++++----- .../WarehouseExportControllerProvider.php | 18 ++++--- .../input/create-request.json | 11 +++++ .../input/delete-request.json | 12 ++--- 4 files changed, 64 insertions(+), 25 deletions(-) diff --git a/classes/DataWarehouse/Export/QueryHandler.php b/classes/DataWarehouse/Export/QueryHandler.php index 543ec786c6..649d201b2c 100644 --- a/classes/DataWarehouse/Export/QueryHandler.php +++ b/classes/DataWarehouse/Export/QueryHandler.php @@ -84,20 +84,44 @@ public function createRequestRecord( $endDate, $format ) { - $sql = "INSERT INTO batch_export_requests - (requested_datetime, user_id, realm, start_date, end_date, export_file_format) - VALUES - (NOW(), :user_id, :realm, :start_date, :end_date, :export_file_format)"; + try { + $this->dbh->beginTransaction(); - $params = array( - 'user_id' => $userId, - 'realm' => $realm, - 'start_date' => $startDate, - 'end_date' => $endDate, - 'export_file_format' => $format - ); + // Check for duplicate submitted or available requests for the user. + $duplicates = array_filter( + $this->listUserRequestsByState($userId), + function ($request) use ($realm, $startDate, $endDate, $format) { + return ($request['state'] == 'Submitted' || $request['state'] == 'Available') + && $realm == $request['realm'] + && $startDate == $request['start_date'] + && $endDate == $request['end_date'] + && $format == $request['export_file_format']; + } + ); + if (count($duplicates) > 0) { + throw new Exception('Cannot create duplicate request'); + } + + $sql = "INSERT INTO batch_export_requests + (requested_datetime, user_id, realm, start_date, end_date, export_file_format) + VALUES + (NOW(), :user_id, :realm, :start_date, :end_date, :export_file_format)"; - return $this->dbh->insert($sql, $params); + $params = array( + 'user_id' => $userId, + 'realm' => $realm, + 'start_date' => $startDate, + 'end_date' => $endDate, + 'export_file_format' => $format + ); + + $id = $this->dbh->insert($sql, $params); + $this->dbh->commit(); + return $id; + } catch (Exception $e) { + $this->dbh->rollBack(); + throw $e; + } } /** diff --git a/classes/Rest/Controllers/WarehouseExportControllerProvider.php b/classes/Rest/Controllers/WarehouseExportControllerProvider.php index 7a49d51430..9c0b079e55 100644 --- a/classes/Rest/Controllers/WarehouseExportControllerProvider.php +++ b/classes/Rest/Controllers/WarehouseExportControllerProvider.php @@ -166,13 +166,17 @@ function ($realm) { throw new BadRequestHttpException('format must be CSV or JSON'); } - $id = $this->queryHandler->createRequestRecord( - $user->getUserId(), - $realm, - $startDate->format('Y-m-d'), - $endDate->format('Y-m-d'), - $format - ); + try { + $id = $this->queryHandler->createRequestRecord( + $user->getUserId(), + $realm, + $startDate->format('Y-m-d'), + $endDate->format('Y-m-d'), + $format + ); + } catch (Exception $e) { + throw new BadRequestHttpException('Failed to create export request: ' . $e->getMessage()); + } return $app->json([ 'success' => true, diff --git a/tests/artifacts/xdmod/integration/rest/warehouse-export/input/create-request.json b/tests/artifacts/xdmod/integration/rest/warehouse-export/input/create-request.json index 6564af9e7e..6fbede2044 100644 --- a/tests/artifacts/xdmod/integration/rest/warehouse-export/input/create-request.json +++ b/tests/artifacts/xdmod/integration/rest/warehouse-export/input/create-request.json @@ -21,6 +21,17 @@ 200, "POST-request" ], + "Normal user (duplicate)": [ + "usr", + { + "realm": "jobs", + "start_date": "2017-02-01", + "end_date": "2017-02-28", + "format": "JSON" + }, + 400, + "error" + ], "PI": [ "pi", { diff --git a/tests/artifacts/xdmod/integration/rest/warehouse-export/input/delete-request.json b/tests/artifacts/xdmod/integration/rest/warehouse-export/input/delete-request.json index cc68732f07..f3cc63845b 100644 --- a/tests/artifacts/xdmod/integration/rest/warehouse-export/input/delete-request.json +++ b/tests/artifacts/xdmod/integration/rest/warehouse-export/input/delete-request.json @@ -3,8 +3,8 @@ "usr", { "realm": "jobs", - "start_date": "2018-01-01", - "end_date": "2018-12-31", + "start_date": "2018-02-01", + "end_date": "2018-02-28", "format": "CSV" }, 200, @@ -14,8 +14,8 @@ "pi", { "realm": "jobs", - "start_date": "2018-01-01", - "end_date": "2018-12-31", + "start_date": "2018-02-01", + "end_date": "2018-02-28", "format": "CSV" }, 200, @@ -25,8 +25,8 @@ "cd", { "realm": "jobs", - "start_date": "2018-01-01", - "end_date": "2018-12-31", + "start_date": "2018-02-01", + "end_date": "2018-02-28", "format": "CSV" }, 200,