Skip to content

Commit

Permalink
OpenID (actualbudget#498)
Browse files Browse the repository at this point in the history
  • Loading branch information
lelemm authored and meonkeys committed Dec 2, 2024
1 parent bb21b7d commit 61c3884
Show file tree
Hide file tree
Showing 27 changed files with 2,391 additions and 117 deletions.
92 changes: 91 additions & 1 deletion jest.global-setup.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,100 @@
import getAccountDb from './src/account-db.js';
import runMigrations from './src/migrations.js';

const GENERIC_ADMIN_ID = 'genericAdmin';
const GENERIC_USER_ID = 'genericUser';
const ADMIN_ROLE_ID = 'ADMIN';
const BASIC_ROLE_ID = 'BASIC';

const createUser = (userId, userName, role, owner = 0, enabled = 1) => {
const missingParams = [];
if (!userId) missingParams.push('userId');
if (!userName) missingParams.push('userName');
if (!role) missingParams.push('role');
if (missingParams.length > 0) {
throw new Error(`Missing required parameters: ${missingParams.join(', ')}`);
}

if (
typeof userId !== 'string' ||
typeof userName !== 'string' ||
typeof role !== 'string'
) {
throw new Error(
'Invalid parameter types. userId, userName, and role must be strings',
);
}

try {
getAccountDb().mutate(
'INSERT INTO users (id, user_name, display_name, enabled, owner, role) VALUES (?, ?, ?, ?, ?, ?)',
[userId, userName, userName, enabled, owner, role],
);
} catch (error) {
console.error(`Error creating user ${userName}:`, error);
throw error;
}
};

const setSessionUser = (userId, token = 'valid-token') => {
if (!userId) {
throw new Error('userId is required');
}

try {
const db = getAccountDb();
const session = db.first('SELECT token FROM sessions WHERE token = ?', [
token,
]);
if (!session) {
throw new Error(`Session not found for token: ${token}`);
}

db.mutate('UPDATE sessions SET user_id = ? WHERE token = ?', [
userId,
token,
]);
} catch (error) {
console.error(`Error updating session for user ${userId}:`, error);
throw error;
}
};

export default async function setup() {
const NEVER_EXPIRES = -1; // or consider using a far future timestamp

await runMigrations();

createUser(GENERIC_ADMIN_ID, 'admin', ADMIN_ROLE_ID, 1);

// Insert a fake "valid-token" fixture that can be reused
const db = getAccountDb();
await db.mutate('INSERT INTO sessions (token) VALUES (?)', ['valid-token']);
try {
await db.mutate('BEGIN TRANSACTION');

await db.mutate('DELETE FROM sessions');
await db.mutate(
'INSERT INTO sessions (token, expires_at, user_id) VALUES (?, ?, ?)',
['valid-token', NEVER_EXPIRES, 'genericAdmin'],
);
await db.mutate(
'INSERT INTO sessions (token, expires_at, user_id) VALUES (?, ?, ?)',
['valid-token-admin', NEVER_EXPIRES, 'genericAdmin'],
);

await db.mutate(
'INSERT INTO sessions (token, expires_at, user_id) VALUES (?, ?, ?)',
['valid-token-user', NEVER_EXPIRES, 'genericUser'],
);

await db.mutate('COMMIT');
} catch (error) {
await db.mutate('ROLLBACK');
throw new Error(`Failed to setup test sessions: ${error.message}`);
}

setSessionUser('genericAdmin');
setSessionUser('genericAdmin', 'valid-token-admin');

createUser(GENERIC_USER_ID, 'user', BASIC_ROLE_ID, 1);
}
41 changes: 41 additions & 0 deletions migrations/1718889148000-openid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import getAccountDb from '../src/account-db.js';

export const up = async function () {
await getAccountDb().exec(
`
BEGIN TRANSACTION;
CREATE TABLE auth_new
(method TEXT PRIMARY KEY,
display_name TEXT,
extra_data TEXT, active INTEGER);
INSERT INTO auth_new (method, display_name, extra_data, active)
SELECT 'password', 'Password', password, 1 FROM auth;
DROP TABLE auth;
ALTER TABLE auth_new RENAME TO auth;
CREATE TABLE pending_openid_requests
(state TEXT PRIMARY KEY,
code_verifier TEXT,
return_url TEXT,
expiry_time INTEGER);
COMMIT;`,
);
};

export const down = async function () {
await getAccountDb().exec(
`
BEGIN TRANSACTION;
ALTER TABLE auth RENAME TO auth_temp;
CREATE TABLE auth
(password TEXT);
INSERT INTO auth (password)
SELECT extra_data FROM auth_temp WHERE method = 'password';
DROP TABLE auth_temp;
DROP TABLE pending_openid_requests;
COMMIT;
`,
);
};
104 changes: 104 additions & 0 deletions migrations/1719409568000-multiuser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import getAccountDb from '../src/account-db.js';

export const up = async function () {
await getAccountDb().exec(
`
BEGIN TRANSACTION;
CREATE TABLE users
(id TEXT PRIMARY KEY,
user_name TEXT,
display_name TEXT,
role TEXT,
enabled INTEGER NOT NULL DEFAULT 1,
owner INTEGER NOT NULL DEFAULT 0);
CREATE TABLE user_access
(user_id TEXT,
file_id TEXT,
PRIMARY KEY (user_id, file_id),
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (file_id) REFERENCES files(id)
);
ALTER TABLE files
ADD COLUMN owner TEXT;
DELETE FROM sessions;
ALTER TABLE sessions
ADD COLUMN expires_at INTEGER;
ALTER TABLE sessions
ADD COLUMN user_id TEXT;
ALTER TABLE sessions
ADD COLUMN auth_method TEXT;
COMMIT;
`,
);
};

export const down = async function () {
await getAccountDb().exec(
`
BEGIN TRANSACTION;
DROP TABLE IF EXISTS user_access;
CREATE TABLE sessions_backup (
token TEXT PRIMARY KEY
);
INSERT INTO sessions_backup (token)
SELECT token FROM sessions;
DROP TABLE sessions;
ALTER TABLE sessions_backup RENAME TO sessions;
CREATE TABLE files_backup (
id TEXT PRIMARY KEY,
group_id TEXT,
sync_version SMALLINT,
encrypt_meta TEXT,
encrypt_keyid TEXT,
encrypt_salt TEXT,
encrypt_test TEXT,
deleted BOOLEAN DEFAULT FALSE,
name TEXT
);
INSERT INTO files_backup (
id,
group_id,
sync_version,
encrypt_meta,
encrypt_keyid,
encrypt_salt,
encrypt_test,
deleted,
name
)
SELECT
id,
group_id,
sync_version,
encrypt_meta,
encrypt_keyid,
encrypt_salt,
encrypt_test,
deleted,
name
FROM files;
DROP TABLE files;
ALTER TABLE files_backup RENAME TO files;
DROP TABLE IF EXISTS users;
COMMIT;
`,
);
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"jws": "^4.0.0",
"migrate": "^2.0.1",
"nordigen-node": "^1.4.0",
"openid-client": "^5.4.2",
"uuid": "^9.0.0",
"winston": "^3.14.2"
},
Expand Down
Loading

0 comments on commit 61c3884

Please sign in to comment.