Skip to content

Commit

Permalink
Merge pull request #845 from HDRUK/release-preprod/v3.1.0
Browse files Browse the repository at this point in the history
Release preprod/v3.1.0
  • Loading branch information
dnhdruk authored Sep 15, 2022
2 parents 1c31fa0 + cc1ef89 commit 4579cfb
Show file tree
Hide file tree
Showing 16 changed files with 96 additions and 33 deletions.
2 changes: 1 addition & 1 deletion src/config/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ configuration.findAccount = Account.findAccount;
const oidc = new Provider(process.env.api_url || 'http://localhost:3001', configuration);
oidc.proxy = true;

var domains = [/\.healthdatagateway\.org$/, process.env.homeURL];
var domains = [/\.healthdatagateway\.org$/, /\.hdruk\.dev$/, process.env.homeURL];

var rx = /^((http|https)+:\/\/[a-z]+)\.([^/]*)/;
var arr = rx.exec(process.env.homeURL);
Expand Down
23 changes: 11 additions & 12 deletions src/resources/auth/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,18 +127,6 @@ const getTeams = async () => {
return teams;
};

const userIsTeamManager = () => async (req, res, next) => {
const { user, params } = req;

const members = await TeamModel.findOne({ _id: params.id }, { _id: 0, members: { $elemMatch: { memberid: user._id } } }).lean();
if (!isEmpty(members) && members.members[0].roles.includes(constants.roleTypes.MANAGER)) return next();

return res.status(401).json({
status: 'error',
message: 'Unauthorised to perform this action.',
});
};

