From 22334174dab8330bb45d0604505f16a4fe68d1a9 Mon Sep 17 00:00:00 2001 From: Lukas Metzger Date: Sat, 31 Mar 2018 17:13:47 +0200 Subject: [PATCH] Added GET /records/{recordId}/credentials/{credentialId} --- backend/src/controllers/Credentials.php | 24 +++++++++++++++++ backend/src/operations/Credentials.php | 35 +++++++++++++++++++++++++ backend/src/public/index.php | 1 + backend/test/tests/credentials-crud.js | 29 ++++++++++++++++++-- 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/backend/src/controllers/Credentials.php b/backend/src/controllers/Credentials.php index d4ad9c6..73b99bf 100644 --- a/backend/src/controllers/Credentials.php +++ b/backend/src/controllers/Credentials.php @@ -105,4 +105,28 @@ class Credentials return $res->withJson(['error' => 'No credential found for id ' . $credentialId], 404); } } + + public function getSingle(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('Non admin user tries to get credential without permission.'); + return $res->withJson(['error' => 'You have no permissions for this record.'], 403); + } + + $credentials = new \Operations\Credentials($this->c); + + try { + $result = $credentials->getCredential($recordId, $credentialId); + $this->logger->debug('Get credential info', ['id' => $credentialId]); + return $res->withJson($result, 200); + } catch (\Exceptions\NotFoundException $e) { + $this->logger->debug('Credential info not found', ['id' => $credentialId, 'record' => $recordId]); + return $res->withJson(['error' => 'No matching credential found.'], 404); + } + } } diff --git a/backend/src/operations/Credentials.php b/backend/src/operations/Credentials.php index 2f5073d..a306a02 100644 --- a/backend/src/operations/Credentials.php +++ b/backend/src/operations/Credentials.php @@ -146,4 +146,39 @@ class Credentials $this->db->commit(); } + + /** + * Get record + * + * @param $recordId Id of the record + * @param $credentialId Id of the credential + * + * @return array Credential entry + * + * @throws NotFoundException if the credential does not exist + */ + public function getCredential(int $recordId, int $credentialId) : array + { + $query = $this->db->prepare('SELECT id,description,type,security FROM remote + WHERE id=:credential AND record=:record'); + $query->bindValue(':credential', $credentialId, \PDO::PARAM_INT); + $query->bindValue(':record', $recordId, \PDO::PARAM_INT); + $query->execute(); + + $record = $query->fetch(); + + if ($record === false) { + throw new \Exceptions\NotFoundException(); + } + + $record['id'] = intval($record['id']); + if ($record['type'] === 'key') { + $record['key'] = $record['security']; + unset($record['security']); + } else { + unset($record['security']); + } + + return $record; + } } diff --git a/backend/src/public/index.php b/backend/src/public/index.php index e6e65a1..b561a47 100644 --- a/backend/src/public/index.php +++ b/backend/src/public/index.php @@ -45,6 +45,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'); + $this->get('/records/{recordId}/credentials/{credentialId}', '\Controllers\Credentials:getSingle'); })->add('\Middlewares\Authentication'); }); diff --git a/backend/test/tests/credentials-crud.js b/backend/test/tests/credentials-crud.js index 002a349..7b4585f 100644 --- a/backend/test/tests/credentials-crud.js +++ b/backend/test/tests/credentials-crud.js @@ -62,7 +62,7 @@ test.run(async function () { assert.equal(res.status, 400); - //Add key (key is intensionally very short but valid) + //Add key (key is intensionally very short but valid) and get it var res = await req({ url: '/records/1/credentials', method: 'post', @@ -81,7 +81,20 @@ test.run(async function () { key: '-----BEGIN PUBLIC KEY-----\nMDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMOLSxmtlYxSkEKep11gjq200PTKVUaA\nyalonAKxw3XnAgMBAAE=\n-----END PUBLIC KEY-----' }, 'Adding credential data fail.'); - //Add password + var res = await req({ + url: '/records/1/credentials/4', + method: 'get' + }); + + assert.equal(res.status, 200, 'Added key should be found.'); + assert.equal(res.data, { + id: 4, + description: 'Test Key', + type: 'key', + key: '-----BEGIN PUBLIC KEY-----\nMDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMOLSxmtlYxSkEKep11gjq200PTKVUaA\nyalonAKxw3XnAgMBAAE=\n-----END PUBLIC KEY-----' + }, 'Added key does not match.'); + + //Add password and get it var res = await req({ url: '/records/1/credentials', method: 'post', @@ -99,6 +112,18 @@ test.run(async function () { type: 'password', }, 'Adding credential data fail.'); + var res = await req({ + url: '/records/1/credentials/5', + method: 'get' + }); + + assert.equal(res.status, 200, 'Added key should be found.'); + assert.equal(res.data, { + id: 5, + description: 'Test Password', + type: 'password', + }, 'Added password does not match.'); + //Delete entry var res = await req({ url: '/records/1/credentials/4',