diff --git a/backend/src/controllers/Credentials.php b/backend/src/controllers/Credentials.php index 74bb014..d4ad9c6 100644 --- a/backend/src/controllers/Credentials.php +++ b/backend/src/controllers/Credentials.php @@ -81,4 +81,28 @@ class Credentials return $res->withJson(['error' => 'The provided key is invalid.'], 400); } } + + public function delete(Request $req, Response $res, array $args) + { + $userId = $req->getAttribute('userId'); + $recordId = intval($args['recordId']); + $credentialId = intval($args['credentialId']); + + $ac = new \Operations\AccessControl($this->c); + if (!$ac->canAccessRecord($userId, $recordId)) { + $this->logger->info('User tries to delete credential without permissions.'); + return $res->withJson(['error' => 'You have no permission for this record'], 403); + } + + $credentials = new \Operations\Credentials($this->c); + + try { + $credentials->deleteCredential($recordId, $credentialId); + + $this->logger->info('Deleted credential', ['id' => $credentialId]); + return $res->withStatus(204); + } catch (\Exceptions\NotFoundException $e) { + return $res->withJson(['error' => 'No credential found for id ' . $credentialId], 404); + } + } } diff --git a/backend/src/operations/Credentials.php b/backend/src/operations/Credentials.php index 710ab0a..2f5073d 100644 --- a/backend/src/operations/Credentials.php +++ b/backend/src/operations/Credentials.php @@ -111,6 +111,39 @@ class Credentials unset($record['security']); } + $this->db->commit(); + return $record; } + + /** + * Delete credential + * + * @param $recordId Id of the record + * @param $credentialId Id of the credential to delete + * + * @return void + * + * @throws NotFoundException if credential does not exist + */ + public function deleteCredential(int $recordId, int $credentialId) : void + { + $this->db->beginTransaction(); + + $query = $this->db->prepare('SELECT id FROM remote WHERE id=:id AND record=:record'); + $query->bindValue(':id', $credentialId, \PDO::PARAM_INT); + $query->bindValue(':record', $recordId, \PDO::PARAM_INT); + $query->execute(); + + if ($query->fetch() === false) { //Credential does not exist + $this->db->rollBack(); + throw new \Exceptions\NotFoundException(); + } + + $query = $this->db->prepare('DELETE FROM remote WHERE id=:id'); + $query->bindValue(':id', $id, \PDO::PARAM_INT); + $query->execute(); + + $this->db->commit(); + } } diff --git a/backend/src/operations/Domains.php b/backend/src/operations/Domains.php index 81c0330..6306e48 100644 --- a/backend/src/operations/Domains.php +++ b/backend/src/operations/Domains.php @@ -194,6 +194,8 @@ class Domains $query = $this->db->prepare('DELETE FROM records WHERE domain_id=:id'); $query->bindValue(':id', $id, \PDO::PARAM_INT); $query->execute(); + + $this->db->commit(); } /** diff --git a/backend/src/operations/Records.php b/backend/src/operations/Records.php index e82540a..5e07fef 100644 --- a/backend/src/operations/Records.php +++ b/backend/src/operations/Records.php @@ -214,6 +214,8 @@ class Records $query = $this->db->prepare('DELETE FROM records WHERE id=:id'); $query->bindValue(':id', $id, \PDO::PARAM_INT); $query->execute(); + + $this->db->commit(); } /** diff --git a/backend/src/public/index.php b/backend/src/public/index.php index 1c79f4a..e6e65a1 100644 --- a/backend/src/public/index.php +++ b/backend/src/public/index.php @@ -44,6 +44,7 @@ $app->group('/v1', function () { $this->get('/records/{recordId}/credentials', '\Controllers\Credentials:getList'); $this->post('/records/{recordId}/credentials', '\Controllers\Credentials:postNew'); + $this->delete('/records/{recordId}/credentials/{credentialId}', '\Controllers\Credentials:delete'); })->add('\Middlewares\Authentication'); }); diff --git a/backend/test/tests/credentials-crud.js b/backend/test/tests/credentials-crud.js index b29a0cd..002a349 100644 --- a/backend/test/tests/credentials-crud.js +++ b/backend/test/tests/credentials-crud.js @@ -99,6 +99,29 @@ test.run(async function () { type: 'password', }, 'Adding credential data fail.'); + //Delete entry + var res = await req({ + url: '/records/1/credentials/4', + method: 'delete' + }); + + assert.equal(res.status, 204, 'Deletion of entry should succeed.'); + + //Delete not existing entry + var res = await req({ + url: '/records/1/credentials/100', + method: 'delete' + }); + + assert.equal(res.status, 404, 'Deletion of not existing entry should fail.'); + + //Delete entry via wrong record + var res = await req({ + url: '/records/4/credentials/5', + method: 'delete' + }); + + assert.equal(res.status, 404, 'Deletion of entry via wrong record should fail.'); }); @@ -133,5 +156,21 @@ test.run(async function () { description: 'Test Password', type: 'password', }, 'Adding credential data fail.'); + + //Delete entry + var res = await req({ + url: '/records/1/credentials/6', + method: 'delete' + }); + + assert.equal(res.status, 204, 'Deletion of entry should succeed for user.'); + + //Delete entry without permission + var res = await req({ + url: '/records/4/credentials/2', + method: 'delete' + }); + + assert.equal(res.status, 403, 'Deletion of entry without permission should fail.'); }); }); \ No newline at end of file diff --git a/backend/test/tests/domains-crud.js b/backend/test/tests/domains-crud.js index a01f75f..b1e3576 100644 --- a/backend/test/tests/domains-crud.js +++ b/backend/test/tests/domains-crud.js @@ -205,11 +205,11 @@ test.run(async function () { //Delete existing domain var res = await req({ - url: '/domains/1', + url: '/domains/8', method: 'delete' }); - assert.equal(res.status, 204, 'Deletion of domain 1 should be successfull.'); + assert.equal(res.status, 204, 'Deletion of domain 8 should be successfull.'); }); await test('user', async function (assert, req) {