mirror of
https://github.com/directus/directus.git
synced 2026-04-03 03:00:39 -04:00
Add register and update hooks for oauth2 and openid drivers (#18131)
* Add register and update hooks for oauth2 and openid drivers * Add register and update hooks for ldap and saml drivers * Update contributors.yml Add username nicam to contributors.yml --------- Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com>
This commit is contained in:
committed by
GitHub
parent
bce0c1c002
commit
b220413819
@@ -3,6 +3,8 @@ import { Router } from 'express';
|
||||
import Joi from 'joi';
|
||||
import type { Client, Error, LDAPResult, SearchCallbackResponse, SearchEntry } from 'ldapjs';
|
||||
import ldap from 'ldapjs';
|
||||
import getDatabase from '../../database/index.js';
|
||||
import emitter from '../../emitter.js';
|
||||
import env from '../../env.js';
|
||||
import { RecordNotUniqueException } from '../../exceptions/database/record-not-unique.js';
|
||||
import {
|
||||
@@ -267,10 +269,23 @@ export class LDAPAuthDriver extends AuthDriver {
|
||||
const userId = await this.fetchUserId(userInfo.dn);
|
||||
|
||||
if (userId) {
|
||||
// Run hook so the end user has the chance to augment the
|
||||
// user that is about to be updated
|
||||
let updatedUserPayload = await emitter.emitFilter(
|
||||
`auth.update`,
|
||||
{},
|
||||
{ identifier: userInfo.dn, provider: this.config['provider'], providerPayload: { userInfo, userRole } },
|
||||
{ database: getDatabase(), schema: this.schema, accountability: null }
|
||||
);
|
||||
|
||||
// Only sync roles if the AD groups are configured
|
||||
if (groupDn) {
|
||||
await this.usersService.updateOne(userId, { role: userRole?.id ?? defaultRoleId ?? null });
|
||||
updatedUserPayload = { role: userRole?.id ?? defaultRoleId ?? null, ...updatedUserPayload };
|
||||
}
|
||||
|
||||
// Update user to update properties that might have changed
|
||||
await this.usersService.updateOne(userId, updatedUserPayload);
|
||||
|
||||
return userId;
|
||||
}
|
||||
|
||||
@@ -278,15 +293,26 @@ export class LDAPAuthDriver extends AuthDriver {
|
||||
throw new InvalidCredentialsException();
|
||||
}
|
||||
|
||||
const userPayload = {
|
||||
provider: this.config['provider'],
|
||||
first_name: userInfo.firstName,
|
||||
last_name: userInfo.lastName,
|
||||
email: userInfo.email,
|
||||
external_identifier: userInfo.dn,
|
||||
role: userRole?.id ?? defaultRoleId,
|
||||
};
|
||||
|
||||
// Run hook so the end user has the chance to augment the
|
||||
// user that is about to be created
|
||||
const updatedUserPayload = await emitter.emitFilter(
|
||||
`auth.create`,
|
||||
userPayload,
|
||||
{ identifier: userInfo.dn, provider: this.config['provider'], providerPayload: { userInfo, userRole } },
|
||||
{ database: getDatabase(), schema: this.schema, accountability: null }
|
||||
);
|
||||
|
||||
try {
|
||||
await this.usersService.createOne({
|
||||
provider: this.config['provider'],
|
||||
first_name: userInfo.firstName,
|
||||
last_name: userInfo.lastName,
|
||||
email: userInfo.email,
|
||||
external_identifier: userInfo.dn,
|
||||
role: userRole?.id ?? defaultRoleId,
|
||||
});
|
||||
await this.usersService.createOne(updatedUserPayload);
|
||||
} catch (e) {
|
||||
if (e instanceof RecordNotUniqueException) {
|
||||
logger.warn(e, '[LDAP] Failed to register user. User not unique');
|
||||
|
||||
@@ -6,6 +6,8 @@ import flatten from 'flat';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { Client, errors, generators, Issuer } from 'openid-client';
|
||||
import { getAuthProvider } from '../../auth.js';
|
||||
import getDatabase from '../../database/index.js';
|
||||
import emitter from '../../emitter.js';
|
||||
import env from '../../env.js';
|
||||
import { RecordNotUniqueException } from '../../exceptions/database/record-not-unique.js';
|
||||
import {
|
||||
@@ -138,15 +140,35 @@ export class OAuth2AuthDriver extends LocalAuthDriver {
|
||||
throw new InvalidCredentialsException();
|
||||
}
|
||||
|
||||
const userPayload = {
|
||||
provider,
|
||||
first_name: userInfo[this.config['firstNameKey']],
|
||||
last_name: userInfo[this.config['lastNameKey']],
|
||||
email: email,
|
||||
external_identifier: identifier,
|
||||
role: this.config['defaultRoleId'],
|
||||
auth_data: tokenSet.refresh_token && JSON.stringify({ refreshToken: tokenSet.refresh_token }),
|
||||
};
|
||||
|
||||
const userId = await this.fetchUserId(identifier);
|
||||
|
||||
if (userId) {
|
||||
// Update user refreshToken if provided
|
||||
if (tokenSet.refresh_token) {
|
||||
await this.usersService.updateOne(userId, {
|
||||
auth_data: JSON.stringify({ refreshToken: tokenSet.refresh_token }),
|
||||
});
|
||||
}
|
||||
// Run hook so the end user has the chance to augment the
|
||||
// user that is about to be updated
|
||||
const updatedUserPayload = await emitter.emitFilter(
|
||||
`auth.update`,
|
||||
{},
|
||||
{
|
||||
identifier,
|
||||
provider: this.config['provider'],
|
||||
providerPayload: { accessToken: tokenSet.access_token, userInfo },
|
||||
},
|
||||
{ database: getDatabase(), schema: this.schema, accountability: null }
|
||||
);
|
||||
|
||||
// Update user to update refresh_token and other properties that might have changed
|
||||
await this.usersService.updateOne(userId, updatedUserPayload);
|
||||
|
||||
return userId;
|
||||
}
|
||||
|
||||
@@ -156,16 +178,21 @@ export class OAuth2AuthDriver extends LocalAuthDriver {
|
||||
throw new InvalidCredentialsException();
|
||||
}
|
||||
|
||||
// Run hook so the end user has the chance to augment the
|
||||
// user that is about to be created
|
||||
const updatedUserPayload = await emitter.emitFilter(
|
||||
`auth.create`,
|
||||
userPayload,
|
||||
{
|
||||
identifier,
|
||||
provider: this.config['provider'],
|
||||
providerPayload: { accessToken: tokenSet.access_token, userInfo },
|
||||
},
|
||||
{ database: getDatabase(), schema: this.schema, accountability: null }
|
||||
);
|
||||
|
||||
try {
|
||||
await this.usersService.createOne({
|
||||
provider,
|
||||
first_name: userInfo[this.config['firstNameKey']],
|
||||
last_name: userInfo[this.config['lastNameKey']],
|
||||
email: email,
|
||||
external_identifier: identifier,
|
||||
role: this.config['defaultRoleId'],
|
||||
auth_data: tokenSet.refresh_token && JSON.stringify({ refreshToken: tokenSet.refresh_token }),
|
||||
});
|
||||
await this.usersService.createOne(updatedUserPayload);
|
||||
} catch (e) {
|
||||
if (e instanceof RecordNotUniqueException) {
|
||||
logger.warn(e, '[OAuth2] Failed to register user. User not unique');
|
||||
|
||||
@@ -6,6 +6,8 @@ import flatten from 'flat';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { Client, errors, generators, Issuer } from 'openid-client';
|
||||
import { getAuthProvider } from '../../auth.js';
|
||||
import getDatabase from '../../database/index.js';
|
||||
import emitter from '../../emitter.js';
|
||||
import env from '../../env.js';
|
||||
import { RecordNotUniqueException } from '../../exceptions/database/record-not-unique.js';
|
||||
import {
|
||||
@@ -161,15 +163,35 @@ export class OpenIDAuthDriver extends LocalAuthDriver {
|
||||
throw new InvalidCredentialsException();
|
||||
}
|
||||
|
||||
const userPayload = {
|
||||
provider,
|
||||
first_name: userInfo['given_name'],
|
||||
last_name: userInfo['family_name'],
|
||||
email: email,
|
||||
external_identifier: identifier,
|
||||
role: this.config['defaultRoleId'],
|
||||
auth_data: tokenSet.refresh_token && JSON.stringify({ refreshToken: tokenSet.refresh_token }),
|
||||
};
|
||||
|
||||
const userId = await this.fetchUserId(identifier);
|
||||
|
||||
if (userId) {
|
||||
// Update user refreshToken if provided
|
||||
if (tokenSet.refresh_token) {
|
||||
await this.usersService.updateOne(userId, {
|
||||
auth_data: JSON.stringify({ refreshToken: tokenSet.refresh_token }),
|
||||
});
|
||||
}
|
||||
// Run hook so the end user has the chance to augment the
|
||||
// user that is about to be updated
|
||||
const updatedUserPayload = await emitter.emitFilter(
|
||||
`auth.update`,
|
||||
{},
|
||||
{
|
||||
identifier,
|
||||
provider: this.config['provider'],
|
||||
providerPayload: { accessToken: tokenSet.access_token, userInfo },
|
||||
},
|
||||
{ database: getDatabase(), schema: this.schema, accountability: null }
|
||||
);
|
||||
|
||||
// Update user to update refresh_token and other properties that might have changed
|
||||
await this.usersService.updateOne(userId, updatedUserPayload);
|
||||
|
||||
return userId;
|
||||
}
|
||||
|
||||
@@ -181,16 +203,21 @@ export class OpenIDAuthDriver extends LocalAuthDriver {
|
||||
throw new InvalidCredentialsException();
|
||||
}
|
||||
|
||||
// Run hook so the end user has the chance to augment the
|
||||
// user that is about to be created
|
||||
const updatedUserPayload = await emitter.emitFilter(
|
||||
`auth.create`,
|
||||
userPayload,
|
||||
{
|
||||
identifier,
|
||||
provider: this.config['provider'],
|
||||
providerPayload: { accessToken: tokenSet.access_token, userInfo },
|
||||
},
|
||||
{ database: getDatabase(), schema: this.schema, accountability: null }
|
||||
);
|
||||
|
||||
try {
|
||||
await this.usersService.createOne({
|
||||
provider,
|
||||
first_name: userInfo['given_name'],
|
||||
last_name: userInfo['family_name'],
|
||||
email: email,
|
||||
external_identifier: identifier,
|
||||
role: this.config['defaultRoleId'],
|
||||
auth_data: tokenSet.refresh_token && JSON.stringify({ refreshToken: tokenSet.refresh_token }),
|
||||
});
|
||||
await this.usersService.createOne(updatedUserPayload);
|
||||
} catch (e) {
|
||||
if (e instanceof RecordNotUniqueException) {
|
||||
logger.warn(e, '[OpenID] Failed to register user. User not unique');
|
||||
|
||||
@@ -4,6 +4,8 @@ import express, { Router } from 'express';
|
||||
import * as samlify from 'samlify';
|
||||
import { getAuthProvider } from '../../auth.js';
|
||||
import { COOKIE_OPTIONS } from '../../constants.js';
|
||||
import getDatabase from '../../database/index.js';
|
||||
import emitter from '../../emitter.js';
|
||||
import env from '../../env.js';
|
||||
import { RecordNotUniqueException } from '../../exceptions/database/record-not-unique.js';
|
||||
import { InvalidCredentialsException, InvalidProviderException } from '../../exceptions/index.js';
|
||||
@@ -63,15 +65,26 @@ export class SAMLAuthDriver extends LocalAuthDriver {
|
||||
const firstName = payload[givenNameKey ?? 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname'];
|
||||
const lastName = payload[familyNameKey ?? 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname'];
|
||||
|
||||
const userPayload = {
|
||||
provider,
|
||||
first_name: firstName,
|
||||
last_name: lastName,
|
||||
email: email,
|
||||
external_identifier: identifier.toLowerCase(),
|
||||
role: this.config['defaultRoleId'],
|
||||
};
|
||||
|
||||
// Run hook so the end user has the chance to augment the
|
||||
// user that is about to be created
|
||||
const updatedUserPayload = await emitter.emitFilter(
|
||||
`auth.create`,
|
||||
userPayload,
|
||||
{ identifier: identifier.toLowerCase(), provider: this.config['provider'], providerPayload: { ...payload } },
|
||||
{ database: getDatabase(), schema: this.schema, accountability: null }
|
||||
);
|
||||
|
||||
try {
|
||||
return await this.usersService.createOne({
|
||||
provider,
|
||||
first_name: firstName,
|
||||
last_name: lastName,
|
||||
email: email,
|
||||
external_identifier: identifier.toLowerCase(),
|
||||
role: this.config['defaultRoleId'],
|
||||
});
|
||||
return await this.usersService.createOne(updatedUserPayload);
|
||||
} catch (error) {
|
||||
if (error instanceof RecordNotUniqueException) {
|
||||
logger.warn(error, '[SAML] Failed to register user. User not unique');
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
- u12206050
|
||||
- that1matt
|
||||
- jaads
|
||||
- nicam
|
||||
- denkhaus
|
||||
- joselcvarela
|
||||
- knulpi
|
||||
|
||||
Reference in New Issue
Block a user