Added /remote/changepw
This commit is contained in:
parent
d5e86f3583
commit
799ce1b371
6 changed files with 141 additions and 1 deletions
|
@ -27,4 +27,30 @@ class Remote
|
|||
'ip' => $req->getAttribute('clientIp')
|
||||
], 200);
|
||||
}
|
||||
|
||||
public function updatePassword(Request $req, Response $res, array $args)
|
||||
{
|
||||
$record = $req->getParam('record');
|
||||
$content = $req->getParam('content');
|
||||
$password = $req->getParam('password');
|
||||
|
||||
if ($record === null || $content === null || $password === null) {
|
||||
return $res->withJson(['error' => 'One of the required fields is missing.'], 422);
|
||||
}
|
||||
|
||||
$remote = new \Operations\Remote($this->c);
|
||||
|
||||
try {
|
||||
$remote->updatePassword(intval($record), $content, $password);
|
||||
} catch (\Exceptions\NotFoundException $e) {
|
||||
$this->logger->debug('User tried to update non existent record via changepw api.');
|
||||
return $res->withJson(['error' => 'The given record does not exist.'], 404);
|
||||
} catch (\Exceptions\ForbiddenException $e) {
|
||||
$this->logger->debug('User tried to update an record via changepw api with incorrect password.');
|
||||
return $res->withJson(['error' => 'The provided password was invalid.'], 403);
|
||||
}
|
||||
|
||||
$this->logger->info('Record ' . $record . ' was changed via the changepw api.');
|
||||
return $res->withStatus(204);
|
||||
}
|
||||
}
|
||||
|
|
9
backend/src/exceptions/ForbiddenException.php
Normal file
9
backend/src/exceptions/ForbiddenException.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Exceptions;
|
||||
|
||||
require '../vendor/autoload.php';
|
||||
|
||||
class ForbiddenException extends \Exception
|
||||
{
|
||||
}
|
68
backend/src/operations/Remote.php
Normal file
68
backend/src/operations/Remote.php
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace Operations;
|
||||
|
||||
require '../vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* This class provides functions for the remote api.
|
||||
*/
|
||||
class Remote
|
||||
{
|
||||
/** @var \Monolog\Logger */
|
||||
private $logger;
|
||||
|
||||
/** @var \PDO */
|
||||
private $db;
|
||||
|
||||
/** @var \Slim\Container */
|
||||
private $c;
|
||||
|
||||
public function __construct(\Slim\Container $c)
|
||||
{
|
||||
$this->logger = $c->logger;
|
||||
$this->db = $c->db;
|
||||
$this->c = $c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new record
|
||||
*
|
||||
* @param $record Name of the new record
|
||||
* @param $content Type of the new record
|
||||
* @param $password Content of the new record
|
||||
*
|
||||
* @throws NotFoundException if the record does not exist
|
||||
* @throws ForbiddenException if the password is not valid for the record
|
||||
*/
|
||||
public function updatePassword(int $record, string $content, string $password) : void
|
||||
{
|
||||
$query = $this->db->prepare('SELECT id FROM records WHERE id=:record');
|
||||
$query->bindValue(':record', $record, \PDO::PARAM_INT);
|
||||
$query->execute();
|
||||
|
||||
if ($query->fetch() === false) {
|
||||
throw new \Exceptions\NotFoundException();
|
||||
}
|
||||
|
||||
$query = $this->db->prepare('SELECT security FROM remote WHERE record=:record AND type=\'password\'');
|
||||
$query->bindValue(':record', $record, \PDO::PARAM_INT);
|
||||
$query->execute();
|
||||
|
||||
$validPwFound = false;
|
||||
|
||||
while ($row = $query->fetch()) {
|
||||
if (password_verify($password, $row['security'])) {
|
||||
$validPwFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$validPwFound) {
|
||||
throw new \Exceptions\ForbiddenException();
|
||||
}
|
||||
|
||||
$records = new \Operations\Records($this->c);
|
||||
$records->updateRecord($record, null, null, $content, null, null);
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ $app->group('/v1', function () {
|
|||
$this->post('/sessions', '\Controllers\Sessions:post');
|
||||
|
||||
$this->get('/remote/ip', '\Controllers\Remote:ip');
|
||||
$this->get('/remote/updatepw', '\Controllers\Remote:updatePassword');
|
||||
|
||||
$this->group('', function () {
|
||||
$this->delete('/sessions/{sessionId}', '\Controllers\Sessions:delete');
|
||||
|
|
|
@ -167,7 +167,7 @@ CREATE TABLE `remote` (
|
|||
--
|
||||
|
||||
INSERT INTO `remote` (`id`, `record`, `description`, `type`, `security`, `nonce`) VALUES
|
||||
(1, 1, 'Password Test', 'password', '$2y$10$5Gxh6yus9yi/FHpKD4k8Zez.OAhGZoa7JgwOWZ059/kDyBP3vI9aK', NULL),
|
||||
(1, 1, 'Password Test', 'password', '$2y$10$abocd6jj/Tw4jzDtqTnjreNzwcerzkXwoVc.JvZBoZ6p0grEKDWoW', NULL),
|
||||
(2, 4, 'Key Test', 'key', '-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5mu3aH90uSXY9sVLgVSz\nKj4FEctrpFDPyVC4ufbJa/44fuLABFe+IizgZUheNBBO7FjpLJYvsL24o6TEeht4\no5j0KHrRHXqp4WQuAL3ZREv/AhNaOC9/xyjoGwUkKkdC2bIfh0J/ACkezxvUrPsh\nbzhzY+co/M9PqlgTbjKjvlv/pRj2dSp98FzUme3HCh7Nn1EOM3yPMtaKNA9Qkkz1\noalfR3xmJjIanoS9zcK77/yyQ8VwI//CgxvnpnWbORZG0B9W2ZBoI8Bj4zprbbFG\nKNmrb403wfDijYF3MXpSMjKvJ5YVuZsn35EWIi5tqFc0oV7Ryy9nBHzKeoYN7Szs\nrXIS5+ZcQDLuN+pqJ7ByVaw4aVn85py8IdO0IYD5xeKd1i0iqm+KSoFTS1jiNSZu\n6iVl4odixWtW7oPLYBbd/vD2F7Ua5cLd12Rs+6kEVtlpnIf7txyFQL4QHYJxB7fI\ny+m70mfufVvKbFh/mHkhe+Arv71ERDMfAV3AD8++axLqYfU/LLFzanjwIBctAA9a\nj++G0lwl1adURwnBeq8+YrMU4/wg9efquKXLR40dU9nkMJOm5tPm+XHt4o3wio4X\n2FqnD57I7qJCWVc00HtpeWno5vHL+eJu0TdxjBuYXnQfwa1z9pWvGaoBtg7tyHgv\ng7YZJzF1MW5N9ZqnkdFJVEsCAwEAAQ==\n-----END PUBLIC KEY-----', NULL),
|
||||
(3, 1, 'Key Test 2', 'key', '-----BEGIN PUBLIC KEY-----\r\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5mu3aH90uSXY9sVLgVSz\r\nKj4FEctrpFDPyVC4ufbJa/44fuLABFe+IizgZUheNBBO7FjpLJYvsL24o6TEeht4\r\no5j0KHrRHXqp4WQuAL3ZREv/AhNaOC9/xyjoGwUkKkdC2bIfh0J/ACkezxvUrPsh\r\nbzhzY+co/M9PqlgTbjKjvlv/pRj2dSp98FzUme3HCh7Nn1EOM3yPMtaKNA9Qkkz1\r\noalfR3xmJjIanoS9zcK77/yyQ8VwI//CgxvnpnWbORZG0B9W2ZBoI8Bj4zprbbFG\r\nKNmrb403wfDijYF3MXpSMjKvJ5YVuZsn35EWIi5tqFc0oV7Ryy9nBHzKeoYN7Szs\r\nrXIS5+ZcQDLuN+pqJ7ByVaw4aVn85py8IdO0IYD5xeKd1i0iqm+KSoFTS1jiNSZu\r\n6iVl4odixWtW7oPLYBbd/vD2F7Ua5cLd12Rs+6kEVtlpnIf7txyFQL4QHYJxB7fI\r\ny+m70mfufVvKbFh/mHkhe+Arv71ERDMfAV3AD8++axLqYfU/LLFzanjwIBctAA9a\r\nj++G0lwl1adURwnBeq8+YrMU4/wg9efquKXLR40dU9nkMJOm5tPm+XHt4o3wio4X\r\n2FqnD57I7qJCWVc00HtpeWno5vHL+eJu0TdxjBuYXnQfwa1z9pWvGaoBtg7tyHgv\r\ng7YZJzF1MW5N9ZqnkdFJVEsCAwEAAQ==\r\n-----END PUBLIC KEY-----', NULL);
|
||||
|
||||
|
|
36
backend/test/tests/remote-changepw.js
Normal file
36
backend/test/tests/remote-changepw.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
const test = require('../testlib');
|
||||
|
||||
test.run(async function () {
|
||||
await test('admin', async function (assert, req) {
|
||||
// Test updating
|
||||
var res = await req({
|
||||
url: '/remote/updatepw?record=1&content=foobarbaz&password=test',
|
||||
method: 'get'
|
||||
});
|
||||
|
||||
assert.equal(res.status, 204);
|
||||
|
||||
var res = await req({
|
||||
url: '/records/1',
|
||||
method: 'get'
|
||||
});
|
||||
|
||||
assert.equal(res.data.content, 'foobarbaz', 'Updating should change content.');
|
||||
|
||||
// Test updating with invalid password
|
||||
var res = await req({
|
||||
url: '/remote/updatepw?record=1&content=foobarbaz&password=foo',
|
||||
method: 'get'
|
||||
});
|
||||
|
||||
assert.equal(res.status, 403);
|
||||
|
||||
// Test updating non existing record
|
||||
var res = await req({
|
||||
url: '/remote/updatepw?record=100&content=foobarbaz&password=foo',
|
||||
method: 'get'
|
||||
});
|
||||
|
||||
assert.equal(res.status, 404);
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue