Fix server level impersonation (#14831)
Tested : - server level ok - workspace level ok - server level without canImpersonate or without allow impersonation - fail ok - workspace level without permission - fail ok
This commit is contained in:
@@ -705,16 +705,31 @@ export class AuthResolver {
|
||||
impersonatorUserWorkspace.user.canImpersonate === true &&
|
||||
impersonatorUserWorkspace.workspace.allowImpersonation === true;
|
||||
|
||||
if (isServerLevelImpersonation && !hasServerLevelImpersonatePermission) {
|
||||
if (isServerLevelImpersonation) {
|
||||
if (!hasServerLevelImpersonatePermission) {
|
||||
await auditService.insertWorkspaceEvent(MONITORING_EVENT, {
|
||||
eventName: 'server.impersonation.token_exchange_failed',
|
||||
message: `Server level impersonation not allowed for ${targetUserEmail} by userId ${impersonatorUserWorkspace.user.id}`,
|
||||
});
|
||||
|
||||
throw new AuthException(
|
||||
'Server level impersonation not allowed on this workspace',
|
||||
AuthExceptionCode.FORBIDDEN_EXCEPTION,
|
||||
);
|
||||
}
|
||||
|
||||
await auditService.insertWorkspaceEvent(MONITORING_EVENT, {
|
||||
eventName: 'server.impersonation.token_exchange_failed',
|
||||
message: `Server level impersonation not allowed for ${targetUserEmail} by userId ${impersonatorUserWorkspace.user.id}`,
|
||||
eventName: `server.impersonation.token_exchange_success`,
|
||||
message: `Impersonation token exchanged for ${targetUserEmail} by userId ${impersonatorUserWorkspace.user.id}`,
|
||||
});
|
||||
|
||||
throw new AuthException(
|
||||
'Server level impersonation not allowed on this workspace',
|
||||
AuthExceptionCode.FORBIDDEN_EXCEPTION,
|
||||
);
|
||||
return {
|
||||
workspaceId: workspace.id,
|
||||
impersonatorUserWorkspaceId: impersonatorUserWorkspace.id,
|
||||
impersonatedUserWorkspaceId: toImpersonateUserWorkspace.id,
|
||||
impersonatorUserId: impersonatorUserWorkspace.user.id,
|
||||
impersonatedUserId: toImpersonateUserWorkspace.user.id,
|
||||
};
|
||||
}
|
||||
|
||||
const hasWorkspaceLevelImpersonatePermission =
|
||||
@@ -724,12 +739,9 @@ export class AuthResolver {
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
|
||||
if (
|
||||
!hasWorkspaceLevelImpersonatePermission &&
|
||||
!hasServerLevelImpersonatePermission
|
||||
) {
|
||||
if (!hasWorkspaceLevelImpersonatePermission) {
|
||||
await auditService.insertWorkspaceEvent(MONITORING_EVENT, {
|
||||
eventName: `${isServerLevelImpersonation ? 'server' : 'workspace'}.impersonation.token_exchange_failed`,
|
||||
eventName: 'workspace.impersonation.token_exchange_failed',
|
||||
message: `Impersonation not allowed for ${targetUserEmail} by userId ${impersonatorUserWorkspace.user.id}`,
|
||||
});
|
||||
throw new AuthException(
|
||||
@@ -739,7 +751,7 @@ export class AuthResolver {
|
||||
}
|
||||
|
||||
await auditService.insertWorkspaceEvent(MONITORING_EVENT, {
|
||||
eventName: `${isServerLevelImpersonation ? 'server' : 'workspace'}.impersonation.token_exchange_success`,
|
||||
eventName: 'workspace.impersonation.token_exchange_success',
|
||||
message: `Impersonation token exchanged for ${targetUserEmail} by userId ${impersonatorUserWorkspace.user.id}`,
|
||||
});
|
||||
|
||||
|
||||
+12
-9
@@ -241,11 +241,17 @@ export class JwtAuthStrategy extends PassportStrategy(Strategy, 'jwt') {
|
||||
impersonatorUserWorkspace.user.canImpersonate === true &&
|
||||
workspace.allowImpersonation === true;
|
||||
|
||||
if (isServerLevelImpersonation && !hasServerLevelImpersonatePermission) {
|
||||
throw new AuthException(
|
||||
'Server level impersonation not allowed',
|
||||
AuthExceptionCode.FORBIDDEN_EXCEPTION,
|
||||
);
|
||||
if (isServerLevelImpersonation) {
|
||||
if (!hasServerLevelImpersonatePermission)
|
||||
throw new AuthException(
|
||||
'Server level impersonation not allowed',
|
||||
AuthExceptionCode.FORBIDDEN_EXCEPTION,
|
||||
);
|
||||
|
||||
return {
|
||||
impersonatorUserWorkspaceId: payload.impersonatorUserWorkspaceId,
|
||||
impersonatedUserWorkspaceId: payload.impersonatedUserWorkspaceId,
|
||||
};
|
||||
}
|
||||
|
||||
const hasWorkspaceLevelImpersonatePermission =
|
||||
@@ -255,10 +261,7 @@ export class JwtAuthStrategy extends PassportStrategy(Strategy, 'jwt') {
|
||||
workspaceId: impersonatedUserWorkspace.workspace.id,
|
||||
});
|
||||
|
||||
if (
|
||||
!hasWorkspaceLevelImpersonatePermission &&
|
||||
!hasServerLevelImpersonatePermission
|
||||
) {
|
||||
if (!hasWorkspaceLevelImpersonatePermission) {
|
||||
throw new AuthException(
|
||||
'Impersonation not allowed',
|
||||
AuthExceptionCode.FORBIDDEN_EXCEPTION,
|
||||
|
||||
+29
-13
@@ -66,10 +66,17 @@ export class ImpersonationService {
|
||||
impersonatorUserWorkspace.user.canImpersonate === true &&
|
||||
impersonatorUserWorkspace.workspace.allowImpersonation === true;
|
||||
|
||||
if (isServerLevelImpersonation && !hasServerLevelImpersonatePermission) {
|
||||
throw new AuthException(
|
||||
'Impersonation not enabled for the impersonator user or the target workspace',
|
||||
AuthExceptionCode.FORBIDDEN_EXCEPTION,
|
||||
if (isServerLevelImpersonation) {
|
||||
if (!hasServerLevelImpersonatePermission)
|
||||
throw new AuthException(
|
||||
'Impersonation not enabled for the impersonator user or the target workspace',
|
||||
AuthExceptionCode.FORBIDDEN_EXCEPTION,
|
||||
);
|
||||
|
||||
return this.generateImpersonationLoginToken(
|
||||
impersonatorUserWorkspace,
|
||||
toImpersonateUserWorkspace,
|
||||
'server',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -80,29 +87,38 @@ export class ImpersonationService {
|
||||
workspaceId: workspaceId,
|
||||
});
|
||||
|
||||
if (
|
||||
!hasWorkspaceLevelImpersonatePermission &&
|
||||
!hasServerLevelImpersonatePermission
|
||||
) {
|
||||
if (!hasWorkspaceLevelImpersonatePermission) {
|
||||
throw new AuthException(
|
||||
'Impersonation not enabled for this workspace',
|
||||
AuthExceptionCode.FORBIDDEN_EXCEPTION,
|
||||
);
|
||||
}
|
||||
|
||||
return this.generateImpersonationLoginToken(
|
||||
impersonatorUserWorkspace,
|
||||
toImpersonateUserWorkspace,
|
||||
'workspace',
|
||||
);
|
||||
}
|
||||
|
||||
async generateImpersonationLoginToken(
|
||||
impersonatorUserWorkspace: UserWorkspace,
|
||||
toImpersonateUserWorkspace: UserWorkspace,
|
||||
impersonationLevel: 'server' | 'workspace',
|
||||
) {
|
||||
const auditService = this.auditService.createContext({
|
||||
workspaceId: impersonatorUserWorkspace.workspace.id,
|
||||
userId: impersonatorUserWorkspace.user.id,
|
||||
});
|
||||
|
||||
await auditService.insertWorkspaceEvent(MONITORING_EVENT, {
|
||||
eventName: `${isServerLevelImpersonation ? 'server' : 'workspace'}.impersonation.attempt`,
|
||||
message: `Impersonation attempt: targetUserId=${toImpersonateUserWorkspace.user.id}, workspaceId=${workspaceId}, impersonatorUserId=${impersonatorUserWorkspace.user.id}`,
|
||||
eventName: `${impersonationLevel}.impersonation.attempt`,
|
||||
message: `Impersonation attempt: targetUserId=${toImpersonateUserWorkspace.user.id}, workspaceId=${toImpersonateUserWorkspace.workspace.id}, impersonatorUserId=${impersonatorUserWorkspace.user.id}`,
|
||||
});
|
||||
|
||||
try {
|
||||
await auditService.insertWorkspaceEvent(MONITORING_EVENT, {
|
||||
eventName: `${isServerLevelImpersonation ? 'server' : 'workspace'}.impersonation.login_token_attempt`,
|
||||
eventName: `${impersonationLevel}.impersonation.login_token_attempt`,
|
||||
message: `Impersonation token generation attempt for user ${toImpersonateUserWorkspace.user.id}`,
|
||||
});
|
||||
|
||||
@@ -116,7 +132,7 @@ export class ImpersonationService {
|
||||
);
|
||||
|
||||
await auditService.insertWorkspaceEvent(MONITORING_EVENT, {
|
||||
eventName: `${isServerLevelImpersonation ? 'server' : 'workspace'}.impersonation.login_token_generated`,
|
||||
eventName: `${impersonationLevel}.impersonation.login_token_generated`,
|
||||
message: `Impersonation token generated successfully for user ${toImpersonateUserWorkspace.user.id}`,
|
||||
});
|
||||
|
||||
@@ -131,7 +147,7 @@ export class ImpersonationService {
|
||||
};
|
||||
} catch {
|
||||
await auditService.insertWorkspaceEvent(MONITORING_EVENT, {
|
||||
eventName: `${isServerLevelImpersonation ? 'server' : 'workspace'}.impersonation.login_token_failed`,
|
||||
eventName: `${impersonationLevel}.impersonation.login_token_failed`,
|
||||
message: `Impersonation token generation failed for targetUserId=${toImpersonateUserWorkspace.user.id}`,
|
||||
});
|
||||
throw new AuthException(
|
||||
|
||||
Reference in New Issue
Block a user