Added GET /domains/{domainId}

This commit is contained in:
Lukas Metzger 2018-03-24 16:37:35 +01:00
parent 29aa6e87f8
commit f4b06ae910
8 changed files with 172 additions and 15 deletions

View file

@ -96,7 +96,30 @@ class Domains
$this->logger->info('Deleted domain', ['id' => $domainId]);
return $res->withStatus(204);
} catch (\Exceptions\NotFoundException $e) {
return $res->withJson(['error' => 'No domain found for id ' + $domainId], 404);
return $res->withJson(['error' => 'No domain found for id ' . $domainId], 404);
}
}
public function getSingle(Request $req, Response $res, array $args)
{
$userId = $req->getAttribute('userId');
$domainId = intval($args['domainId']);
$ac = new \Operations\AccessControl($this->c);
if (!$ac->canAccessDomain($userId, $domainId)) {
$this->logger->info('Non admin user tries to get domain without permission.');
return $res->withJson(['error' => 'You have no permissions for this domain.'], 403);
}
$domains = new \Operations\Domains($this->c);
try {
$result = $domains->getDomain($domainId);
$this->logger->debug('Get domain info', ['id' => $domainId]);
return $res->withJson($result, 200);
} catch (\Exceptions\NotFoundException $e) {
return $res->withJson(['error' => 'No domain found for id ' . $domainId], 404);
}
}
}

View file

@ -43,4 +43,32 @@ class AccessControl
return $record['type'] == 'admin';
}
/**
* Check if a given user has permissons for a given domain.
*
* @param $userId User id of the user
* @param $domainId Domain to check
*
* @return bool true if access is granted, false otherwise
*/
public function canAccessDomain(int $userId, int $domainId) : bool
{
if ($this->isAdmin($userId)) {
return true;
}
$query = $this->db->prepare('SELECT user_id,domain_id FROM permissions WHERE user_id=:userId AND domain_id=:domainId');
$query->bindValue(':userId', $userId, \PDO::PARAM_INT);
$query->bindValue(':domainId', $domainId, \PDO::PARAM_INT);
$query->execute();
$record = $query->fetch();
if ($record === false) {
return false;
} else {
return true;
}
}
}

View file

@ -162,7 +162,7 @@ class Domains
}
/**
* Add new domain
* Delete domain
*
* @param $id Id of the domain to delete
*
@ -187,4 +187,39 @@ class Domains
$query->bindValue(':id', $id, \PDO::PARAM_INT);
$query->execute();
}
/**
* Get domain
*
* @param $id Id of the domain to get
*
* @return array Domain data
*
* @throws NotFoundException if domain does not exist
*/
public function getDomain(int $id) : array
{
$query = $this->db->prepare('
SELECT D.id,D.name,D.type,D.master,COUNT(R.domain_id) AS records FROM domains D
LEFT OUTER JOIN records R ON D.id = R.domain_id
WHERE D.id=:id
GROUP BY D.id,D.name,D.type,D.master
');
$query->bindValue(':id', $id, \PDO::PARAM_INT);
$query->execute();
$record = $query->fetch();
if ($record === false) {
throw new \Exceptions\NotFoundException();
}
$record['id'] = intval($record['id']);
$record['records'] = intval($record['records']);
if ($record['type'] !== 'SLAVE') {
unset($record['master']);
}
return $record;
}
}

View file

@ -30,6 +30,7 @@ $app->group('/v1', function () {
$this->get('/domains', '\Controllers\Domains:getList');
$this->post('/domains', '\Controllers\Domains:postNew');
$this->delete('/domains/{domainId}', '\Controllers\Domains:delete');
$this->get('/domains/{domainId}', '\Controllers\Domains:getSingle');
})->add('\Middlewares\Authentication');
});

View file

@ -37,7 +37,10 @@ async function runTest(user, f) {
process.exit(1);
}
}
}
async function run(f) {
await f();
process.exit(0);
}
@ -69,4 +72,5 @@ async function logOut(assert, req, token) {
assert.equal(res.status, 204, 'LOGOUT: Answer should be successfull but empty');
}
module.exports = runTest;
module.exports = runTest;
module.exports.run = run;

View file

@ -1,7 +1,7 @@
const cartesianProduct = require('cartesian-product');
const test = require('../testlib');
(async function () {
await require('../testlib')('admin', async function (assert, req) {
test.run(async function () {
await test('admin', async function (assert, req) {
//Test missing fields
var res = await req({
url: '/domains',
@ -88,6 +88,49 @@ const cartesianProduct = require('cartesian-product');
master: '1.2.3.4'
}, 'Creation result fail.')
//Get master domain
var res = await req({
url: '/domains/6',
method: 'get'
});
assert.equal(res.status, 200, 'Domain access for master domain should be OK.');
assert.equal(res.data, {
id: 6,
name: 'master.de',
type: 'MASTER',
records: 0
}, 'Master domain data mismatch');
//Get native domain
var res = await req({
url: '/domains/7',
method: 'get'
});
assert.equal(res.status, 200, 'Domain access for native domain should be OK.');
assert.equal(res.data, {
id: 7,
name: 'native.de',
type: 'NATIVE',
records: 0
}, 'Native domain data mismatch');
//Get slave domain
var res = await req({
url: '/domains/8',
method: 'get'
});
assert.equal(res.status, 200, 'Domain access for slave domain should be OK.');
assert.equal(res.data, {
id: 8,
name: 'slave.de',
type: 'SLAVE',
records: 0,
master: '1.2.3.4'
}, 'Slave domain data mismatch');
//Delete not existing domain
var res = await req({
url: '/domains/100',
@ -105,7 +148,7 @@ const cartesianProduct = require('cartesian-product');
assert.equal(res.status, 204, 'Deletion of domain 1 should be successfull.');
});
await require('../testlib')('user', async function (assert, req) {
await test('user', async function (assert, req) {
//Test insufficient privileges for add
var res = await req({
url: '/domains',
@ -124,6 +167,27 @@ const cartesianProduct = require('cartesian-product');
});
assert.equal(res.status, 403, 'Domain deletion should be forbidden for users.');
});
})();
//Test insufficient privileges for get
var res = await req({
url: '/domains/3',
method: 'get'
});
assert.equal(res.status, 403, 'Domain get for domain 3 should be forbidden.');
//Test privileges for get
var res = await req({
url: '/domains/1',
method: 'get'
});
assert.equal(res.status, 200, 'Domain access for domain 1 should be OK.');
assert.equal(res.data, {
id: 1,
name: 'example.com',
type: 'MASTER',
records: 1
}, 'Domain 3 data mismatch');
});
});

View file

@ -1,7 +1,8 @@
const test = require('../testlib');
const cartesianProduct = require('cartesian-product');
(async function () {
require('../testlib')('admin', async function (assert, req) {
test.run(async function () {
test('admin', async function (assert, req) {
//GET /domains?page=5&pagesize=10&query=foo&sort=id-asc,name-desc,type-asc,records-asc&type=MASTER
//Test sorting in all combinations
@ -105,4 +106,4 @@ const cartesianProduct = require('cartesian-product');
}
], 'Result fail for ' + res.config.url);
});
})();
});

View file

@ -1,6 +1,7 @@
const test = require('../testlib');
(async function () {
require('../testlib')('admin', async function (assert, req) {
test.run(async function () {
test('admin', async function (assert, req) {
//Try to login with invalid username and password
var res = await req({
url: '/sessions',
@ -60,4 +61,4 @@
assert.equal(res.status, 201, 'Status not valid');
});
})();
});