1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-07-18 20:59:44 +02:00

feat: Add ability to map OIDC attributes and ignore username

Closes #554
This commit is contained in:
Maksim Eltyshev 2024-01-25 23:01:59 +01:00
parent df9f06fb0f
commit 856e2efc3c
13 changed files with 112 additions and 72 deletions

View file

@ -27,7 +27,11 @@ SECRET_KEY=notsecretkey
# OIDC_CLIENT_SECRET=
# OIDC_SCOPES=openid email profile
# OIDC_ADMIN_ROLES=admin
# OIDC_EMAIL_ATTRIBUTE=email
# OIDC_NAME_ATTRIBUTE=name
# OIDC_USERNAME_ATTRIBUTE=preferred_username
# OIDC_ROLES_ATTRIBUTE=groups
# OIDC_IGNORE_USERNAME=true
# OIDC_IGNORE_ROLES=true
## Do not edit this

View file

@ -53,11 +53,7 @@ module.exports = {
async fn(inputs) {
const { currentUser } = this.req;
if (inputs.id === currentUser.id) {
if (!inputs.currentPassword) {
throw Errors.INVALID_CURRENT_PASSWORD;
}
} else if (!currentUser.isAdmin) {
if (inputs.id !== currentUser.id && !currentUser.isAdmin) {
throw Errors.USER_NOT_FOUND; // Forbidden
}
@ -67,15 +63,18 @@ module.exports = {
throw Errors.USER_NOT_FOUND;
}
if (user.email === sails.config.custom.defaultAdminEmail || user.isSso) {
if (user.email === sails.config.custom.defaultAdminEmail) {
throw Errors.NOT_ENOUGH_RIGHTS;
}
if (
inputs.id === currentUser.id &&
!bcrypt.compareSync(inputs.currentPassword, user.password)
) {
throw Errors.INVALID_CURRENT_PASSWORD;
if (user.isSso) {
if (!sails.config.custom.oidcIgnoreUsername) {
throw Errors.NOT_ENOUGH_RIGHTS;
}
} else if (inputs.id === currentUser.id) {
if (!inputs.currentPassword || !bcrypt.compareSync(inputs.currentPassword, user.password)) {
throw Errors.INVALID_CURRENT_PASSWORD;
}
}
const values = _.pick(inputs, ['username']);

View file

@ -38,7 +38,10 @@ module.exports = {
throw 'invalidCodeOrNonce';
}
if (!userInfo.email || !userInfo.name) {
if (
!userInfo[sails.config.custom.oidcEmailAttribute] ||
!userInfo[sails.config.custom.oidcNameAttribute]
) {
throw 'missingValues';
}
@ -56,12 +59,14 @@ module.exports = {
const values = {
isAdmin,
email: userInfo.email,
email: userInfo[sails.config.custom.oidcEmailAttribute],
isSso: true,
name: userInfo.name,
username: userInfo.preferred_username,
name: userInfo[sails.config.custom.oidcNameAttribute],
subscribeToOwnCards: false,
};
if (!sails.config.custom.oidcIgnoreUsername) {
values.username = userInfo[sails.config.custom.oidcUsernameAttribute];
}
let user;
// This whole block technically needs to be executed in a transaction
@ -95,7 +100,10 @@ module.exports = {
});
}
const updateFieldKeys = ['email', 'isSso', 'name', 'username'];
const updateFieldKeys = ['email', 'isSso', 'name'];
if (!sails.config.custom.oidcIgnoreUsername) {
updateFieldKeys.push('username');
}
if (!sails.config.custom.oidcIgnoreRoles) {
updateFieldKeys.push('isAdmin');
}

View file

@ -116,6 +116,7 @@ module.exports = {
..._.omit(this, ['password', 'isSso', 'avatar', 'passwordChangedAt']),
isLocked: this.isSso || isDefaultAdmin,
isRoleLocked: (this.isSso && !sails.config.custom.oidcIgnoreRoles) || isDefaultAdmin,
isUsernameLocked: (this.isSso && !sails.config.custom.oidcIgnoreUsername) || isDefaultAdmin,
isDeletionLocked: isDefaultAdmin,
avatarUrl:
this.avatar &&

View file

@ -38,7 +38,11 @@ module.exports.custom = {
oidcClientSecret: process.env.OIDC_CLIENT_SECRET,
oidcScopes: process.env.OIDC_SCOPES || 'openid email profile',
oidcAdminRoles: process.env.OIDC_ADMIN_ROLES ? process.env.OIDC_ADMIN_ROLES.split(',') : [],
oidcEmailAttribute: process.env.OIDC_EMAIL_ATTRIBUTE || 'email',
oidcNameAttribute: process.env.OIDC_NAME_ATTRIBUTE || 'name',
oidcUsernameAttribute: process.env.OIDC_USERNAME_ATTRIBUTE || 'preferred_username',
oidcRolesAttribute: process.env.OIDC_ROLES_ATTRIBUTE || 'groups',
oidcIgnoreUsername: process.env.OIDC_IGNORE_USERNAME === 'true',
oidcIgnoreRoles: process.env.OIDC_IGNORE_ROLES === 'true',
// TODO: move client base url to environment variable?