Skip to content

Lint errors fix #48

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"mocha": true
},
"rules": {
"import/no-extraneous-dependencies": ["error", {"devDependencies": ["**/*.test.js", "**/*.spec.js"]}],
"import/no-extraneous-dependencies": ["error", {"devDependencies": ["**/*.test.js", "**/*.spec.js", "**/serviceMocks.js"]}],
max-len: ["error", { "ignoreComments": true, code: 120 }],
"valid-jsdoc": ["error", {
"requireReturn": true,
"requireReturnType": true,
Expand Down
3 changes: 2 additions & 1 deletion migrations/sync.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@


/* eslint-disable no-console */
/**
* Sync the database models to db tables.
*/
Expand All @@ -10,7 +11,7 @@
*/
// process.env.NODE_ENV = 'development'

require('./dist/models').default.sequelize.sync({ force: true })
require('../dist/models').default.sequelize.sync({ force: true })
.then(() => {
console.log('Database synced successfully');
process.exit();
Expand Down
4 changes: 1 addition & 3 deletions src/events/projects/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import config from 'config';
import querystring from 'querystring';
import util from '../../util';


/**
* Creates a lead in salesforce for the connect project.
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@


const app = require('./app');
const coreLib = require('tc-core-library-js');
const expressListRoutes = require('express-list-routes');
Expand Down
12 changes: 7 additions & 5 deletions src/middlewares/checkRole.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@
* @version 1.0
*/
import config from 'config';

const util = require('tc-core-library-js').util(config);

module.exports = function (roleName) {
return function (req, res, next) {
if (!req.authUser || !Array.isArray(req.authUser.roles) || req.authUser.roles.indexOf(roleName) == -1) {
module.exports = function defineCheckRole(roleName) {
return function checkRoleMiddleware(req, res, next) {
if (!req.authUser || !Array.isArray(req.authUser.roles) ||
req.authUser.roles.indexOf(roleName) === -1) {
return res.status(403)
.json(util.wrapErrorResponse(req.id, 403, 'You are not allowed to perform this action.'));
.json(util.wrapErrorResponse(req.id, 403, 'You are not allowed to perform this action.'));
}
next();
return next();
};
};
8 changes: 4 additions & 4 deletions src/mocks/addBillingAccount.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
/* eslint-disable max-len */

const http = require('https');
const _ = require('lodash');

const options = {
method: 'POST',
Expand All @@ -21,10 +24,7 @@ const req = http.request(options, (res) => {
chunks.push(chunk);
});

res.on('end', () => {
const body = Buffer.concat(chunks);
console.log(body.toString());
});
res.on('end', _.noop);
});
req.write('{\n "billingAccountId": 123456789\n}');
req.end();
8 changes: 4 additions & 4 deletions src/mocks/addCopilot.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
/* eslint-disable max-len */

const http = require('https');
const _ = require('lodash');

const options = {
method: 'POST',
Expand All @@ -21,10 +24,7 @@ const req = http.request(options, (res) => {
chunks.push(chunk);
});

res.on('end', () => {
const body = Buffer.concat(chunks);
console.log(body.toString());
});
res.on('end', _.noop);
});
req.write('{\n "copilotUserId": 123456789\n}');
req.end();
8 changes: 4 additions & 4 deletions src/mocks/createProject.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
/* eslint-disable max-len */

const http = require('https');
const _ = require('lodash');

const options = {
method: 'POST',
Expand All @@ -21,10 +24,7 @@ const req = http.request(options, (res) => {
chunks.push(chunk);
});

res.on('end', () => {
const body = Buffer.concat(chunks);
console.log(body.toString());
});
res.on('end', _.noop);
});

req.write('{\n "projectName": "Tony Test 1",\n "projectDescription": "test 1 description"\n}');
Expand Down
60 changes: 32 additions & 28 deletions src/mocks/direct.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@


import express from 'express';
import express, { Router } from 'express';
import _ from 'lodash';
import bodyParser from 'body-parser';
import config from 'config';
import coreLib from 'tc-core-library-js';
import expressRequestId from 'express-request-id';
import Router from 'express';
import https from 'https';
import path from 'path';
import fs from 'fs';
config.version = 'v3';

const util = require('tc-core-library-js').util(config);
const jwtAuth = require('tc-core-library-js').middleware.jwtAuthenticator;

config.version = 'v3';

const app = express();
app.use(bodyParser.urlencoded({
extended: false,
Expand All @@ -33,10 +36,9 @@ app.use(coreLib.middleware.logger(null, logger));
app.logger = logger;

const router = Router();
const jwtAuth = require('tc-core-library-js').middleware.jwtAuthenticator;
router.all('/v3/direct/projects*', jwtAuth());

let projectId = 2;
const projectId = 2;
const projects = {
1: {
projectName: 'test direct project1',
Expand All @@ -53,57 +55,59 @@ router.route('/v3/direct/projects')
app.logger.info('get direct projects');
res.json(util.wrapResponse(req.id, { projects }));
})
.post((req, res) => {
.post((freq, res) => {
const req = freq;
app.logger.info({ body: req.body }, 'create direct project');
const newId = projectId++;
const newId = projectId + 1;
req.body.id = newId;
projects[newId] = req.body;
res.json(util.wrapResponse(req.id, { projectId: newId }));
});

router.route('/v3/direct/projects/:projectId(\\d+)/billingaccount')
.post((req, res) => {
const projectId = req.params.projectId;
app.logger.info({ body: req.body, projectId }, 'add billingaccount to Project');
if (projects[projectId]) {
projects[projectId] = _.merge(projects[projectId], req.body);
res.json(util.wrapResponse(req.id, { billingAccountName: `mock account name for ${req.body.billingAccountId}` }));
const pId = req.params.projectId;
app.logger.info({ body: req.body, pId }, 'add billingaccount to Project');
if (projects[pId]) {
projects[pId] = _.merge(projects[pId], req.body);
res.json(util.wrapResponse(req.id, { billingAccountName: 'mock account name for ' +
`${req.body.billingAccountId}` }));
} else {
res.json(util.wrapErrorResponse(req.id, 404, `Cannot find direct project ${projectId}`));
res.json(util.wrapErrorResponse(req.id, 404, `Cannot find direct project ${pId}`));
}
});


router.route('/v3/direct/projects/:projectId(\\d+)/copilot')
.post((req, res) => {
const projectId = req.params.projectId;
app.logger.info({ body: req.body, projectId }, 'add copilot to Project');
if (projects[projectId]) {
projects[projectId] = _.merge(projects[projectId], req.body);
res.json(util.wrapResponse(req.id, { copilotProjectId: projectId }));
const pId = req.params.projectId;
app.logger.info({ body: req.body, pId }, 'add copilot to Project');
if (projects[pId]) {
projects[pId] = _.merge(projects[pId], req.body);
res.json(util.wrapResponse(req.id, { copilotProjectId: pId }));
} else {
res.json(util.wrapErrorResponse(req.id, 404, `Cannot find direct project ${projectId}`));
res.json(util.wrapErrorResponse(req.id, 404, `Cannot find direct project ${pId}`));
}
})
.delete((req, res) => {
const projectId = req.params.projectId;
app.logger.info({ body: req.body, projectId }, 'remove copilot from Project');
if (projects[projectId]) {
projects[projectId] = _.omit(projects[projectId], 'copilotUserId');
const pId = req.params.projectId;
app.logger.info({ body: req.body, pId }, 'remove copilot from Project');
if (projects[pId]) {
projects[pId] = _.omit(projects[pId], 'copilotUserId');
res.json(util.wrapResponse(req.id, true));
} else {
res.json(util.wrapErrorResponse(req.id, 404, `Cannot find direct project ${projectId}`));
res.json(util.wrapErrorResponse(req.id, 404, `Cannot find direct project ${pId}`));
}
});

router.route('/v3/direct/projects/:projectId(\\d+)/permissions')
.post((req, res) => {
const projectId = req.params.projectId;
app.logger.info({ body: req.body, projectId }, 'add permissions to Project');
if (projects[projectId]) {
const pId = req.params.projectId;
app.logger.info({ body: req.body, pId }, 'add permissions to Project');
if (projects[pId]) {
res.json();
} else {
res.json(util.wrapErrorResponse(req.id, 404, `Cannot find direct project ${projectId}`));
res.json(util.wrapErrorResponse(req.id, 404, `Cannot find direct project ${pId}`));
}
});

Expand Down
22 changes: 13 additions & 9 deletions src/models/project.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/* eslint-disable valid-jsdoc */

import { PROJECT_TYPE, PROJECT_STATUS, PROJECT_MEMBER_ROLE } from '../constants';
import _ from 'lodash';
import { PROJECT_TYPE, PROJECT_STATUS, PROJECT_MEMBER_ROLE } from '../constants';

module.exports = function (sequelize, DataTypes) {
var Project = sequelize.define('Project', {
module.exports = function defineProject(sequelize, DataTypes) {
const Project = sequelize.define('Project', {
id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true },
directProjectId: DataTypes.BIGINT,
billingAccountId: DataTypes.BIGINT,
Expand Down Expand Up @@ -65,15 +66,17 @@ module.exports = function (sequelize, DataTypes) {
return this.findAll({
where: {
$or: [
['EXISTS(SELECT * FROM "project_members" WHERE "deletedAt" IS NULL AND "projectId" = "Project".id AND "userId" = ? )', userId],
['"Project".status=? AND NOT EXISTS(SELECT * FROM "project_members" WHERE "deletedAt" IS NULL AND "projectId" = "Project".id AND "role" = ? )',
['EXISTS(SELECT * FROM "project_members" WHERE "deletedAt" ' +
'IS NULL AND "projectId" = "Project".id AND "userId" = ? )', userId],
['"Project".status=? AND NOT EXISTS(SELECT * FROM "project_members" WHERE ' +
' "deletedAt" IS NULL AND "projectId" = "Project".id AND "role" = ? )',
PROJECT_STATUS.REVIEWED, PROJECT_MEMBER_ROLE.COPILOT],
],
},
attributes: ['id'],
raw: true,
})
.then(res => _.map(res, 'id'));
.then(res => _.map(res, 'id'));
},
/**
* Get direct project id
Expand Down Expand Up @@ -139,10 +142,11 @@ module.exports = function (sequelize, DataTypes) {
logging: (str) => { log.debug(str); },
raw: true,
})
.then((count) => {
count = count[0].count;
.then((fcount) => {
const count = fcount[0].count;
// select project attributes
return sequelize.query(`SELECT ${attributesStr} FROM projects WHERE ${query} ORDER BY ${orderStr} LIMIT ${parameters.limit} OFFSET ${parameters.offset}`,
return sequelize.query(`SELECT ${attributesStr} FROM projects WHERE ${query} ORDER BY ` +
` ${orderStr} LIMIT ${parameters.limit} OFFSET ${parameters.offset}`,
{ type: sequelize.QueryTypes.SELECT,
logging: (str) => { log.debug(str); },
raw: true,
Expand Down
2 changes: 1 addition & 1 deletion src/models/projectAttachment.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@


module.exports = function (sequelize, DataTypes) {
module.exports = function defineProjectAttachment(sequelize, DataTypes) {
const ProjectAttachment = sequelize.define('ProjectAttachment', {
id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true },
title: { type: DataTypes.STRING, allowNull: true },
Expand Down
2 changes: 1 addition & 1 deletion src/models/projectHistory.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@


module.exports = function (sequelize, DataTypes) {
module.exports = function defineProjectHistory(sequelize, DataTypes) {
const ProjectHistory = sequelize.define('ProjectHistory', {
id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true },
projectId: { type: DataTypes.BIGINT, allowNull: false },
Expand Down
2 changes: 1 addition & 1 deletion src/models/projectMember.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import _ from 'lodash';
import { PROJECT_MEMBER_ROLE } from '../constants';

module.exports = function (sequelize, DataTypes) {
module.exports = function defineProjectMember(sequelize, DataTypes) {
const ProjectMember = sequelize.define('ProjectMember', {
id: { type: DataTypes.BIGINT, primaryKey: true, autoIncrement: true },
userId: DataTypes.BIGINT,
Expand Down
22 changes: 13 additions & 9 deletions src/permissions/index.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@


const Authorizer = require('tc-core-library-js').Authorizer;
const projectView = require('./project.view');
const projectEdit = require('./project.edit');
const projectDelete = require('./project.delete');
const projectMemberDelete = require('./projectMember.delete');

module.exports = () => {
Authorizer.setDeniedStatusCode(403);

// anyone can create a project
Authorizer.setPolicy('project.create', true);
Authorizer.setPolicy('project.view', require('./project.view'));
Authorizer.setPolicy('project.edit', require('./project.edit'));
Authorizer.setPolicy('project.delete', require('./project.delete'));
Authorizer.setPolicy('project.addMember', require('./project.view'));
Authorizer.setPolicy('project.removeMember', require('./projectMember.delete'));
Authorizer.setPolicy('project.addAttachment', require('./project.edit'));
Authorizer.setPolicy('project.updateAttachment', require('./project.edit'));
Authorizer.setPolicy('project.removeAttachment', require('./project.edit'));
Authorizer.setPolicy('project.updateMember', require('./project.edit'));
Authorizer.setPolicy('project.view', projectView);
Authorizer.setPolicy('project.edit', projectEdit);
Authorizer.setPolicy('project.delete', projectDelete);
Authorizer.setPolicy('project.addMember', projectView);
Authorizer.setPolicy('project.removeMember', projectMemberDelete);
Authorizer.setPolicy('project.addAttachment', projectEdit);
Authorizer.setPolicy('project.updateAttachment', projectEdit);
Authorizer.setPolicy('project.removeAttachment', projectEdit);
Authorizer.setPolicy('project.updateMember', projectEdit);
};
18 changes: 10 additions & 8 deletions src/permissions/project.delete.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@

/* globals Promise */

import _ from 'lodash';
import util from '../util';
import models from '../models';
import { USER_ROLE, PROJECT_MEMBER_ROLE } from '../constants';
import _ from 'lodash';

/**
* Super admin, Topcoder Managers are allowed to edit any project
* Rest can add members only if they are currently part of the project team.
* @param {Object} freq the express request instance
* @return {Promise} Returns a promise
*/
module.exports = req => new Promise((resolve, reject) => {
const projectId = _.parseInt(req.params.projectId);
module.exports = freq => new Promise((resolve, reject) => {
const projectId = _.parseInt(freq.params.projectId);
return models.ProjectMember.getActiveProjectMembers(projectId)
.then((members) => {
const req = freq;
req.context = req.context || {};
req.context.currentProjectMembers = members;
// check if auth user has acecss to this project
const hasAccess = util.hasRole(req, USER_ROLE.TOPCODER_ADMIN)
|| !_.isUndefined(_.find(members, m => m.userId === req.authUser.userId
&& (
m.role === PROJECT_MEMBER_ROLE.CUSTOMER && m.isPrimary
|| m.role === PROJECT_MEMBER_ROLE.MANAGER)));
const hasAccess = util.hasRole(req, USER_ROLE.TOPCODER_ADMIN) ||
!_.isUndefined(_.find(members, m => m.userId === req.authUser.userId &&
((m.role === PROJECT_MEMBER_ROLE.CUSTOMER && m.isPrimary) ||
m.role === PROJECT_MEMBER_ROLE.MANAGER)));

if (!hasAccess) {
// user is not an admin nor is a registered project member
Expand Down
Loading