OPENID: Added option to create users on login (#4421)

* Added option to create users on login (openid)

* md

* added default value

* linter

* added validation to ACTUAL_USER_CREATION_MODE

* Merge

* linter

* fixes

* removed enchancement

* linter
This commit is contained in:
lelemm
2025-04-08 11:18:47 -03:00
committed by GitHub
parent cefc8da7bc
commit afab6ee773
5 changed files with 54 additions and 23 deletions

View File

@@ -200,8 +200,8 @@ export async function loginWithOpenIdFinalize(body) {
userInfo.login ??
userInfo.email ??
userInfo.id ??
userInfo.name ??
'default-username';
userInfo.sub;
if (identity == null) {
return { error: 'openid-grant-failed: no identification was found' };
}
@@ -213,29 +213,35 @@ export async function loginWithOpenIdFinalize(body) {
'SELECT count(*) as countUsersWithUserName FROM users WHERE user_name <> ?',
[''],
);
if (countUsersWithUserName === 0) {
// Check if user was created by another transaction
const existingUser = accountDb.first(
'SELECT id FROM users WHERE user_name = ?',
[identity],
);
if (
!existingUser &&
(countUsersWithUserName === 0 ||
config.get('userCreationMode') === 'login')
) {
userId = uuidv4();
// Check if user was created by another transaction
const existingUser = accountDb.first(
'SELECT id FROM users WHERE user_name = ?',
[identity],
);
if (existingUser) {
throw new Error('user-already-exists');
}
accountDb.mutate(
'INSERT INTO users (id, user_name, display_name, enabled, owner, role) VALUES (?, ?, ?, 1, 1, ?)',
'INSERT INTO users (id, user_name, display_name, enabled, owner, role) VALUES (?, ?, ?, 1, ?, ?)',
[
userId,
identity,
userInfo.name ?? userInfo.email ?? identity,
'ADMIN',
countUsersWithUserName === 0 ? '1' : '0',
countUsersWithUserName === 0 ? 'ADMIN' : 'BASIC',
],
);
const userFromPasswordMethod = getUserByUsername('');
if (userFromPasswordMethod) {
transferAllFilesFromUser(userId, userFromPasswordMethod.user_id);
if (countUsersWithUserName === 0) {
const userFromPasswordMethod = getUserByUsername('');
if (userFromPasswordMethod) {
transferAllFilesFromUser(userId, userFromPasswordMethod.user_id);
}
}
} else {
const { id: userIdFromDb, display_name: displayName } =

View File

@@ -40,4 +40,5 @@ export interface Config {
};
token_expiration?: 'never' | 'openid-provider' | number;
enforceOpenId: boolean;
userCreationMode?: 'manual' | 'login';
}

View File

@@ -248,6 +248,13 @@ const configSchema = convict({
default: false,
env: 'ACTUAL_OPENID_ENFORCE',
},
userCreationMode: {
doc: 'Determines how users can be created.',
format: ['manual', 'login'],
default: 'manual',
env: 'ACTUAL_USER_CREATION_MODE',
},
});
let configPath = null;

View File

@@ -241,14 +241,25 @@ export function deleteUserAccessByFileId(userIds, fileId) {
}
export function getAllUserAccess(fileId) {
//This can't be used here until we can create user invite links:
//const isLoginMode = config.get('userCreationMode') === 'login';
const isLoginMode = false;
const joinType = isLoginMode ? 'JOIN' : 'LEFT JOIN';
return getAccountDb().all(
`SELECT users.id as userId, user_name as userName, display_name as displayName,
CASE WHEN user_access.file_id IS NULL THEN 0 ELSE 1 END as haveAccess,
CASE WHEN files.id IS NULL THEN 0 ELSE 1 END as owner
FROM users
LEFT JOIN user_access ON user_access.file_id = ? and user_access.user_id = users.id
LEFT JOIN files ON files.id = ? and files.owner = users.id
WHERE users.enabled = 1 AND users.user_name <> ''`,
`
SELECT
users.id as userId,
user_name as userName,
display_name as displayName,
CASE WHEN user_access.file_id IS NULL THEN 0 ELSE 1 END as haveAccess,
CASE WHEN files.id IS NULL THEN 0 ELSE 1 END as owner
FROM users
${joinType} user_access ON user_access.file_id = ? AND user_access.user_id = users.id
${joinType} files ON files.id = ? AND files.owner = users.id
WHERE users.enabled = 1
AND users.user_name <> ''
`,
[fileId, fileId],
);
}

View File

@@ -0,0 +1,6 @@
---
category: Enhancements
authors: [lelemm]
---
Added `ACTUAL_USER_CREATION_MODE=login` enviroment variable to create users on login