Skip to content

Commit c739a73

Browse files
authored
add zone routes and tests (#32)
* dnskey: fix test case * test.sh: constrain test runner, so that it doesn't try running ./test.js * rename test.js -> test-fixtures.js * add zone routes and tests
1 parent b38c5bf commit c739a73

10 files changed

Lines changed: 299 additions & 14 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ and if we peek inside the cookie jar:
121121

122122
We can see that our session cookie has been saved. Now we can make other requests to the API using that session cookie:
123123

124-
```
125-
curl -b nt-session -X GET http://localhost:3000/user/4096 --header "Content-Type: application/json" | json_pp
124+
```sh
125+
curl -b nt-session -X GET http://localhost:3000/user/4096 --header "Content-Type: application/json" | json_pp
126126
{
127127
"group" : {
128128
"id" : 4096

lib/test/rrs/dnskey.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"id": 4096,
33
"zid": 4096,
4-
"owner": "mail.example.com.",
4+
"owner": "example.com.",
55
"ttl": 86400,
6-
"type": "CERT",
7-
"cert type": "PGP",
8-
"key tag": 0,
9-
"algorithm": 0,
10-
"certificate": "hexidecimalkeystring1"
6+
"type": "DNSKEY",
7+
"flags": 256,
8+
"protocol": 3,
9+
"algorithm": 5,
10+
"publickey": "( AQPSKmynfzW4kyBv015MUG2DeIQ3 Cbl+BBZH4b/0PY1kxkmvHjcZc8no kfzj31GajIQKY+5CptLr3buXA10h WqTkF7H6RfoRqXQeogmMHfpftf6z Mv1LyBUgia7za6ZEzOJBOztyvhjL 742iU/TpPSEDhm2SNKLijfUppn1U aNvv4w== )"
1111
}

lib/zone_record.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ function unApplyMap(obj, map) {
215215
}
216216
}
217217

218+
// map of NicTool 2.0 fields to RR field names
218219
function getMap(rrType) {
219220
switch (rrType) {
220221
case 'CAA':
@@ -236,7 +237,7 @@ function getMap(rrType) {
236237
return { address: 'target' }
237238
case 'DNSKEY':
238239
return {
239-
address: 'public key',
240+
address: 'publickey',
240241
weight: 'flags',
241242
priority: 'protocol',
242243
other: 'algorithm',

routes/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { User, UserRoutes } from './user.js'
2121
import { Session, SessionRoutes } from './session.js'
2222
import { PermissionRoutes } from './permission.js'
2323
import { NameserverRoutes } from './nameserver.js'
24+
import { ZoneRoutes } from './zone.js'
2425

2526
let server
2627

@@ -86,6 +87,7 @@ async function setup() {
8687
SessionRoutes(server)
8788
PermissionRoutes(server)
8889
NameserverRoutes(server)
90+
ZoneRoutes(server)
8991

9092
server.route({
9193
method: '*',

routes/test/zone.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"id": 4095,
3+
"gid": 4095,
4+
"zone": "route.example.com",
5+
"mailaddr": "route-master.example.com.",
6+
"description": "route test",
7+
"serial": 20240306,
8+
"refresh": 2,
9+
"retry": 3,
10+
"expire": 4,
11+
"minimum": 5,
12+
"ttl": 3601,
13+
"location": "",
14+
"last_publish": null
15+
}

routes/user.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ describe('user routes', () => {
107107
assert.equal(res.statusCode, 200)
108108
})
109109

110-
it(`GET /user/${userId2}`, async () => {
110+
it(`GET /user/${userId2} (deleted)`, async () => {
111111
const res = await server.inject({
112112
method: 'GET',
113113
url: `/user/${userId2}`,

routes/zone.js

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import validate from '@nictool/validate'
2+
3+
import Zone from '../lib/zone.js'
4+
import { meta } from '../lib/util.js'
5+
6+
function ZoneRoutes(server) {
7+
server.route([
8+
{
9+
method: 'GET',
10+
path: '/zone/{id}',
11+
options: {
12+
validate: {
13+
query: validate.zone.GET_req,
14+
},
15+
response: {
16+
schema: validate.zone.GET_res,
17+
},
18+
tags: ['api'],
19+
},
20+
handler: async (request, h) => {
21+
const getArgs = {
22+
deleted: request.query.deleted === true ? 1 : 0,
23+
id: parseInt(request.params.id, 10),
24+
}
25+
26+
const zones = await Zone.get(getArgs)
27+
28+
return h
29+
.response({
30+
zone: zones[0],
31+
meta: {
32+
api: meta.api,
33+
msg: `here's your zone`,
34+
},
35+
})
36+
.code(200)
37+
},
38+
},
39+
{
40+
method: 'POST',
41+
path: '/zone',
42+
options: {
43+
validate: {
44+
payload: validate.zone.POST,
45+
},
46+
response: {
47+
schema: validate.zone.GET_res,
48+
},
49+
tags: ['api'],
50+
},
51+
handler: async (request, h) => {
52+
const id = await Zone.create(request.payload)
53+
54+
const zones = await Zone.get({ id })
55+
56+
return h
57+
.response({
58+
zone: zones[0],
59+
meta: {
60+
api: meta.api,
61+
msg: `the zone was created`,
62+
},
63+
})
64+
.code(201)
65+
},
66+
},
67+
{
68+
method: 'DELETE',
69+
path: '/zone/{id}',
70+
options: {
71+
validate: {
72+
query: validate.zone.DELETE,
73+
},
74+
response: {
75+
schema: validate.zone.GET_res,
76+
},
77+
tags: ['api'],
78+
},
79+
handler: async (request, h) => {
80+
const zones = await Zone.get({
81+
deleted: request.query.deleted === true ? 1 : 0,
82+
id: parseInt(request.params.id, 10),
83+
})
84+
85+
if (zones.length === 0) {
86+
return h
87+
.response({
88+
meta: {
89+
api: meta.api,
90+
msg: `I couldn't find that zone`,
91+
},
92+
})
93+
.code(404)
94+
}
95+
96+
await Zone.delete({
97+
id: zones[0].id,
98+
deleted: 1,
99+
})
100+
101+
return h
102+
.response({
103+
zone: zones[0],
104+
meta: {
105+
api: meta.api,
106+
msg: `I deleted that zone`,
107+
},
108+
})
109+
.code(200)
110+
},
111+
},
112+
])
113+
}
114+
115+
export default ZoneRoutes
116+
117+
export { Zone, ZoneRoutes }

routes/zone.test.js

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import assert from 'node:assert/strict'
2+
import { describe, it, before, after } from 'node:test'
3+
4+
import { init } from './index.js'
5+
import Group from '../lib/group.js'
6+
import User from '../lib/user.js'
7+
import Zone from '../lib/zone.js'
8+
9+
import groupCase from './test/group.json' with { type: 'json' }
10+
import userCase from './test/user.json' with { type: 'json' }
11+
import nsCase from './test/zone.json' with { type: 'json' }
12+
13+
let server
14+
let case2Id = 4094
15+
16+
before(async () => {
17+
await Zone.destroy({ id: case2Id })
18+
await Group.create(groupCase)
19+
await User.create(userCase)
20+
await Zone.create(nsCase)
21+
server = await init()
22+
})
23+
24+
after(async () => {
25+
// await Zone.destroy({ id: case2Id })
26+
server.stop()
27+
})
28+
29+
describe('zone routes', () => {
30+
let sessionCookie
31+
32+
it('POST /session establishes a session', async () => {
33+
const res = await server.inject({
34+
method: 'POST',
35+
url: '/session',
36+
payload: {
37+
username: `${userCase.username}@${groupCase.name}`,
38+
password: userCase.password,
39+
},
40+
})
41+
assert.ok(res.headers['set-cookie'][0])
42+
sessionCookie = res.headers['set-cookie'][0].split(';')[0]
43+
})
44+
45+
it(`GET /zone/${nsCase.id}`, async () => {
46+
const res = await server.inject({
47+
method: 'GET',
48+
url: `/zone/${nsCase.id}`,
49+
headers: {
50+
Cookie: sessionCookie,
51+
},
52+
})
53+
// console.log(res.result)
54+
assert.equal(res.statusCode, 200)
55+
assert.equal(res.result.zone.name, nsCase.name)
56+
})
57+
58+
it(`POST /zone (${case2Id})`, async () => {
59+
const testCase = JSON.parse(JSON.stringify(nsCase))
60+
testCase.id = case2Id // make it unique
61+
testCase.gid = case2Id
62+
testCase.zone = 'route2.example.com.'
63+
64+
const res = await server.inject({
65+
method: 'POST',
66+
url: '/zone',
67+
headers: {
68+
Cookie: sessionCookie,
69+
},
70+
payload: testCase,
71+
})
72+
// console.log(res.result)
73+
assert.equal(res.statusCode, 201)
74+
assert.ok(res.result.zone.gid)
75+
})
76+
77+
it(`GET /zone/${case2Id}`, async () => {
78+
const res = await server.inject({
79+
method: 'GET',
80+
url: `/zone/${case2Id}`,
81+
headers: {
82+
Cookie: sessionCookie,
83+
},
84+
})
85+
// console.log(res.result)
86+
assert.equal(res.statusCode, 200)
87+
assert.ok(res.result.zone.gid)
88+
})
89+
90+
it(`DELETE /zone/${case2Id}`, async () => {
91+
const res = await server.inject({
92+
method: 'DELETE',
93+
url: `/zone/${case2Id}`,
94+
headers: {
95+
Cookie: sessionCookie,
96+
},
97+
})
98+
// console.log(res.result)
99+
assert.equal(res.statusCode, 200)
100+
})
101+
102+
it(`DELETE /zone/${case2Id}`, async () => {
103+
const res = await server.inject({
104+
method: 'DELETE',
105+
url: `/zone/${case2Id}`,
106+
headers: {
107+
Cookie: sessionCookie,
108+
},
109+
})
110+
// console.log(res.result)
111+
assert.equal(res.statusCode, 404)
112+
})
113+
114+
it(`GET /zone/${case2Id}`, async () => {
115+
const res = await server.inject({
116+
method: 'GET',
117+
url: `/zone/${case2Id}`,
118+
headers: {
119+
Cookie: sessionCookie,
120+
},
121+
})
122+
// console.log(res.result)
123+
// assert.equal(res.statusCode, 200)
124+
assert.equal(res.result.zone, undefined)
125+
})
126+
127+
it(`GET /zone/${case2Id} (deleted)`, async () => {
128+
const res = await server.inject({
129+
method: 'GET',
130+
url: `/zone/${case2Id}?deleted=true`,
131+
headers: {
132+
Cookie: sessionCookie,
133+
},
134+
})
135+
// console.log(res.result)
136+
assert.equal(res.statusCode, 200)
137+
assert.equal(res?.result?.zone, undefined)
138+
})
139+
140+
it('DELETE /session', async () => {
141+
const res = await server.inject({
142+
method: 'DELETE',
143+
url: '/session',
144+
headers: {
145+
Cookie: sessionCookie,
146+
},
147+
})
148+
assert.equal(res.statusCode, 200)
149+
})
150+
})
File renamed without changes.

test.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
set -eu
44

55
NODE="node --no-warnings=ExperimentalWarning"
6-
$NODE test.js teardown
7-
$NODE test.js setup
6+
$NODE test-fixtures.js teardown
7+
$NODE test-fixtures.js setup
88

99
cleanup() {
1010
echo "cleaning DB objects"
11-
$NODE test.js teardown
11+
$NODE test-fixtures.js teardown
1212
}
1313

1414
trap cleanup EXIT 1 2 3 6
@@ -20,7 +20,7 @@ else
2020
# npm i --no-save node-test-github-reporter
2121
# $NODE --test --test-reporter=node-test-github-reporter
2222
# else
23-
$NODE --test --test-reporter=spec
23+
$NODE --test --test-reporter=spec lib/*.test.js routes/*.test.js
2424
# fi
2525
fi
2626

0 commit comments

Comments
 (0)