Skip to content

Commit c749a22

Browse files
author
Jamie Curnow
committed
Certificates into their own section
1 parent 1c57ccd commit c749a22

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+597
-383
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "nginx-proxy-manager",
33
"version": "2.0.0",
4-
"description": "A nice web interface for managing your endpoints",
4+
"description": "A beautiful interface for creating Nginx endpoints",
55
"main": "src/backend/index.js",
66
"devDependencies": {
77
"babel-core": "^6.26.3",

src/backend/internal/certificate.js

Lines changed: 91 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
const _ = require('lodash');
44
const error = require('../lib/error');
55
const certificateModel = require('../models/certificate');
6+
const internalAuditLog = require('./audit-log');
7+
const internalHost = require('./host');
68

79
function omissions () {
810
return ['is_deleted'];
@@ -17,9 +19,27 @@ const internalCertificate = {
1719
*/
1820
create: (access, data) => {
1921
return access.can('certificates:create', data)
20-
.then(access_data => {
21-
// TODO
22-
return {};
22+
.then(() => {
23+
data.owner_user_id = access.token.get('attrs').id;
24+
25+
return certificateModel
26+
.query()
27+
.omit(omissions())
28+
.insertAndFetch(data);
29+
})
30+
.then(row => {
31+
data.meta = _.assign({}, data.meta || {}, row.meta);
32+
33+
// Add to audit log
34+
return internalAuditLog.add(access, {
35+
action: 'created',
36+
object_type: 'certificate',
37+
object_id: row.id,
38+
meta: data
39+
})
40+
.then(() => {
41+
return row;
42+
});
2343
});
2444
},
2545

@@ -135,7 +155,7 @@ const internalCertificate = {
135155
.groupBy('id')
136156
.omit(['is_deleted'])
137157
.allowEager('[owner]')
138-
.orderBy('name', 'ASC');
158+
.orderBy('nice_name', 'ASC');
139159

140160
if (access_data.permission_visibility !== 'all') {
141161
query.andWhere('owner_user_id', access.token.get('attrs').id);
@@ -177,6 +197,73 @@ const internalCertificate = {
177197
.then(row => {
178198
return parseInt(row.count, 10);
179199
});
200+
},
201+
202+
/**
203+
* Validates that the certs provided are good
204+
*
205+
* @param {Access} access
206+
* @param {Object} data
207+
* @param {Object} data.files
208+
* @returns {Promise}
209+
*/
210+
validate: (access, data) => {
211+
return new Promise((resolve, reject) => {
212+
let files = {};
213+
_.map(data.files, (file, name) => {
214+
if (internalHost.allowed_ssl_files.indexOf(name) !== -1) {
215+
files[name] = file.data.toString();
216+
}
217+
});
218+
219+
resolve(files);
220+
})
221+
.then(files => {
222+
223+
// TODO: validate using openssl
224+
// files.certificate
225+
// files.certificate_key
226+
227+
return true;
228+
});
229+
},
230+
231+
/**
232+
* @param {Access} access
233+
* @param {Object} data
234+
* @param {Integer} data.id
235+
* @param {Object} data.files
236+
* @returns {Promise}
237+
*/
238+
upload: (access, data) => {
239+
return internalCertificate.get(access, {id: data.id})
240+
.then(row => {
241+
if (row.provider !== 'other') {
242+
throw new error.ValidationError('Cannot upload certificates for this type of provider');
243+
}
244+
245+
_.map(data.files, (file, name) => {
246+
if (internalHost.allowed_ssl_files.indexOf(name) !== -1) {
247+
row.meta[name] = file.data.toString();
248+
}
249+
});
250+
251+
return internalCertificate.update(access, {
252+
id: data.id,
253+
meta: row.meta
254+
});
255+
})
256+
.then(row => {
257+
return internalAuditLog.add(access, {
258+
action: 'updated',
259+
object_type: 'certificate',
260+
object_id: row.id,
261+
meta: data
262+
})
263+
.then(() => {
264+
return _.pick(row.meta, internalHost.allowed_ssl_files);
265+
});
266+
});
180267
}
181268
};
182269

src/backend/internal/dead-host.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,6 @@ const internalDeadHost = {
4141
// At this point the domains should have been checked
4242
data.owner_user_id = access.token.get('attrs').id;
4343

44-
if (typeof data.meta === 'undefined') {
45-
data.meta = {};
46-
}
47-
4844
return deadHostModel
4945
.query()
5046
.omit(omissions())
@@ -149,7 +145,7 @@ const internalDeadHost = {
149145
.query()
150146
.where('is_deleted', 0)
151147
.andWhere('id', data.id)
152-
.allowEager('[owner]')
148+
.allowEager('[owner,certificate]')
153149
.first();
154150

155151
if (access_data.permission_visibility !== 'all') {
@@ -274,7 +270,7 @@ const internalDeadHost = {
274270
.where('is_deleted', 0)
275271
.groupBy('id')
276272
.omit(['is_deleted'])
277-
.allowEager('[owner]')
273+
.allowEager('[owner,certificate]')
278274
.orderBy('domain_names', 'ASC');
279275

280276
if (access_data.permission_visibility !== 'all') {

src/backend/internal/host.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const deadHostModel = require('../models/dead_host');
88

99
const internalHost = {
1010

11-
allowed_ssl_files: ['other_certificate', 'other_certificate_key'],
11+
allowed_ssl_files: ['certificate', 'certificate_key'],
1212

1313
/**
1414
* Internal use only, checks to see if the ___domain is already taken by any other record

src/backend/internal/proxy-host.js

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,6 @@ const internalProxyHost = {
4141
// At this point the domains should have been checked
4242
data.owner_user_id = access.token.get('attrs').id;
4343

44-
if (typeof data.meta === 'undefined') {
45-
data.meta = {};
46-
}
47-
4844
return proxyHostModel
4945
.query()
5046
.omit(omissions())
@@ -151,7 +147,7 @@ const internalProxyHost = {
151147
.query()
152148
.where('is_deleted', 0)
153149
.andWhere('id', data.id)
154-
.allowEager('[owner,access_list]')
150+
.allowEager('[owner,access_list,certificate]')
155151
.first();
156152

157153
if (access_data.permission_visibility !== 'all') {
@@ -226,40 +222,6 @@ const internalProxyHost = {
226222
});
227223
},
228224

229-
/**
230-
* @param {Access} access
231-
* @param {Object} data
232-
* @param {Integer} data.id
233-
* @param {Object} data.files
234-
* @returns {Promise}
235-
*/
236-
setCerts: (access, data) => {
237-
return internalProxyHost.get(access, {id: data.id})
238-
.then(row => {
239-
_.map(data.files, (file, name) => {
240-
if (internalHost.allowed_ssl_files.indexOf(name) !== -1) {
241-
row.meta[name] = file.data.toString();
242-
}
243-
});
244-
245-
return internalProxyHost.update(access, {
246-
id: data.id,
247-
meta: row.meta
248-
});
249-
})
250-
.then(row => {
251-
return internalAuditLog.add(access, {
252-
action: 'updated',
253-
object_type: 'proxy-host',
254-
object_id: row.id,
255-
meta: data
256-
})
257-
.then(() => {
258-
return _.pick(row.meta, internalHost.allowed_ssl_files);
259-
});
260-
});
261-
},
262-
263225
/**
264226
* All Hosts
265227
*
@@ -276,7 +238,7 @@ const internalProxyHost = {
276238
.where('is_deleted', 0)
277239
.groupBy('id')
278240
.omit(['is_deleted'])
279-
.allowEager('[owner,access_list]')
241+
.allowEager('[owner,access_list,certificate]')
280242
.orderBy('domain_names', 'ASC');
281243

282244
if (access_data.permission_visibility !== 'all') {

src/backend/internal/redirection-host.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,6 @@ const internalRedirectionHost = {
4141
// At this point the domains should have been checked
4242
data.owner_user_id = access.token.get('attrs').id;
4343

44-
if (typeof data.meta === 'undefined') {
45-
data.meta = {};
46-
}
47-
4844
return redirectionHostModel
4945
.query()
5046
.omit(omissions())
@@ -149,7 +145,7 @@ const internalRedirectionHost = {
149145
.query()
150146
.where('is_deleted', 0)
151147
.andWhere('id', data.id)
152-
.allowEager('[owner]')
148+
.allowEager('[owner,certificate]')
153149
.first();
154150

155151
if (access_data.permission_visibility !== 'all') {
@@ -274,7 +270,7 @@ const internalRedirectionHost = {
274270
.where('is_deleted', 0)
275271
.groupBy('id')
276272
.omit(['is_deleted'])
277-
.allowEager('[owner]')
273+
.allowEager('[owner,certificate]')
278274
.orderBy('domain_names', 'ASC');
279275

280276
if (access_data.permission_visibility !== 'all') {

src/backend/migrations/20180618015850_initial.js

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ exports.up = function (knex/*, Promise*/) {
2222
table.integer('user_id').notNull().unsigned();
2323
table.string('type', 30).notNull();
2424
table.string('secret').notNull();
25-
table.json('meta').notNull();
25+
table.json('meta').notNull().defaultTo('{}');
2626
table.integer('is_deleted').notNull().unsigned().defaultTo(0);
2727
})
2828
.then(() => {
@@ -72,12 +72,11 @@ exports.up = function (knex/*, Promise*/) {
7272
table.string('forward_ip').notNull();
7373
table.integer('forward_port').notNull().unsigned();
7474
table.integer('access_list_id').notNull().unsigned().defaultTo(0);
75-
table.integer('ssl_enabled').notNull().unsigned().defaultTo(0);
76-
table.string('ssl_provider').notNull().defaultTo('');
75+
table.integer('certificate_id').notNull().unsigned().defaultTo(0);
7776
table.integer('ssl_forced').notNull().unsigned().defaultTo(0);
7877
table.integer('caching_enabled').notNull().unsigned().defaultTo(0);
7978
table.integer('block_exploits').notNull().unsigned().defaultTo(0);
80-
table.json('meta').notNull();
79+
table.json('meta').notNull().defaultTo('{}');
8180
});
8281
})
8382
.then(() => {
@@ -92,11 +91,10 @@ exports.up = function (knex/*, Promise*/) {
9291
table.json('domain_names').notNull();
9392
table.string('forward_domain_name').notNull();
9493
table.integer('preserve_path').notNull().unsigned().defaultTo(0);
95-
table.integer('ssl_enabled').notNull().unsigned().defaultTo(0);
96-
table.string('ssl_provider').notNull().defaultTo('');
94+
table.integer('certificate_id').notNull().unsigned().defaultTo(0);
9795
table.integer('ssl_forced').notNull().unsigned().defaultTo(0);
9896
table.integer('block_exploits').notNull().unsigned().defaultTo(0);
99-
table.json('meta').notNull();
97+
table.json('meta').notNull().defaultTo('{}');
10098
});
10199
})
102100
.then(() => {
@@ -109,10 +107,9 @@ exports.up = function (knex/*, Promise*/) {
109107
table.integer('owner_user_id').notNull().unsigned();
110108
table.integer('is_deleted').notNull().unsigned().defaultTo(0);
111109
table.json('domain_names').notNull();
112-
table.integer('ssl_enabled').notNull().unsigned().defaultTo(0);
113-
table.string('ssl_provider').notNull().defaultTo('');
110+
table.integer('certificate_id').notNull().unsigned().defaultTo(0);
114111
table.integer('ssl_forced').notNull().unsigned().defaultTo(0);
115-
table.json('meta').notNull();
112+
table.json('meta').notNull().defaultTo('{}');
116113
});
117114
})
118115
.then(() => {
@@ -129,7 +126,7 @@ exports.up = function (knex/*, Promise*/) {
129126
table.integer('forwarding_port').notNull().unsigned();
130127
table.integer('tcp_forwarding').notNull().unsigned().defaultTo(0);
131128
table.integer('udp_forwarding').notNull().unsigned().defaultTo(0);
132-
table.json('meta').notNull();
129+
table.json('meta').notNull().defaultTo('{}');
133130
});
134131
})
135132
.then(() => {
@@ -142,7 +139,7 @@ exports.up = function (knex/*, Promise*/) {
142139
table.integer('owner_user_id').notNull().unsigned();
143140
table.integer('is_deleted').notNull().unsigned().defaultTo(0);
144141
table.string('name').notNull();
145-
table.json('meta').notNull();
142+
table.json('meta').notNull().defaultTo('{}');
146143
});
147144
})
148145
.then(() => {
@@ -154,9 +151,11 @@ exports.up = function (knex/*, Promise*/) {
154151
table.dateTime('modified_on').notNull();
155152
table.integer('owner_user_id').notNull().unsigned();
156153
table.integer('is_deleted').notNull().unsigned().defaultTo(0);
157-
table.string('name').notNull();
158-
// TODO
159-
table.json('meta').notNull();
154+
table.string('provider').notNull();
155+
table.string('nice_name').notNull().defaultTo('');
156+
table.json('domain_names').notNull().defaultTo('[]');
157+
table.dateTime('expires_on').notNull();
158+
table.json('meta').notNull().defaultTo('{}');
160159
});
161160
})
162161
.then(() => {
@@ -169,7 +168,7 @@ exports.up = function (knex/*, Promise*/) {
169168
table.integer('access_list_id').notNull().unsigned();
170169
table.string('username').notNull();
171170
table.string('password').notNull();
172-
table.json('meta').notNull();
171+
table.json('meta').notNull().defaultTo('{}');
173172
});
174173
})
175174
.then(() => {
@@ -183,7 +182,7 @@ exports.up = function (knex/*, Promise*/) {
183182
table.string('object_type').notNull().defaultTo('');
184183
table.integer('object_id').notNull().unsigned().defaultTo(0);
185184
table.string('action').notNull();
186-
table.json('meta').notNull();
185+
table.json('meta').notNull().defaultTo('{}');
187186
});
188187
})
189188
.then(() => {

src/backend/models/certificate.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ class Certificate extends Model {
1313
$beforeInsert () {
1414
this.created_on = Model.raw('NOW()');
1515
this.modified_on = Model.raw('NOW()');
16+
17+
if (typeof this.expires_on === 'undefined') {
18+
this.expires_on = Model.raw('NOW()');
19+
}
1620
}
1721

1822
$beforeUpdate () {
@@ -28,7 +32,7 @@ class Certificate extends Model {
2832
}
2933

3034
static get jsonAttributes () {
31-
return ['meta'];
35+
return ['domain_names', 'meta'];
3236
}
3337

3438
static get relationMappings () {

0 commit comments

Comments
 (0)