mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-23 00:22:19 +01:00
feat: added IAuditUser to request with middleware (#6857)
Adds a middleware which adds our needed audit info as a separate object to the request.
This commit is contained in:
parent
06f2f06f38
commit
633cae6f0d
@ -29,6 +29,7 @@ import { unless } from './middleware/unless-middleware';
|
||||
import { catchAllErrorHandler } from './middleware/catch-all-error-handler';
|
||||
import NotFoundError from './error/notfound-error';
|
||||
import { bearerTokenMiddleware } from './middleware/bearer-token-middleware';
|
||||
import { auditAccessMiddleware } from './middleware';
|
||||
|
||||
export default async function getApp(
|
||||
config: IUnleashConfig,
|
||||
@ -176,6 +177,7 @@ export default async function getApp(
|
||||
rbacMiddleware(config, stores, services.accessService),
|
||||
);
|
||||
|
||||
app.use(`${baseUriPath}/api/admin`, auditAccessMiddleware(config));
|
||||
app.use(
|
||||
`${baseUriPath}/api/admin`,
|
||||
maintenanceMiddleware(config, services.maintenanceService),
|
||||
|
42
src/lib/middleware/audit-middleware.test.ts
Normal file
42
src/lib/middleware/audit-middleware.test.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { auditAccessMiddleware } from './audit-middleware';
|
||||
import { createTestConfig } from '../../test/config/test-config';
|
||||
import express from 'express';
|
||||
import noAuthentication from './no-authentication';
|
||||
import type { IAuthRequest } from '../routes/unleash-types';
|
||||
import type { IAuditUser } from '../types';
|
||||
import supertest from 'supertest';
|
||||
|
||||
const config = createTestConfig();
|
||||
|
||||
describe('auditMiddleware testing', () => {
|
||||
test('Adds username and id from an IAuthRequest', async () => {
|
||||
const middleware = auditAccessMiddleware(config);
|
||||
const app = express();
|
||||
noAuthentication('', app);
|
||||
app.use('', middleware);
|
||||
let audit: IAuditUser | undefined;
|
||||
app.get('/api/admin/test', (req: IAuthRequest, res) => {
|
||||
audit = req.audit;
|
||||
res.status(200).end();
|
||||
});
|
||||
const request = supertest(app);
|
||||
await request.get('/api/admin/test').expect(200);
|
||||
expect(audit).toBeDefined();
|
||||
expect(audit!.id).toBe(-1);
|
||||
expect(audit!.username).toBe('unknown');
|
||||
expect(audit!.ip).toBe('::ffff:127.0.0.1');
|
||||
});
|
||||
test('If no auth in place, does not add the audit object', async () => {
|
||||
const middleware = auditAccessMiddleware(config);
|
||||
const app = express();
|
||||
app.use('', middleware);
|
||||
let audit: IAuditUser | undefined;
|
||||
app.get('/api/admin/test', (req: IAuthRequest, res) => {
|
||||
audit = req.audit;
|
||||
res.status(200).end();
|
||||
});
|
||||
const request = supertest(app);
|
||||
await request.get('/api/admin/test').expect(200);
|
||||
expect(audit).toBeUndefined();
|
||||
});
|
||||
});
|
17
src/lib/middleware/audit-middleware.ts
Normal file
17
src/lib/middleware/audit-middleware.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import type { IUnleashConfig } from '../types';
|
||||
import type { IApiRequest, IAuthRequest } from '../routes/unleash-types';
|
||||
import { extractAuditInfo } from '../util';
|
||||
|
||||
export const auditAccessMiddleware = ({
|
||||
getLogger,
|
||||
}: Pick<IUnleashConfig, 'getLogger'>): any => {
|
||||
const logger = getLogger('/middleware/audit-middleware.ts');
|
||||
return (req: IAuthRequest | IApiRequest, _res, next) => {
|
||||
if (!req.user) {
|
||||
logger.info('Could not find user');
|
||||
} else {
|
||||
req.audit = extractAuditInfo(req);
|
||||
}
|
||||
next();
|
||||
};
|
||||
};
|
@ -1,4 +1,5 @@
|
||||
export * from './api-token-middleware';
|
||||
export * from './audit-middleware';
|
||||
export * from './conditional-middleware';
|
||||
export * from './content_type_checker';
|
||||
export * from './cors-origin-middleware';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { Request } from 'express';
|
||||
import type { IUser } from '../types/user';
|
||||
import type { IAuditUser, IUser } from '../types/user';
|
||||
import type { IApiUser } from '../types';
|
||||
|
||||
export interface IAuthRequest<
|
||||
@ -11,6 +11,7 @@ export interface IAuthRequest<
|
||||
user: IUser;
|
||||
logout: (() => void) | ((callback: (err?: any) => void) => void);
|
||||
session: any;
|
||||
audit?: IAuditUser;
|
||||
}
|
||||
|
||||
export interface IApiRequest<
|
||||
@ -22,6 +23,7 @@ export interface IApiRequest<
|
||||
user: IApiUser;
|
||||
logout: (() => void) | ((callback: (err?: any) => void) => void);
|
||||
session: any;
|
||||
audit?: IAuditUser;
|
||||
}
|
||||
|
||||
export interface RequestBody<T> extends Express.Request {
|
||||
|
@ -22,7 +22,7 @@ import {
|
||||
SYSTEM_USER,
|
||||
} from './types';
|
||||
|
||||
import User, { type IUser } from './types/user';
|
||||
import User, { type IAuditUser, type IUser } from './types/user';
|
||||
import ApiUser, { type IApiUser } from './types/api-user';
|
||||
import { type Logger, LogLevel } from './logger';
|
||||
import AuthenticationRequired from './types/authentication-required';
|
||||
@ -220,6 +220,7 @@ export type {
|
||||
IUnleashConfig,
|
||||
IUser,
|
||||
IApiUser,
|
||||
IAuditUser,
|
||||
IUnleashServices,
|
||||
IAuthRequest,
|
||||
IApiRequest,
|
||||
|
@ -37,6 +37,12 @@ export interface IProjectUser extends IUser {
|
||||
addedAt: Date;
|
||||
}
|
||||
|
||||
export interface IAuditUser {
|
||||
id: number;
|
||||
username: string;
|
||||
ip?: string;
|
||||
}
|
||||
|
||||
export default class User implements IUser {
|
||||
isAPI: boolean = false;
|
||||
|
||||
|
@ -3,6 +3,7 @@ import type {
|
||||
IApiRequest,
|
||||
IApiUser,
|
||||
IAuthRequest,
|
||||
IAuditUser,
|
||||
IUser,
|
||||
} from '../server-impl';
|
||||
|
||||
@ -26,3 +27,11 @@ export const extractUserInfo = (req: IAuthRequest | IApiRequest) => ({
|
||||
id: extractUserId(req),
|
||||
username: extractUsername(req),
|
||||
});
|
||||
|
||||
export const extractAuditInfo = (
|
||||
req: IAuthRequest | IApiRequest,
|
||||
): IAuditUser => ({
|
||||
id: extractUserId(req),
|
||||
username: extractUsername(req),
|
||||
ip: req.ip,
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user