Skip to content

Commit 990a9b1

Browse files
committed
Merge branch 'bugfix/CLDSRV-746/add-log-fields-to-backbeat-routes-for-analytics' into q/9.0
2 parents 0fbfa5c + 83691b5 commit 990a9b1

File tree

2 files changed

+68
-2
lines changed

2 files changed

+68
-2
lines changed

lib/routes/routeBackbeat.js

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ function putData(request, response, bucketInfo, objMd, log, callback) {
475475
*/
476476

477477
/**
478-
*
478+
*
479479
* @param {string} accountId - account ID
480480
* @param {Log} log - logger instance
481481
* @param {CanonicalIdCallback} cb - callback function
@@ -1466,6 +1466,7 @@ function routeBackbeat(clientIP, request, response, log) {
14661466
const contentLength = request.headers['x-amz-decoded-content-length'] || request.headers['content-length'];
14671467
// eslint-disable-next-line no-param-reassign
14681468
request.parsedContentLength = Number.parseInt(contentLength?.toString() ?? '', 10);
1469+
_normalizeBackbeatRequest(request);
14691470
log.addDefaultFields({
14701471
clientIP,
14711472
url: request.url,
@@ -1478,7 +1479,7 @@ function routeBackbeat(clientIP, request, response, log) {
14781479
});
14791480

14801481
log.debug('routing request');
1481-
_normalizeBackbeatRequest(request);
1482+
14821483
const requestContexts = prepareRequestContexts('objectReplicate', request);
14831484

14841485
if (request.resourceType === 'expiration' || request.resourceType === 'batchdelete') {
@@ -1521,6 +1522,12 @@ function routeBackbeat(clientIP, request, response, log) {
15211522
}
15221523
// eslint-disable-next-line no-param-reassign
15231524
request.accountQuotas = infos?.accountQuota;
1525+
1526+
// Add authentication info to logs for consistency with regular S3 routes
1527+
if (userInfo) {
1528+
log.addDefaultFields(getAuthLogFields(userInfo));
1529+
}
1530+
15241531
// FIXME for now, any authenticated user can access API
15251532
// routes. We should introduce admin accounts or accounts
15261533
// with admin privileges, and restrict access to those
@@ -1570,9 +1577,20 @@ function routeBackbeat(clientIP, request, response, log) {
15701577
}
15711578
// eslint-disable-next-line no-param-reassign
15721579
request.accountQuotas = infos?.accountQuota;
1580+
1581+
// Add authentication info to logs for consistency with regular S3 routes
1582+
if (!err && userInfo) {
1583+
log.addDefaultFields(getAuthLogFields(userInfo));
1584+
}
1585+
15731586
return next(err, userInfo);
15741587
}, 's3', requestContexts),
15751588
(userInfo, next) => {
1589+
// Add action to logs for consistency with regular S3 routes
1590+
const routeName = actionFromRequest(request);
1591+
if (routeName) {
1592+
log.addDefaultFields({ action: routeName });
1593+
}
15761594
// TODO: understand why non-object requests (batchdelete) were not authenticated
15771595
if (!_isObjectRequest(request)) {
15781596
if (userInfo.getCanonicalID() === constants.publicId) {
@@ -1657,5 +1675,50 @@ function routeBackbeat(clientIP, request, response, log) {
16571675
));
16581676
}
16591677

1678+
function getAuthLogFields(userInfo) {
1679+
const authNames = {};
1680+
if (typeof userInfo.getAccountDisplayName === 'function') {
1681+
authNames.accountName = userInfo.getAccountDisplayName();
1682+
authNames.accountDisplayName = userInfo.getAccountDisplayName();
1683+
}
1684+
if (typeof userInfo.isRequesterAnIAMUser === 'function' && userInfo.isRequesterAnIAMUser()) {
1685+
if (typeof userInfo.getIAMdisplayName === 'function') {
1686+
authNames.userName = userInfo.getIAMdisplayName();
1687+
authNames.IAMdisplayName = userInfo.getIAMdisplayName();
1688+
}
1689+
}
1690+
if (typeof userInfo.isRequesterASessionUser === 'function' && userInfo.isRequesterASessionUser()) {
1691+
authNames.sessionName = userInfo.getShortid().split(':')[1];
1692+
}
1693+
return authNames;
1694+
}
1695+
1696+
function actionFromRequest(request) {
1697+
const methodRoutes = backbeatRoutes[request.method];
1698+
if (!methodRoutes) {
1699+
return null;
1700+
}
1701+
1702+
let route = methodRoutes[request.resourceType];
1703+
if (!route) {
1704+
return null;
1705+
}
1706+
1707+
// For multiplebackenddata and index, we need to get the operation one layer deeper
1708+
if (typeof route !== 'function') {
1709+
const operation = request.query.operation;
1710+
if (!operation || !route[operation]) {
1711+
return null;
1712+
}
1713+
route = route[operation];
1714+
}
1715+
1716+
// Final check that we have a function with a name
1717+
if (typeof route !== 'function' || !route.name) {
1718+
return null;
1719+
}
1720+
1721+
return route.name.charAt(0).toUpperCase() + route.name.slice(1);
1722+
}
16601723

16611724
module.exports = routeBackbeat;

tests/unit/routes/routeBackbeat.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,9 @@ describe('routeBackbeat', () => {
550550
cb(null, {
551551
canonicalID: 'id',
552552
getCanonicalID: () => 'id',
553+
getAccountDisplayName: () => 'my-account',
554+
getIAMdisplayName: () => '[assumedRole] service-backbeat-lifecycle-1:backbeat-lifecycle',
555+
isRequesterAnIAMUser: () => true,
553556
});
554557
});
555558

0 commit comments

Comments
 (0)