Skip to content

Commit ab15629

Browse files
committed
feat: add system user
1 parent 2cd6810 commit ab15629

File tree

2 files changed

+94
-2
lines changed

2 files changed

+94
-2
lines changed

src/backend/src/services/database/SqliteDatabaseAccessService.js

+31-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class SqliteDatabaseAccessService extends BaseDatabaseAccessService {
4242
this.db = new Database(this.config.path);
4343

4444
// Database upgrade logic
45-
const TARGET_VERSION = 22;
45+
const TARGET_VERSION = 23;
4646

4747
if ( do_setup ) {
4848
this.log.noticeme(`SETUP: creating database at ${this.config.path}`);
@@ -71,6 +71,7 @@ class SqliteDatabaseAccessService extends BaseDatabaseAccessService {
7171
'0022_dev-center-max.sql',
7272
'0023_fix-kv.sql',
7373
'0024_default-groups.sql',
74+
'0025_system-user.dbmig.js'
7475
].map(p => path_.join(__dirname, 'sqlite_setup', p));
7576
const fs = require('fs');
7677
for ( const filename of sql_files ) {
@@ -175,6 +176,10 @@ class SqliteDatabaseAccessService extends BaseDatabaseAccessService {
175176
upgrade_files.push('0024_default-groups.sql');
176177
}
177178

179+
if ( user_version <= 22 ) {
180+
upgrade_files.push('0025_system-user.dbmig.js');
181+
}
182+
178183
if ( upgrade_files.length > 0 ) {
179184
this.log.noticeme(`Database out of date: ${this.config.path}`);
180185
this.log.noticeme(`UPGRADING DATABASE: ${user_version} -> ${TARGET_VERSION}`);
@@ -188,7 +193,20 @@ class SqliteDatabaseAccessService extends BaseDatabaseAccessService {
188193
const basename = path_.basename(filename);
189194
this.log.noticeme(`applying ${basename}`);
190195
const contents = fs.readFileSync(filename, 'utf8');
191-
this.db.exec(contents);
196+
switch ( path_.extname(filename) ) {
197+
case '.sql':
198+
this.db.exec(contents);
199+
break;
200+
case '.js':
201+
await this.run_js_migration_({
202+
filename, contents,
203+
});
204+
break;
205+
default:
206+
throw new Error(
207+
`unrecognized migration type: ${filename}`
208+
);
209+
}
192210
}
193211

194212
// Update version number
@@ -273,6 +291,17 @@ class SqliteDatabaseAccessService extends BaseDatabaseAccessService {
273291
return p;
274292
});
275293
}
294+
295+
async run_js_migration_ ({ filename, contents }) {
296+
contents = `(async () => {${contents}})()`;
297+
const vm = require('vm');
298+
const context = vm.createContext({
299+
read: this.read.bind(this),
300+
write: this.write.bind(this),
301+
log: this.log,
302+
});
303+
await vm.runInContext(contents, context);
304+
}
276305

277306
_register_commands (commands) {
278307
commands.registerCommands('sqlite', [
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
Add a user called `system`.
3+
4+
If a user called `system` already exists, first rename the existing
5+
user to the first username in this sequence:
6+
system_, system_0, system_1, system_2, ...
7+
*/
8+
9+
let existing_user;
10+
11+
;[existing_user] = await read(
12+
"SELECT username FROM `user` WHERE username='system'",
13+
);
14+
15+
if ( existing_user ) {
16+
let replace_num = 0;
17+
let replace_name = 'system_';
18+
19+
for (;;) {
20+
;[existing_user] = await read(
21+
'SELECT username FROM `user` WHERE username=?',
22+
[replace_name]
23+
);
24+
if ( ! existing_user ) break;
25+
replace_name = 'system_' + (replace_num++);
26+
}
27+
28+
log.noticeme('updating existing user called system', {
29+
replace_num,
30+
replace_name,
31+
});
32+
33+
await write(
34+
`UPDATE \`user\` SET username=? WHERE username='system' LIMIT 1`,
35+
[replace_name]
36+
);
37+
}
38+
39+
const { insertId: system_user_id } = await write(
40+
'INSERT INTO `user` (`uuid`, `username`) VALUES (?, ?)',
41+
[
42+
'5d4adce0-a381-4982-9c02-6e2540026238',
43+
'system',
44+
]
45+
);
46+
47+
const [{id: system_group_id}] = await read(
48+
'SELECT id FROM `group` WHERE uid=?',
49+
['26bfb1fb-421f-45bc-9aa4-d81ea569e7a5']
50+
);
51+
52+
const [{id: admin_group_id}] = await read(
53+
'SELECT id FROM `group` WHERE uid=?',
54+
['ca342a5e-b13d-4dee-9048-58b11a57cc55']
55+
);
56+
57+
// admin group has unlimited access to all drivers
58+
await write(
59+
'INSERT INTO `user_to_group_permissions` ' +
60+
'(`user_id`, `group_id`, `permission`, `extra`) ' +
61+
'VALUES (?, ?, ?, ?)',
62+
[system_user_id, admin_group_id, 'driver', '{}']
63+
);

0 commit comments

Comments
 (0)