Skip to content

Commit

Permalink
Add tracing instrumentation for ARPA POST /api/uploads handler (#3624)
Browse files Browse the repository at this point in the history
* Instrument spans for persist-upload helpers

* Annotate express traces with authenticated user info
  • Loading branch information
TylerHendrickson authored Oct 10, 2024
1 parent 13b7c9d commit 77cdb1b
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 26 deletions.
58 changes: 32 additions & 26 deletions packages/server/src/arpa_reporter/services/persist-upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@ const jsonFSName = (upload) => {
* @throws {ValidationError}
*/
async function validateBuffer(buffer) {
try {
await XLSX.read(buffer, { type: 'buffer' });
} catch (e) {
throw new ValidationError(`Cannot parse XLSX from supplied data: ${e}`);
}
return tracer.trace('validateBuffer', async () => {
try {
await XLSX.read(buffer, { type: 'buffer' });
} catch (e) {
throw new ValidationError(`Cannot parse XLSX from supplied data: ${e}`);
}
});
}

/**
Expand Down Expand Up @@ -111,19 +113,21 @@ function ensureValidNotes(notes) {
* @throws {ValidationError}
*/
async function ensureValidAgencyId(agencyId, userId) {
// If agencyId is null, it's ok. We derive this later from the spreadsheet
// itself in validate-upload. We leave it as null here.
if (!agencyId) {
return null;
}
// Otherwise, we need to make sure the user is associated with the agency
const userRecord = await getUser(userId);
const tenantAgencies = await getTenantAgencies(userRecord.tenant_id);
const agency = tenantAgencies.find((a) => a.id === Number(agencyId));
if (!agency) {
throw new ValidationError(`Supplied agency ID ${agencyId} does not correspond to an agency in the user's tenant ${userRecord.tenant_id}. Please report this issue to USDR.`);
}
return agencyId;
return tracer.trace('ensureValidAgencyId', async () => {
// If agencyId is null, it's ok. We derive this later from the spreadsheet
// itself in validate-upload. We leave it as null here.
if (!agencyId) {
return null;
}
// Otherwise, we need to make sure the user is associated with the agency
const userRecord = await getUser(userId);
const tenantAgencies = await getTenantAgencies(userRecord.tenant_id);
const agency = tenantAgencies.find((a) => a.id === Number(agencyId));
if (!agency) {
throw new ValidationError(`Supplied agency ID ${agencyId} does not correspond to an agency in the user's tenant ${userRecord.tenant_id}. Please report this issue to USDR.`);
}
return agencyId;
});
}

/**
Expand All @@ -133,14 +137,16 @@ async function ensureValidAgencyId(agencyId, userId) {
* @throws {ValidationError}
*/
async function ensureValidReportingPeriodId(reportingPeriodId) {
// Get the current reporting period. Passing an undefined value
// defaults to the current period.
const reportingPeriod = await getReportingPeriod(reportingPeriodId);

if (!reportingPeriod) {
throw new ValidationError(`Supplied reporting period ID ${reportingPeriodId} does not correspond to any existing reporting period. Please report this issue to USDR.`);
}
return reportingPeriod.id;
return tracer.trace('ensureValidReportingPeriodId', async () => {
// Get the current reporting period. Passing an undefined value
// defaults to the current period.
const reportingPeriod = await getReportingPeriod(reportingPeriodId);

if (!reportingPeriod) {
throw new ValidationError(`Supplied reporting period ID ${reportingPeriodId} does not correspond to any existing reporting period. Please report this issue to USDR.`);
}
return reportingPeriod.id;
});
}

/**
Expand Down
16 changes: 16 additions & 0 deletions packages/server/src/lib/access-helpers.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const tracer = require('dd-trace');
const { getUser, inTenant } = require('../db');
const { log } = require('./logging');

Expand Down Expand Up @@ -83,6 +84,14 @@ async function requireAdminUser(req, res, next) {
try {
const { user, selectedAgency } = await getAdminAuthInfo(req);
req.session = { ...req.session, user, selectedAgency };
tracer.setUser({
id: user.id,
agency_id: user.agency_id,
tenant_id: user.tenant_id,
role_name: user.role_name,
selected_agency_id: selectedAgency,
is_user_super_admin: isUSDRSuperAdmin(user),
});
} catch (err) {
res.sendStatus(403);
return;
Expand Down Expand Up @@ -116,6 +125,13 @@ async function requireUser(req, res, next) {

req.session = { ...req.session, user, selectedAgency: user.agency_id };

tracer.setUser({
id: req.session.user?.id,
role: req.session.user?.role.name,
tenant_id: req.session.user?.tenant?.id,
agency_id: req.session.user?.agency?.id,
});

next();
}

Expand Down

0 comments on commit 77cdb1b

Please sign in to comment.