const catchLoginErrorAndRedirect = (req, res, next) => {
if (req.auth.err || !req.auth.user) {
if (req.auth.err === 'loginError') {
Expand Down Expand Up @@ -214,6 +202,17 @@ const loginAndSignToken = (req, res, next) => {
});
};

const userIsTeamManager = () => async (req, res, next) => {
const { user, params } = req;
const members = await TeamModel.findOne({ _id: params.id }, { _id: 0, members: { $elemMatch: { memberid: user._id } } }).lean();
if ((!isEmpty(members) && members.members[0].roles.includes(constants.roleTypes.MANAGER)) || user.role === 'Admin') return next();

return res.status(401).json({
status: 'error',
message: 'Unauthorised to perform this action.',
});
};

function isUserMemberOfTeamById(user, teamId) {
let { teams } = user;
return teams.filter(team => !isNull(team.publisher)).some(team => team.publisher._id.equals(teamId));
Expand Down
1 change: 1 addition & 0 deletions src/resources/datarequest/datarequest.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ export default class DataRequestController extends Controller {
dataRequestId: accessRecord._id,
createdDate: accessRecord.createdAt,
questionBank: accessRecord.questionAnswers,
files: accessRecord.files,
},
darIntegration: publisherDetails['dar-integration'],
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import DatarequestschemaController from './datarequest.schema.controller';
import { datarequestschemaService } from './dependency';
import { utils } from '../../auth';
import { ROLES } from '../../user/user.roles';
import constants from '../../utilities/constants.util';

const datarequestschemaController = new DatarequestschemaController(datarequestschemaService);

Expand Down Expand Up @@ -39,8 +40,9 @@ const authorizeUpdate = async (req, res, next) => {
}

const authorised = isUserMemberOfTeam(requestingUser, datarequestschema.publisher);
const isAdminUser = requestingUser.teams.map(team => team.type).includes(constants.teamTypes.ADMIN);

if (!authorised) {
if (!authorised && !isAdminUser) {
return res.status(401).json({
success: false,
message: 'You are not authorised to perform this action',
Expand Down

This file was deleted.

1 change: 1 addition & 0 deletions src/resources/dataset/datasetfiles/dummy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "reasonForExistence": "I live so this folder will live" }
4 changes: 2 additions & 2 deletions src/resources/message/message.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module.exports = {
// POST /api/v1/messages
createMessage: async (req, res) => {
try {
const { _id: createdBy, firstname, lastname } = req.user;
const { _id: createdBy, firstname, lastname, isServiceAccount = false } = req.user;
let { messageType = 'message', topic = '', messageDescription, relatedObjectIds, firstMessage } = req.body;
let topicObj = {};
let team, publisher, userType;
Expand Down Expand Up @@ -188,7 +188,7 @@ module.exports = {

// publish the message to GCP PubSub
const cacheEnabled = parseInt(process.env.CACHE_ENABLED) || 0;
if(cacheEnabled) {
if (cacheEnabled && !isServiceAccount) {
let publisherDetails = await PublisherModel.findOne({ _id: ObjectId(tools[0].publisher._id) }).lean();

if (publisherDetails['dar-integration']['enabled']) {
Expand Down
13 changes: 13 additions & 0 deletions src/resources/publisher/publisher.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,19 @@ export default class PublisherController extends Controller {
}
}

async updateDataUseWidget(req, res) {
try {
await this.publisherService.updateDataUseWidget(req.params.id, req.body).then(() => {
return res.status(200).json({ success: true });
});
} catch (err) {
return res.status(500).json({
success: false,
message: 'An error occurred updating data use widget settings',
});
}
}

async updateDataRequestModalContent(req, res) {
try {
await this.publisherService.updateDataRequestModalContent(req.params.id, req.user.id, req.body.content).then(() => {
Expand Down
8 changes: 8 additions & 0 deletions src/resources/publisher/publisher.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ const PublisherSchema = new Schema(
accessRequestCost: String,
dataUseLimitation: [String],
dataUseRequirements: [String],
dataUse: {
widget: {
enabled: { type: Boolean, default: false },
accepted: { type: Boolean, default: false },
acceptedByUserId: String,
acceptedDate: Date,
},
},
questionBank: {
enabled: { type: Boolean, default: false },
},
Expand Down
7 changes: 7 additions & 0 deletions src/resources/publisher/publisher.route.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import passport from 'passport';
import { logger } from '../utilities/logger';
import PublisherController from './publisher.controller';
import { publisherService, workflowService, dataRequestService, amendmentService } from './dependency';
import { userIsTeamManager } from '../auth/utils';
import { utils } from '../auth';

const logCategory = 'Publisher';
Expand Down Expand Up @@ -55,6 +56,12 @@ router.get(
(req, res) => publisherController.getPublisherWorkflows(req, res)
);

// @route PATCH /api/publishers/:id/dataUseWidget
// @desc Update data use widget settings (terms and conditions)
// @access Public
router.patch('/:id/dataUseWidget', passport.authenticate('jwt'), utils.userIsTeamManager(), (req, res) =>
publisherController.updateDataUseWidget(req, res)
);
router.patch('/dataRequestModalContent/:id', passport.authenticate('jwt'), utils.userIsTeamManager(), (req, res) =>
publisherController.updateDataRequestModalContent(req, res)
);
Expand Down
16 changes: 16 additions & 0 deletions src/resources/publisher/publisher.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,22 @@ export default class PublisherService {
return filteredApplications;
}

async updateDataUseWidget(publisherId, content) {
const publisher = await this.publisherRepository.getPublisher(publisherId);
const data = { ...publisher.publisherDetails.dataUse.widget, ...content };
await this.publisherRepository.updateByQuery(
{ _id: publisherId },
{
'publisherDetails.dataUse': {
widget: {
...data,
acceptedDate: Date.now(),
},
},
}
);
}

async update(document, body = {}) {
return this.publisherRepository.update(document, body);
}
Expand Down
9 changes: 6 additions & 3 deletions src/resources/questionbank/questionbank.route.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { questionbankService } from './dependency';
import { datarequestschemaService } from './../datarequest/schema/dependency';
import { logger } from '../utilities/logger';
import { isUserMemberOfTeamById, isUserMemberOfTeamByName } from '../auth/utils';
import constants from '../utilities/constants.util';

const router = express.Router();
const questionbankController = new QuestionbankController(questionbankService);
Expand All @@ -24,8 +25,9 @@ const authorizeViewRequest = (req, res, next) => {
const { publisherId } = req.params;

const authorised = isUserMemberOfTeamById(requestingUser, publisherId);
const isAdminUser = requestingUser.teams.map(team => team.type).includes(constants.teamTypes.ADMIN);

if (!authorised) {
if (!authorised && !isAdminUser) {
return res.status(401).json({
success: false,
message: 'You are not authorised to perform this action',
Expand Down Expand Up @@ -57,8 +59,9 @@ const authorizePostRequest = async (req, res, next) => {
}

const authorised = isUserMemberOfTeamByName(requestingUser, dataRequestSchema.publisher);
const isAdminUser = requestingUser.teams.map(team => team.type).includes(constants.teamTypes.ADMIN);

if (!authorised) {
if (!authorised && !isAdminUser) {
return res.status(401).json({
success: false,
message: 'You are not authorised to perform this action',
Expand All @@ -82,7 +85,7 @@ router.get(
(req, res) => questionbankController.getQuestionbank(req, res)
);

// @route POST /api/v1/questionbanks
// @route POST /api/v1/questionbank/schemaId
// @desc Activate a draft schema creating a jsonSchema from masterSchema
// @access Public
router.post('/:schemaId', passport.authenticate('jwt'), validatePostRequest, authorizePostRequest, (req, res) =>
Expand Down
15 changes: 14 additions & 1 deletion src/resources/search/search.repository.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,14 +313,27 @@ export async function getObjectResult(type, searchAll, searchQuery, startIndex,
'datasetv2.summary.publisher.name': 1,
'datasetv2.summary.publisher.logo': 1,
'datasetv2.summary.publisher.memberOf': 1,
'datasetv2.provenance.temporal.accrualPeriodicity': 1,

'persons.id': 1,
'persons.firstname': 1,
'persons.lastname': 1,

activeflag: 1,
counter: 1,
'datasetfields.metadataquality.weighted_quality_score': 1,

'datasetfields.metadataquality.weighted_quality_score': {
$convert: {
input: '$datasetfields.metadataquality.weighted_quality_score',
to: 'double',
onError: 0,
onNull: 0,
},
},

'datasetfields.metadataquality.weighted_quality_rating': 1,
'datasetfields.metadataquality.weighted_error_percent': 1,
'datasetfields.metadataquality.weighted_completeness_percent': 1,

latestUpdate: '$timestamps.updated',
relatedresources: {
Expand Down
5 changes: 4 additions & 1 deletion src/resources/team/team.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,7 @@ const getTeamsList = async (req, res) => {
'publisherDetails.name': 1,
'publisherDetails.memberOf': 1,
'publisherDetails.questionBank.enabled': 1,
'publisherDetails.dataUse.widget.enabled': 1,
})
.populate('users', { firstname: 1, lastname: 1 })
.sort({ updatedAt: -1 })
Expand Down Expand Up @@ -693,6 +694,7 @@ const addTeam = async (req, res) => {

publisher.name = `${inputSanitizer.removeNonBreakingSpaces(memberOf)} > ${inputSanitizer.removeNonBreakingSpaces(name)}`;
publisher.publisherDetails = {
...publisher.publisherDetails,
name: inputSanitizer.removeNonBreakingSpaces(name),
memberOf: inputSanitizer.removeNonBreakingSpaces(memberOf),
contactPoint: inputSanitizer.removeNonBreakingSpaces(contactPoint),
Expand Down Expand Up @@ -722,7 +724,8 @@ const addTeam = async (req, res) => {
// 11. Send email and notification to managers
await createNotifications(constants.notificationTypes.TEAMADDED, { recipients }, name, req.user, publisherId);

return res.status(200).json({ success: true, _id: newTeam._id });
return res.status(200).json(newPublisher);

} catch (err) {
console.error(err.message);
return res.status(500).json({
Expand Down
2 changes: 1 addition & 1 deletion src/resources/utilities/cloudStorage.util.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const fileStatus = {
UPLOADED: 'UPLOADED',
ERROR: 'ERROR',
SCANNED: 'SCANNED',
QUARANTINED: 'QUARANTINED'
QUARANTINED: 'QUARANTINED',
};

export const processFile = (file, id, uniqueId) =>
Expand Down
18 changes: 8 additions & 10 deletions src/utils/datasetonboarding.util.js
Original file line number Diff line number Diff line change
Expand Up @@ -884,8 +884,10 @@ const createNotifications = async (type, context) => {
team = await TeamModel.findOne({ _id: context.datasetv2.summary.publisher.identifier }).lean();

for (let member of team.members) {
if ((Array.isArray(member.roles) && member.roles.some(role => ['manager', 'metadata_editor'].includes(role)))
|| (typeof member.roles === 'string' && ['manager', 'metadata_editor'].includes(member.roles))) {
if (
(Array.isArray(member.roles) && member.roles.some(role => ['manager', 'metadata_editor'].includes(role))) ||
(typeof member.roles === 'string' && ['manager', 'metadata_editor'].includes(member.roles))
) {
teamMembers.push(member.memberid);
}
}
Expand Down Expand Up @@ -958,14 +960,10 @@ const createNotifications = async (type, context) => {
};

html = emailGenerator.generateMetadataOnboardingRejected(options);
let subject = (options.isFederated) ? 'Your federated dataset has been rejected and requires review' : 'Your dataset version has been reviewed and rejected';
emailGenerator.sendEmail(
teamMembersDetails,
constants.hdrukEmail,
subject,
html,
false
);
let subject = options.isFederated
? 'Your federated dataset has been rejected and requires review'
: 'Your dataset version has been reviewed and rejected';
emailGenerator.sendEmail(teamMembersDetails, constants.hdrukEmail, subject, html, false);
break;
case constants.notificationTypes.DATASETDUPLICATED:
// 1. Get user removed
Expand Down

0 comments on commit 4579cfb

Please sign in to comment.