Added POST /domains api
This commit is contained in:
parent
b38cf25a75
commit
5928203a0a
|
@ -13,17 +13,17 @@ class Domains
|
|||
private $logger;
|
||||
|
||||
/** @var \Slim\Container */
|
||||
private $container;
|
||||
private $c;
|
||||
|
||||
public function __construct(\Slim\Container $c)
|
||||
{
|
||||
$this->logger = $c->logger;
|
||||
$this->container = $c;
|
||||
$this->c = $c;
|
||||
}
|
||||
|
||||
public function getList(Request $req, Response $res, array $args)
|
||||
{
|
||||
$domains = new \Operations\Domains($this->container);
|
||||
$domains = new \Operations\Domains($this->c);
|
||||
|
||||
$paging = new \Utils\PagingInfo($req->getQueryParam('page'), $req->getQueryParam('pagesize'));
|
||||
$query = $req->getQueryParam('query');
|
||||
|
@ -39,4 +39,42 @@ class Domains
|
|||
'results' => $results
|
||||
], 200);
|
||||
}
|
||||
|
||||
public function postNew(Request $req, Response $res, array $args)
|
||||
{
|
||||
$ac = new \Operations\AccessControl($this->c);
|
||||
if (!$ac->isAdmin($req->getAttribute('userId'))) {
|
||||
$this->logger->info('Non admin user tries to add domain');
|
||||
return $res->withJson(['error' => 'You must be admin to use this feature'], 403);
|
||||
}
|
||||
|
||||
$body = $req->getParsedBody();
|
||||
|
||||
if (!array_key_exists('name', $body) ||
|
||||
!array_key_exists('type', $body) || ($body['type'] === 'SLAVE' && !array_key_exists('master', $body))) {
|
||||
$this->logger->debug('One of the required fields is missing');
|
||||
return $res->withJson(['error' => 'One of the required fields is missing'], 422);
|
||||
}
|
||||
|
||||
$name = $body['name'];
|
||||
$type = $body['type'];
|
||||
$master = isset($body['master']) ? $body['master'] : null;
|
||||
|
||||
if (!in_array($type, ['MASTER', 'NATIVE', 'SLAVE'])) {
|
||||
$this->logger->info('Invalid type for new domain', ['type' => $type]);
|
||||
return $res->withJson(['error' => 'Invalid type allowed are MASTER, NATIVE and SLAVE'], 422);
|
||||
}
|
||||
|
||||
$domains = new \Operations\Domains($this->c);
|
||||
|
||||
try {
|
||||
$result = $domains->addDomain($name, $type, $master);
|
||||
|
||||
$this->logger->debug('Domain was added', $result);
|
||||
return $res->withJson($result, 201);
|
||||
} catch (\Exceptions\AlreadyExistentException $e) {
|
||||
$this->logger->debug('Zone with name ' . $name . ' already exists.');
|
||||
return $res->withJson(['error' => 'Zone with name ' . $name . ' already exists.'], 409);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
9
backend/src/exceptions/AlreadyExistentException.php
Normal file
9
backend/src/exceptions/AlreadyExistentException.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Exceptions;
|
||||
|
||||
require '../vendor/autoload.php';
|
||||
|
||||
class AlreadyExistentException extends \Exception
|
||||
{
|
||||
}
|
|
@ -33,6 +33,8 @@ class Domains
|
|||
* @param $query Search query to search in the domain name, null for no filter
|
||||
* @param $sorting Sort string in format 'field-asc,field2-desc', null for default
|
||||
* @param $type Type to filter for, null for no filter
|
||||
*
|
||||
* @return array Array with matching domains
|
||||
*/
|
||||
public function getDomains(\Utils\PagingInfo &$pi, int $userId, ? string $query, ? string $sorting, ? string $type) : array
|
||||
{
|
||||
|
@ -104,4 +106,53 @@ class Domains
|
|||
return $item;
|
||||
}, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of domains according to filter criteria
|
||||
*
|
||||
* @param $name Name of the new zone
|
||||
* @param $type Type of the new zone
|
||||
* @param $master Master for slave zones, otherwise null
|
||||
*
|
||||
* @return array New domain entry
|
||||
*/
|
||||
public function addDomain(string $name, string $type, ? string $master)
|
||||
{
|
||||
$this->db->beginTransaction();
|
||||
|
||||
$query = $this->db->prepare('SELECT id FROM domains WHERE name=:name');
|
||||
$query->bindValue(':name', $name, \PDO::PARAM_STR);
|
||||
$query->execute();
|
||||
|
||||
$record = $query->fetch();
|
||||
|
||||
if ($record !== false) { // Domain already exists
|
||||
$this->db->rollBack();
|
||||
throw new \Exceptions\AlreadyExistentException();
|
||||
}
|
||||
|
||||
if ($type === 'SLAVE') {
|
||||
$query = $this->db->prepare('INSERT INTO domains (name, type, master) VALUES(:name, :type, :master)');
|
||||
$query->bindValue(':master', $master, \PDO::PARAM_STR);
|
||||
} else {
|
||||
$query = $this->db->prepare('INSERT INTO domains (name, type) VALUES(:name, :type)');
|
||||
}
|
||||
$query->bindValue(':name', $name, \PDO::PARAM_STR);
|
||||
$query->bindValue(':type', $type, \PDO::PARAM_STR);
|
||||
$query->execute();
|
||||
|
||||
|
||||
$query = $this->db->prepare('SELECT id,name,type,master FROM domains WHERE name=:name');
|
||||
$query->bindValue(':name', $name, \PDO::PARAM_STR);
|
||||
$query->execute();
|
||||
|
||||
$record = $query->fetch();
|
||||
if ($type !== 'SLAVE') {
|
||||
unset($record['master']);
|
||||
}
|
||||
|
||||
$this->db->commit();
|
||||
|
||||
return $record;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ $app->group('/v1', function () {
|
|||
$this->delete('/sessions/{sessionId}', '\Controllers\Sessions:delete');
|
||||
|
||||
$this->get('/domains', '\Controllers\Domains:getList');
|
||||
$this->post('/domains', '\Controllers\Domains:postNew');
|
||||
})->add('\Middlewares\Authentication');
|
||||
});
|
||||
|
||||
|
|
|
@ -175,10 +175,11 @@ CREATE TABLE `users` (
|
|||
|
||||
--
|
||||
-- Dumping data for table `users`
|
||||
--
|
||||
--$2y$10$MktCI4XcfD0FpIFSkxex6OVifnIw3Nqw6QJueWmjVte99wx6XGBoq
|
||||
|
||||
INSERT INTO `users` (`id`, `name`, `backend`, `type`, `password`) VALUES
|
||||
(1, 'admin', 'native', 'admin', '$2y$10$9iIDHWgjY0pEsz8pZLXPx.gkMNDxTMzb7U0Um5hUGjKmUUHWQNXcW');
|
||||
(1, 'admin', 'native', 'admin', '$2y$10$9iIDHWgjY0pEsz8pZLXPx.gkMNDxTMzb7U0Um5hUGjKmUUHWQNXcW'),
|
||||
(2, 'user', 'native', 'user', '$2y$10$MktCI4XcfD0FpIFSkxex6OVifnIw3Nqw6QJueWmjVte99wx6XGBoq');
|
||||
|
||||
--
|
||||
-- Indexes for dumped tables
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const assert = require('assert');
|
||||
const axios = require('axios');
|
||||
|
||||
async function runTest(f) {
|
||||
async function runTest(user, f) {
|
||||
const assertObj = {
|
||||
equal: assert.deepStrictEqual,
|
||||
true: assert.ok
|
||||
|
@ -13,7 +13,7 @@ async function runTest(f) {
|
|||
});
|
||||
|
||||
try {
|
||||
const token = await logIn(assertObj, requestObj);
|
||||
const token = await logIn(assertObj, requestObj, user);
|
||||
|
||||
requestObj = axios.create({
|
||||
baseURL: process.argv[2],
|
||||
|
@ -41,19 +41,19 @@ async function runTest(f) {
|
|||
process.exit(0);
|
||||
}
|
||||
|
||||
async function logIn(assert, req) {
|
||||
async function logIn(assert, req, username) {
|
||||
//Try to login with valid username and password
|
||||
var res = await req({
|
||||
url: '/sessions',
|
||||
method: 'post',
|
||||
data: {
|
||||
username: 'admin',
|
||||
password: 'admin'
|
||||
username: username,
|
||||
password: username
|
||||
}
|
||||
});
|
||||
|
||||
assert.equal(res.status, 201, 'LOGIN: Status not valid');
|
||||
assert.equal(res.data.username, 'admin', 'LOGIN: Username should be admin');
|
||||
assert.equal(res.data.username, username, 'LOGIN: Username should be ' + username);
|
||||
assert.equal(res.data.token.length, 86, 'LOGIN: Token length fail');
|
||||
|
||||
return res.data.token;
|
||||
|
|
100
backend/test/tests/domains-crud.js
Normal file
100
backend/test/tests/domains-crud.js
Normal file
|
@ -0,0 +1,100 @@
|
|||
const cartesianProduct = require('cartesian-product');
|
||||
|
||||
require('../testlib')('admin', async function (assert, req) {
|
||||
//Test missing fields
|
||||
var res = await req({
|
||||
url: '/domains',
|
||||
method: 'post',
|
||||
data: {
|
||||
name: 'abc.de'
|
||||
}
|
||||
});
|
||||
|
||||
assert.equal(res.status, 422, 'Missing type filed should trigger error.');
|
||||
|
||||
var res = await req({
|
||||
url: '/domains',
|
||||
method: 'post',
|
||||
data: {
|
||||
name: 'abc.de',
|
||||
type: 'SLAVE'
|
||||
}
|
||||
});
|
||||
|
||||
assert.equal(res.status, 422, 'Missing master field for SLAVE domain should trigger error.');
|
||||
|
||||
var res = await req({
|
||||
url: '/domains',
|
||||
method: 'post',
|
||||
data: {
|
||||
name: 'foo.de',
|
||||
type: 'MASTER'
|
||||
}
|
||||
});
|
||||
|
||||
assert.equal(res.status, 409, 'Existing domain should trigger error.');
|
||||
|
||||
//Test creation of master zone
|
||||
var res = await req({
|
||||
url: '/domains',
|
||||
method: 'post',
|
||||
data: {
|
||||
name: 'master.de',
|
||||
type: 'MASTER'
|
||||
}
|
||||
});
|
||||
|
||||
assert.equal(res.status, 201, 'Creation should be successfull');
|
||||
assert.equal(res.data, {
|
||||
id: '6',
|
||||
name: 'master.de',
|
||||
type: 'MASTER'
|
||||
}, 'Creation result fail.')
|
||||
|
||||
//Test creation of native zone
|
||||
var res = await req({
|
||||
url: '/domains',
|
||||
method: 'post',
|
||||
data: {
|
||||
name: 'native.de',
|
||||
type: 'NATIVE'
|
||||
}
|
||||
});
|
||||
|
||||
assert.equal(res.status, 201, 'Creation should be successfull');
|
||||
assert.equal(res.data, {
|
||||
id: '7',
|
||||
name: 'native.de',
|
||||
type: 'NATIVE'
|
||||
}, 'Creation result fail.')
|
||||
|
||||
//Test creation of slave zone
|
||||
var res = await req({
|
||||
url: '/domains',
|
||||
method: 'post',
|
||||
data: {
|
||||
name: 'slave.de',
|
||||
type: 'SLAVE'
|
||||
}
|
||||
});
|
||||
|
||||
assert.equal(res.status, 201, 'Creation should be successfull');
|
||||
assert.equal(res.data, {
|
||||
id: '8',
|
||||
name: 'slave.de',
|
||||
type: 'SLAVE'
|
||||
}, 'Creation result fail.')
|
||||
});
|
||||
|
||||
require('../testlib')('user', async function (assert, req) {
|
||||
//Test insufficient privileges
|
||||
var res = await req({
|
||||
url: '/domains',
|
||||
method: 'post',
|
||||
data: {
|
||||
name: 'foo.de'
|
||||
}
|
||||
});
|
||||
|
||||
assert.equal(res.status, 403, 'Domain creation should be forbidden for users.')
|
||||
});
|
|
@ -1,6 +1,6 @@
|
|||
const cartesianProduct = require('cartesian-product');
|
||||
|
||||
require('../testlib')(async function (assert, req) {
|
||||
require('../testlib')('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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
require('../testlib')(async function (assert, req) {
|
||||
require('../testlib')('admin', async function (assert, req) {
|
||||
//Try to login with invalid username and password
|
||||
var res = await req({
|
||||
url: '/sessions',
|
||||
|
|
Loading…
Reference in a new issue