Skip to content

Commit cd80cc8

Browse files
jbowringjc21
authored andcommitted
Add certificate to streams database model
1 parent ee4250d commit cd80cc8

File tree

4 files changed

+142
-22
lines changed

4 files changed

+142
-22
lines changed

backend/internal/stream.js

Lines changed: 86 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
const _ = require('lodash');
2-
const error = require('../lib/error');
3-
const utils = require('../lib/utils');
4-
const streamModel = require('../models/stream');
5-
const internalNginx = require('./nginx');
6-
const internalAuditLog = require('./audit-log');
7-
const {castJsonIfNeed} = require('../lib/helpers');
1+
const _ = require('lodash');
2+
const error = require('../lib/error');
3+
const utils = require('../lib/utils');
4+
const streamModel = require('../models/stream');
5+
const internalNginx = require('./nginx');
6+
const internalAuditLog = require('./audit-log');
7+
const internalCertificate = require('./certificate');
8+
const internalHost = require('./host');
9+
const {castJsonIfNeed} = require('../lib/helpers');
810

911
function omissions () {
1012
return ['is_deleted'];
@@ -18,6 +20,12 @@ const internalStream = {
1820
* @returns {Promise}
1921
*/
2022
create: (access, data) => {
23+
let create_certificate = data.certificate_id === 'new';
24+
25+
if (create_certificate) {
26+
delete data.certificate_id;
27+
}
28+
2129
return access.can('streams:create', data)
2230
.then((/*access_data*/) => {
2331
// TODO: At this point the existing ports should have been checked
@@ -27,11 +35,40 @@ const internalStream = {
2735
data.meta = {};
2836
}
2937

38+
let data_no_domains = structuredClone(data);
39+
40+
// streams aren't routed by domain name so don't store domain names in the DB
41+
delete data_no_domains.domain_names;
42+
3043
return streamModel
3144
.query()
32-
.insertAndFetch(data)
45+
.insertAndFetch(data_no_domains)
3346
.then(utils.omitRow(omissions()));
3447
})
48+
.then((row) => {
49+
if (create_certificate) {
50+
return internalCertificate.createQuickCertificate(access, data)
51+
.then((cert) => {
52+
// update host with cert id
53+
return internalStream.update(access, {
54+
id: row.id,
55+
certificate_id: cert.id
56+
});
57+
})
58+
.then(() => {
59+
return row;
60+
});
61+
} else {
62+
return row;
63+
}
64+
})
65+
.then((row) => {
66+
// re-fetch with cert
67+
return internalStream.get(access, {
68+
id: row.id,
69+
expand: ['certificate', 'owner']
70+
});
71+
})
3572
.then((row) => {
3673
// Configure nginx
3774
return internalNginx.configure(streamModel, 'stream', row)
@@ -60,6 +97,12 @@ const internalStream = {
6097
* @return {Promise}
6198
*/
6299
update: (access, data) => {
100+
let create_certificate = data.certificate_id === 'new';
101+
102+
if (create_certificate) {
103+
delete data.certificate_id;
104+
}
105+
63106
return access.can('streams:update', data.id)
64107
.then((/*access_data*/) => {
65108
// TODO: at this point the existing streams should have been checked
@@ -71,6 +114,28 @@ const internalStream = {
71114
throw new error.InternalValidationError('Stream could not be updated, IDs do not match: ' + row.id + ' !== ' + data.id);
72115
}
73116

117+
if (create_certificate) {
118+
return internalCertificate.createQuickCertificate(access, {
119+
domain_names: data.domain_names || row.domain_names,
120+
meta: _.assign({}, row.meta, data.meta)
121+
})
122+
.then((cert) => {
123+
// update host with cert id
124+
data.certificate_id = cert.id;
125+
})
126+
.then(() => {
127+
return row;
128+
});
129+
} else {
130+
return row;
131+
}
132+
})
133+
.then((row) => {
134+
// Add domain_names to the data in case it isn't there, so that the audit log renders correctly. The order is important here.
135+
data = _.assign({}, {
136+
domain_names: row.domain_names
137+
}, data);
138+
74139
return streamModel
75140
.query()
76141
.patchAndFetchById(row.id, data)
@@ -115,7 +180,7 @@ const internalStream = {
115180
.query()
116181
.where('is_deleted', 0)
117182
.andWhere('id', data.id)
118-
.allowGraph('[owner]')
183+
.allowGraph('[owner,certificate]')
119184
.first();
120185

121186
if (access_data.permission_visibility !== 'all') {
@@ -132,6 +197,7 @@ const internalStream = {
132197
if (!row || !row.id) {
133198
throw new error.ItemNotFoundError(data.id);
134199
}
200+
row = internalHost.cleanRowCertificateMeta(row);
135201
// Custom omissions
136202
if (typeof data.omit !== 'undefined' && data.omit !== null) {
137203
row = _.omit(row, data.omit);
@@ -197,14 +263,14 @@ const internalStream = {
197263
.then(() => {
198264
return internalStream.get(access, {
199265
id: data.id,
200-
expand: ['owner']
266+
expand: ['certificate', 'owner']
201267
});
202268
})
203269
.then((row) => {
204270
if (!row || !row.id) {
205271
throw new error.ItemNotFoundError(data.id);
206272
} else if (row.enabled) {
207-
throw new error.ValidationError('Host is already enabled');
273+
throw new error.ValidationError('Stream is already enabled');
208274
}
209275

210276
row.enabled = 1;
@@ -250,7 +316,7 @@ const internalStream = {
250316
if (!row || !row.id) {
251317
throw new error.ItemNotFoundError(data.id);
252318
} else if (!row.enabled) {
253-
throw new error.ValidationError('Host is already disabled');
319+
throw new error.ValidationError('Stream is already disabled');
254320
}
255321

256322
row.enabled = 0;
@@ -298,7 +364,7 @@ const internalStream = {
298364
.query()
299365
.where('is_deleted', 0)
300366
.groupBy('id')
301-
.allowGraph('[owner]')
367+
.allowGraph('[owner,certificate]')
302368
.orderByRaw('CAST(incoming_port AS INTEGER) ASC');
303369

304370
if (access_data.permission_visibility !== 'all') {
@@ -317,6 +383,13 @@ const internalStream = {
317383
}
318384

319385
return query.then(utils.omitRows(omissions()));
386+
})
387+
.then((rows) => {
388+
if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) {
389+
return internalHost.cleanAllRowsCertificateMeta(rows);
390+
}
391+
392+
return rows;
320393
});
321394
},
322395

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const migrate_name = 'stream_ssl';
2+
const logger = require('../logger').migrate;
3+
4+
/**
5+
* Migrate
6+
*
7+
* @see http://knexjs.org/#Schema
8+
*
9+
* @param {Object} knex
10+
* @returns {Promise}
11+
*/
12+
exports.up = function (knex) {
13+
logger.info('[' + migrate_name + '] Migrating Up...');
14+
15+
return knex.schema.table('stream', (table) => {
16+
table.integer('certificate_id').notNull().unsigned().defaultTo(0);
17+
})
18+
.then(function () {
19+
logger.info('[' + migrate_name + '] stream Table altered');
20+
});
21+
};
22+
23+
/**
24+
* Undo Migrate
25+
*
26+
* @param {Object} knex
27+
* @returns {Promise}
28+
*/
29+
exports.down = function (knex) {
30+
logger.info('[' + migrate_name + '] Migrating Down...');
31+
32+
return knex.schema.table('stream', (table) => {
33+
table.dropColumn('certificate_id');
34+
})
35+
.then(function () {
36+
logger.info('[' + migrate_name + '] stream Table altered');
37+
});
38+
};

backend/models/stream.js

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
// Objection Docs:
2-
// http://vincit.github.io/objection.js/
3-
4-
const db = require('../db');
5-
const helpers = require('../lib/helpers');
6-
const Model = require('objection').Model;
7-
const User = require('./user');
8-
const now = require('./now_helper');
1+
const Model = require('objection').Model;
2+
const db = require('../db');
3+
const helpers = require('../lib/helpers');
4+
const User = require('./user');
5+
const Certificate = require('./certificate');
6+
const now = require('./now_helper');
97

108
Model.knex(db);
119

@@ -64,6 +62,17 @@ class Stream extends Model {
6462
modify: function (qb) {
6563
qb.where('user.is_deleted', 0);
6664
}
65+
},
66+
certificate: {
67+
relation: Model.HasOneRelation,
68+
modelClass: Certificate,
69+
join: {
70+
from: 'stream.certificate_id',
71+
to: 'certificate.id'
72+
},
73+
modify: function (qb) {
74+
qb.where('certificate.is_deleted', 0);
75+
}
6776
}
6877
};
6978
}

frontend/js/app/nginx/stream/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ module.exports = Mn.View.extend({
8888
onRender: function () {
8989
let view = this;
9090

91-
view.fetch(['owner'])
91+
view.fetch(['owner', 'certificate'])
9292
.then(response => {
9393
if (!view.isDestroyed()) {
9494
if (response && response.length) {

0 commit comments

Comments
 (0)