Skip to content

Commit f990d3f

Browse files
committed
add access list clients to back-end
1 parent 9a7a216 commit f990d3f

File tree

5 files changed

+220
-21
lines changed

5 files changed

+220
-21
lines changed

backend/internal/access-list.js

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
const _ = require('lodash');
2-
const fs = require('fs');
3-
const batchflow = require('batchflow');
4-
const logger = require('../logger').access;
5-
const error = require('../lib/error');
6-
const accessListModel = require('../models/access_list');
7-
const accessListAuthModel = require('../models/access_list_auth');
8-
const proxyHostModel = require('../models/proxy_host');
9-
const internalAuditLog = require('./audit-log');
10-
const internalNginx = require('./nginx');
11-
const utils = require('../lib/utils');
1+
const _ = require('lodash');
2+
const fs = require('fs');
3+
const batchflow = require('batchflow');
4+
const logger = require('../logger').access;
5+
const error = require('../lib/error');
6+
const accessListModel = require('../models/access_list');
7+
const accessListAuthModel = require('../models/access_list_auth');
8+
const accessListClientModel = require('../models/access_list_client');
9+
const proxyHostModel = require('../models/proxy_host');
10+
const internalAuditLog = require('./audit-log');
11+
const internalNginx = require('./nginx');
12+
const utils = require('../lib/utils');
1213

