Skip to content

Commit 4fa1ed4

Browse files
author
Vikas Agarwal
committed
Adding new endpoint for user level reports
1 parent eac52dc commit 4fa1ed4

File tree

4 files changed

+124
-3
lines changed

4 files changed

+124
-3
lines changed

src/routes/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,10 @@ router.route('/v5/projects/metadata/planConfig/:key/versions/:version(\\d+)')
310310
.patch(require('./planConfig/version/update'))
311311
.delete(require('./planConfig/version/delete'));
312312

313+
// user level reports
314+
router.route('/v5/projects/reports/embed')
315+
.get(require('./userReports/getEmbedReport'));
316+
313317
// work streams
314318
router.route('/v5/projects/:projectId(\\d+)/workstreams')
315319
.get(require('./workStreams/list'))

src/routes/projectReports/getEmbedReport.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ module.exports = [
105105
const embedUrl = REPORTS[reportName];
106106
req.log.trace(`Generating embed URL for ${reportName} report, using ${embedUrl} as embed URL.`);
107107
if (embedUrl) {
108-
result = await lookerSerivce.generateEmbedUrl(req.authUser, project, member, embedUrl);
108+
result = await lookerSerivce.generateEmbedUrlForProject(req.authUser, project, member, embedUrl);
109109
} else {
110110
return res.status(404).send('Report not found');
111111
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/* eslint-disable no-unused-vars */
2+
import config from 'config';
3+
import _ from 'lodash';
4+
import { middleware as tcMiddleware } from 'tc-core-library-js';
5+
import util from '../../util';
6+
import { USER_ROLE, ADMIN_ROLES, MANAGER_ROLES } from '../../constants';
7+
import models from '../../models';
8+
import lookerSerivce from '../../services/lookerService';
9+
10+
const permissions = tcMiddleware.permissions;
11+
12+
13+
module.exports = [
14+
async (req, res, next) => {
15+
const mockReport = config.get('lookerConfig.USE_MOCK') === 'true';
16+
let reportName = mockReport ? 'mock' : req.query.reportName;
17+
const authUser = req.authUser;
18+
let REPORTS = null;
19+
let allowedUsers = null;
20+
try {
21+
allowedUsers = JSON.parse(_.get(config, 'lookerConfig.ALLOWED_USERS', '[]'));
22+
req.log.trace(allowedUsers, 'allowedUsers');
23+
REPORTS = JSON.parse(config.get('lookerConfig.EMBED_REPORTS_MAPPING'));
24+
} catch (error) {
25+
req.log.error(error);
26+
req.log.debug('Invalid reports mapping. Should be a valid JSON.');
27+
}
28+
if (!mockReport && !REPORTS) {
29+
return res.status(404).send('Report not found');
30+
}
31+
32+
try {
33+
const isAdmin = util.hasRoles(req, ADMIN_ROLES);
34+
const userDisallowed = allowedUsers.length > 0 && !allowedUsers.includes(authUser.userId);
35+
if (userDisallowed) {
36+
req.log.error(`User whitelisting prevented accessing report ${reportName} to ${authUser.userId}`);
37+
return res.status(403).send('User is not allowed to access the report');
38+
}
39+
const token = await util.getM2MToken();
40+
const callerUser = await util.getTopcoderUser(authUser.userId, token, req.log);
41+
req.log.trace(callerUser, 'callerUser');
42+
const member = {
43+
firstName: callerUser.firstName,
44+
lastName: callerUser.lastName,
45+
userId: callerUser.userId,
46+
role: '',
47+
};
48+
let roleKey = '';
49+
if (!mockReport) {
50+
if (util.hasRoles(req, [USER_ROLE.COPILOT])) {
51+
roleKey = 'copilot';
52+
}
53+
if (isAdmin || util.hasRoles(req, MANAGER_ROLES)) {
54+
roleKey = 'topcoder';
55+
} else {
56+
roleKey = 'customer';
57+
}
58+
reportName = `${reportName}-${roleKey}`;
59+
}
60+
// pick the report based on its name
61+
let result = {};
62+
const embedUrl = REPORTS[reportName];
63+
req.log.trace(`Generating embed URL for ${reportName} report, using ${embedUrl} as embed URL.`);
64+
if (embedUrl) {
65+
result = await lookerSerivce.generateEmbedUrlForUser(req.authUser, member, embedUrl);
66+
} else {
67+
return res.status(404).send('Report not found');
68+
}
69+
70+
req.log.trace(result);
71+
return res.status(200).json(result);
72+
} catch (err) {
73+
req.log.error(err);
74+
return res.status(500).send(err.toString());
75+
}
76+
},
77+
];

src/services/lookerService.js

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,44 @@ function createdSignedEmbedUrl(options) {
9292
return `${host}${embedPath}?${queryString}`;
9393
}
9494

95+
/**
96+
* Generates the looker embed URL for the given look/dashboard.
97+
*
98+
* @param {Object} authUser requesting user
99+
* @param {Object} member member object for the requesting user
100+
* @param {String} reportUrl embed URL (look,dashboard etc)
101+
* @returns {String} URL for embedding the looker report, it can be GET only once
102+
*/
103+
function generateEmbedUrlForUser(authUser, member, reportUrl) {
104+
const SESSION_LENGTH = parseInt(config.lookerConfig.SESSION_LENGTH, 10);
105+
const urlData = {
106+
host: config.lookerConfig.LOOKER_HOST,
107+
secret: config.lookerConfig.EMBED_KEY,
108+
external_user_id: authUser.userId,
109+
group_ids: [],
110+
first_name: member.firstName,
111+
last_name: member.lastName,
112+
permissions: ['access_data', 'see_looks', 'see_user_dashboards', 'schedule_look_emails', 'download_with_limit'],
113+
models: ['tc_user_projects'],
114+
access_filters: {
115+
tc_user_projects: {
116+
tc_user_id: `${member.userId}`,
117+
},
118+
},
119+
user_attributes: {
120+
user_roles_project: member.role,
121+
user_roles_platform: authUser.roles,
122+
tc_user_id: member.userId,
123+
},
124+
session_length: SESSION_LENGTH,
125+
embed_url: reportUrl,
126+
force_logout_login: true,
127+
};
128+
129+
const url = createdSignedEmbedUrl(urlData);
130+
return `https://${url}`;
131+
}
132+
95133
/**
96134
* Generates the looker embed URL for the given look/dashboard.
97135
*
@@ -101,7 +139,7 @@ function createdSignedEmbedUrl(options) {
101139
* @param {String} reportUrl embed URL (look,dashboard etc)
102140
* @returns {String} URL for embedding the looker report, it can be GET only once
103141
*/
104-
function generateEmbedUrl(authUser, project, member, reportUrl) {
142+
function generateEmbedUrlForProject(authUser, project, member, reportUrl) {
105143
const SESSION_LENGTH = parseInt(config.lookerConfig.SESSION_LENGTH, 10);
106144
const urlData = {
107145
host: config.lookerConfig.LOOKER_HOST,
@@ -121,6 +159,7 @@ function generateEmbedUrl(authUser, project, member, reportUrl) {
121159
connect_project_id: `${project.id}`,
122160
user_roles_project: member.role,
123161
user_roles_platform: authUser.roles,
162+
tc_user_id: member.userId,
124163
},
125164
session_length: SESSION_LENGTH,
126165
embed_url: reportUrl,
@@ -132,5 +171,6 @@ function generateEmbedUrl(authUser, project, member, reportUrl) {
132171
}
133172

134173
module.exports = {
135-
generateEmbedUrl,
174+
generateEmbedUrlForUser,
175+
generateEmbedUrlForProject,
136176
};

0 commit comments

Comments
 (0)