1314
function omissions () {
1415
return ['is_deleted'];
@@ -35,8 +36,9 @@ const internalAccessList = {
3536
.then((row) => {
3637
data.id = row.id;
3738

38-
// Now add the items
3939
let promises = [];
40+
41+
// Now add the items
4042
data.items.map((item) => {
4143
promises.push(accessListAuthModel
4244
.query()
@@ -48,13 +50,27 @@ const internalAccessList = {
4850
);
4951
});
5052

53+
// Now add the clients
54+
if (typeof data.clients !== 'undefined' && data.clients) {
55+
data.clients.map((client) => {
56+
promises.push(accessListClientModel
57+
.query()
58+
.insert({
59+
access_list_id: row.id,
60+
address: client.address,
61+
directive: client.directive
62+
})
63+
);
64+
});
65+
}
66+
5167
return Promise.all(promises);
5268
})
5369
.then(() => {
5470
// re-fetch with expansions
5571
return internalAccessList.get(access, {
5672
id: data.id,
57-
expand: ['owner', 'items']
73+
expand: ['owner', 'items', 'clients']
5874
}, true /* <- skip masking */);
5975
})
6076
.then((row) => {
@@ -152,6 +168,37 @@ const internalAccessList = {
152168
}
153169
});
154170
}
171+
172+
// Check for clients and add/update/remove them
173+
if (typeof data.clients !== 'undefined' && data.clients) {
174+
let promises = [];
175+
176+
data.clients.map(function (client) {
177+
if (client.address) {
178+
promises.push(accessListAuthModel
179+
.query()
180+
.insert({
181+
access_list_id: data.id,
182+
address: client.address,
183+
directive: client.directive
184+
})
185+
);
186+
}
187+
});
188+
189+
let query = accessListClientModel
190+
.query()
191+
.delete()
192+
.where('access_list_id', data.id);
193+
194+
return query
195+
.then(() => {
196+
// Add new items
197+
if (promises.length) {
198+
return Promise.all(promises);
199+
}
200+
});
201+
}
155202
})
156203
.then(() => {
157204
// Add to audit log
@@ -166,7 +213,7 @@ const internalAccessList = {
166213
// re-fetch with expansions
167214
return internalAccessList.get(access, {
168215
id: data.id,
169-
expand: ['owner', 'items']
216+
expand: ['owner', 'items', 'clients']
170217
}, true /* <- skip masking */);
171218
})
172219
.then((row) => {
@@ -204,7 +251,7 @@ const internalAccessList = {
204251
.joinRaw('LEFT JOIN `proxy_host` ON `proxy_host`.`access_list_id` = `access_list`.`id` AND `proxy_host`.`is_deleted` = 0')
205252
.where('access_list.is_deleted', 0)
206253
.andWhere('access_list.id', data.id)
207-
.allowEager('[owner,items,proxy_hosts]')
254+
.allowEager('[owner,items,clients,proxy_hosts]')
208255
.omit(['access_list.is_deleted'])
209256
.first();
210257

@@ -246,7 +293,7 @@ const internalAccessList = {
246293
delete: (access, data) => {
247294
return access.can('access_lists:delete', data.id)
248295
.then(() => {
249-
return internalAccessList.get(access, {id: data.id, expand: ['proxy_hosts', 'items']});
296+
return internalAccessList.get(access, {id: data.id, expand: ['proxy_hosts', 'items', 'clients']});
250297
})
251298
.then((row) => {
252299
if (!row) {
@@ -330,7 +377,7 @@ const internalAccessList = {
330377
.where('access_list.is_deleted', 0)
331378
.groupBy('access_list.id')
332379
.omit(['access_list.is_deleted'])
333-
.allowEager('[owner,items]')
380+
.allowEager('[owner,items,clients]')
334381
.orderBy('access_list.name', 'ASC');
335382

336383
if (access_data.permission_visibility !== 'all') {
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
const migrate_name = 'access_list_client';
2+
const logger = require('../logger').migrate;
3+
4+
/**
5+
* Migrate
6+
*
7+
* @see http://knexjs.org/#Schema
8+
*
9+
* @param {Object} knex
10+
* @param {Promise} Promise
11+
* @returns {Promise}
12+
*/
13+
exports.up = function (knex/*, Promise*/) {
14+
15+
logger.info('[' + migrate_name + '] Migrating Up...');
16+
17+
return knex.schema.createTable('access_list_client', (table) => {
18+
table.increments().primary();
19+
table.dateTime('created_on').notNull();
20+
table.dateTime('modified_on').notNull();
21+
table.integer('access_list_id').notNull().unsigned();
22+
table.string('address').notNull();
23+
table.string('directive').notNull();
24+
table.json('meta').notNull();
25+
26+
})
27+
.then(function () {
28+
logger.info('[' + migrate_name + '] access_list_client Table created');
29+
});
30+
};
31+
32+
/**
33+
* Undo Migrate
34+
*
35+
* @param {Object} knex
36+
* @param {Promise} Promise
37+
* @returns {Promise}
38+
*/
39+
exports.down = function (knex/*, Promise*/) {
40+
logger.info('[' + migrate_name + '] Migrating Down...');
41+
42+
return knex.schema.dropTable('access_list_client')
43+
.then(() => {
44+
logger.info('[' + migrate_name + '] access_list_client Table dropped');
45+
});
46+
};

backend/models/access_list.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// Objection Docs:
22
// http://vincit.github.io/objection.js/
33

4-
const db = require('../db');
5-
const Model = require('objection').Model;
6-
const User = require('./user');
7-
const AccessListAuth = require('./access_list_auth');
4+
const db = require('../db');
5+
const Model = require('objection').Model;
6+
const User = require('./user');
7+
const AccessListAuth = require('./access_list_auth');
8+
const AccessListClient = require('./access_list_client');
89

910
Model.knex(db);
1011

@@ -62,6 +63,17 @@ class AccessList extends Model {
6263
qb.omit(['id', 'created_on', 'modified_on', 'access_list_id', 'meta']);
6364
}
6465
},
66+
clients: {
67+
relation: Model.HasManyRelation,
68+
modelClass: AccessListClient,
69+
join: {
70+
from: 'access_list.id',
71+
to: 'access_list_client.access_list_id'
72+
},
73+
modify: function (qb) {
74+
qb.omit(['id', 'created_on', 'modified_on', 'access_list_id', 'meta']);
75+
}
76+
},
6577
proxy_hosts: {
6678
relation: Model.HasManyRelation,
6779
modelClass: ProxyHost,

backend/models/access_list_client.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Objection Docs:
2+
// http://vincit.github.io/objection.js/
3+
4+
const db = require('../db');
5+
const Model = require('objection').Model;
6+
7+
Model.knex(db);
8+
9+
class AccessListClient extends Model {
10+
$beforeInsert () {
11+
this.created_on = Model.raw('NOW()');
12+
this.modified_on = Model.raw('NOW()');
13+
14+
// Default for meta
15+
if (typeof this.meta === 'undefined') {
16+
this.meta = {};
17+
}
18+
}
19+
20+
$beforeUpdate () {
21+
this.modified_on = Model.raw('NOW()');
22+
}
23+
24+
static get name () {
25+
return 'AccessListClient';
26+
}
27+
28+
static get tableName () {
29+
return 'access_list_client';
30+
}
31+
32+
static get jsonAttributes () {
33+
return ['meta'];
34+
}
35+
36+
static get relationMappings () {
37+
return {
38+
access_list: {
39+
relation: Model.HasOneRelation,
40+
modelClass: require('./access_list'),
41+
join: {
42+
from: 'access_list_client.access_list_id',
43+
to: 'access_list.id'
44+
},
45+
modify: function (qb) {
46+
qb.where('access_list.is_deleted', 0);
47+
qb.omit(['created_on', 'modified_on', 'is_deleted', 'access_list_id']);
48+
}
49+
}
50+
};
51+
}
52+
}
53+
54+
module.exports = AccessListClient;

backend/schema/endpoints/access-lists.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@
1919
"type": "string",
2020
"description": "Name of the Access List"
2121
},
22+
"directive": {
23+
"type": "string",
24+
"enum": ["allow", "deny"]
25+
},
26+
"address": {
27+
"type": "string",
28+
"format": "ipv4"
29+
},
2230
"meta": {
2331
"type": "object"
2432
}
@@ -96,6 +104,22 @@
96104
}
97105
}
98106
},
107+
"clients": {
108+
"type": "array",
109+
"minItems": 0,
110+
"items": {
111+
"type": "object",
112+
"additionalProperties": false,
113+
"properties": {
114+
"address": {
115+
"$ref": "#/definitions/address"
116+
},
117+
"directive": {
118+
"$ref": "#/definitions/directive"
119+
}
120+
}
121+
}
122+
},
99123
"meta": {
100124
"$ref": "#/definitions/meta"
101125
}
@@ -141,6 +165,22 @@
141165
}
142166
}
143167
}
168+
},
169+
"clients": {
170+
"type": "array",
171+
"minItems": 0,
172+
"items": {
173+
"type": "object",
174+
"additionalProperties": false,
175+
"properties": {
176+
"address": {
177+
"$ref": "#/definitions/address"
178+
},
179+
"directive": {
180+
"$ref": "#/definitions/directive"
181+
}
182+
}
183+
}
144184
}
145185
}
146186
},

0 commit comments

Comments
 (0)