feat: inplement auth for runs and runCases
This commit is contained in:
@@ -4,6 +4,7 @@ const defineMember = require('../models/members');
|
||||
const defineProject = require('../models/projects');
|
||||
const defineFolder = require('../models/folders');
|
||||
const defineCase = require('../models/cases');
|
||||
const defineRun = require('../models/runs');
|
||||
|
||||
function verifyEditableMiddleware(sequelize) {
|
||||
/**
|
||||
@@ -195,12 +196,99 @@ function verifyEditableMiddleware(sequelize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify user is reporter of the project by projectId
|
||||
* (have to be called after verifySignedIn() middleware)
|
||||
*/
|
||||
async function verifyProjectReporterFromProjectId(req, res, next) {
|
||||
const projectId = req.params.projectId || req.query.projectId;
|
||||
if (!projectId) {
|
||||
return res.status(400).json({ error: 'projectId is required' });
|
||||
}
|
||||
|
||||
const isReporterRet = await isReporter(projectId, req.userId);
|
||||
if (isReporterRet) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
return res.status(403).json({ error: 'Forbidden' });
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify user is reporter of the project by runId
|
||||
* (have to be called after verifySignedIn() middleware)
|
||||
*/
|
||||
async function verifyProjectReporterFromRunId(req, res, next) {
|
||||
const Run = defineRun(sequelize, DataTypes);
|
||||
|
||||
const runId = req.params.runId || req.query.runId;
|
||||
if (!runId) {
|
||||
return res.status(400).json({ error: 'runId is required' });
|
||||
}
|
||||
|
||||
// find project id from runId
|
||||
const run = await Run.findByPk(runId);
|
||||
const projectId = run && run.id;
|
||||
if (!projectId) {
|
||||
return res.status(404).send('failed to find projectId');
|
||||
}
|
||||
|
||||
const isReporterRet = await isReporter(projectId, req.userId);
|
||||
if (isReporterRet) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
return res.status(403).json({ error: 'Forbidden' });
|
||||
}
|
||||
|
||||
async function isReporter(projectId, userId) {
|
||||
const Project = defineProject(sequelize, DataTypes);
|
||||
const Member = defineMember(sequelize, DataTypes);
|
||||
Project.hasMany(Member, { foreignKey: 'projectId' });
|
||||
Member.belongsTo(Project, { foreignKey: 'projectId' });
|
||||
|
||||
const project = await Project.findOne({
|
||||
where: { id: projectId },
|
||||
include: [
|
||||
{
|
||||
model: Member,
|
||||
where: { userId: userId },
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
if (!project) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// owner has reporter or higher authority
|
||||
if (project.userId === userId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const member = project.Members && project.Members[0];
|
||||
if (member) {
|
||||
const managerRoleIndex = memberRoles.findIndex((entry) => entry.uid === 'manager');
|
||||
const developerRoleIndex = memberRoles.findIndex((entry) => entry.uid === 'developer');
|
||||
const reporterRoleIndex = memberRoles.findIndex((entry) => entry.uid === 'reporter');
|
||||
if (member.role === managerRoleIndex || member.role === developerRoleIndex || member.role === reporterRoleIndex) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return {
|
||||
verifyProjectOwner,
|
||||
verifyProjectManagerFromProjectId,
|
||||
verifyProjectDeveloperFromProjectId,
|
||||
verifyProjectDeveloperFromFolderId,
|
||||
verifyProjectDeveloperFromCaseId,
|
||||
verifyProjectReporterFromProjectId,
|
||||
verifyProjectReporterFromRunId,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ const defineMember = require('../models/members');
|
||||
const defineProject = require('../models/projects');
|
||||
const defineFolder = require('../models/folders');
|
||||
const defineCase = require('../models/cases');
|
||||
const defineRun = require('../models/runs');
|
||||
|
||||
function verifyVisibleMiddleware(sequelize) {
|
||||
/**
|
||||
@@ -88,6 +89,34 @@ function verifyVisibleMiddleware(sequelize) {
|
||||
return res.status(403).json({ error: 'Forbidden' });
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify user can read project by runId
|
||||
* (have to be called after verifySignedIn() middleware)
|
||||
*/
|
||||
async function verifyProjectVisibleFromRunId(req, res, next) {
|
||||
const Run = defineRun(sequelize, DataTypes);
|
||||
|
||||
const runId = req.params.runId || req.query.runId;
|
||||
if (!runId) {
|
||||
return res.status(400).json({ error: 'runId is required' });
|
||||
}
|
||||
|
||||
// find project id from runId
|
||||
const run = await Run.findByPk(runId);
|
||||
const projectId = run && run.id;
|
||||
if (!projectId) {
|
||||
return res.status(404).send('failed to find projectId');
|
||||
}
|
||||
|
||||
const isVisble = await isVisible(projectId, req.userId);
|
||||
if (isVisble) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
return res.status(403).json({ error: 'Forbidden' });
|
||||
}
|
||||
|
||||
async function isVisible(projectId, userId) {
|
||||
const Project = defineProject(sequelize, DataTypes);
|
||||
const Member = defineMember(sequelize, DataTypes);
|
||||
@@ -128,6 +157,7 @@ function verifyVisibleMiddleware(sequelize) {
|
||||
verifyProjectVisibleFromProjectId,
|
||||
verifyProjectVisibleFromFolderId,
|
||||
verifyProjectVisibleFromCaseId,
|
||||
verifyProjectVisibleFromRunId,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,14 @@ const { DataTypes, Op } = require('sequelize');
|
||||
|
||||
module.exports = function (sequelize) {
|
||||
const RunCase = defineRunCase(sequelize, DataTypes);
|
||||
const { verifySignedIn } = require('../../middleware/auth')(sequelize);
|
||||
const { verifyProjectReporterFromRunId } = require('../../middleware/verifyEditable')(sequelize);
|
||||
|
||||
router.post('/bulkdelete', async (req, res) => {
|
||||
router.post('/bulkdelete', verifySignedIn, verifyProjectReporterFromRunId, async (req, res) => {
|
||||
const recordsToDelete = req.body;
|
||||
|
||||
// TODO Instead of receiving a combination of runId and caseId from frontend,
|
||||
// receives only an array of caseId and constructs a pair from the query parameter runId
|
||||
try {
|
||||
const existingRunCases = await RunCase.findAll({
|
||||
where: {
|
||||
|
||||
@@ -4,11 +4,15 @@ const defineRunCase = require('../../models/runCases');
|
||||
const { DataTypes, Op } = require('sequelize');
|
||||
|
||||
module.exports = function (sequelize) {
|
||||
const { verifySignedIn } = require('../../middleware/auth')(sequelize);
|
||||
const { verifyProjectReporterFromRunId } = require('../../middleware/verifyEditable')(sequelize);
|
||||
const RunCase = defineRunCase(sequelize, DataTypes);
|
||||
|
||||
router.post('/bulknew', async (req, res) => {
|
||||
router.post('/bulknew', verifySignedIn, verifyProjectReporterFromRunId, async (req, res) => {
|
||||
const recordsToCreate = req.body;
|
||||
|
||||
// TODO Instead of receiving a combination of runId and caseId from frontend,
|
||||
// receives only an array of caseId and constructs a pair from the query parameter runId
|
||||
try {
|
||||
const existingRunCases = await RunCase.findAll({
|
||||
where: {
|
||||
|
||||
@@ -4,9 +4,11 @@ const defineRunCase = require('../../models/runCases');
|
||||
const { DataTypes } = require('sequelize');
|
||||
|
||||
module.exports = function (sequelize) {
|
||||
const { verifySignedIn } = require('../../middleware/auth')(sequelize);
|
||||
const { verifyProjectReporterFromRunId } = require('../../middleware/verifyEditable')(sequelize);
|
||||
const RunCase = defineRunCase(sequelize, DataTypes);
|
||||
|
||||
router.delete('/', async (req, res) => {
|
||||
router.delete('/', verifySignedIn, verifyProjectReporterFromRunId, async (req, res) => {
|
||||
const runId = req.query.runId;
|
||||
const caseId = req.query.caseId;
|
||||
|
||||
|
||||
@@ -4,9 +4,11 @@ const defineRunCase = require('../../models/runCases');
|
||||
const { DataTypes } = require('sequelize');
|
||||
|
||||
module.exports = function (sequelize) {
|
||||
const { verifySignedIn } = require('../../middleware/auth')(sequelize);
|
||||
const { verifyProjectReporterFromRunId } = require('../../middleware/verifyEditable')(sequelize);
|
||||
const RunCase = defineRunCase(sequelize, DataTypes);
|
||||
|
||||
router.put('/', async (req, res) => {
|
||||
router.put('/', verifySignedIn, verifyProjectReporterFromRunId, async (req, res) => {
|
||||
const runId = req.query.runId;
|
||||
const caseId = req.query.caseId;
|
||||
const status = req.query.status;
|
||||
|
||||
@@ -4,9 +4,11 @@ const defineRunCase = require('../../models/runCases');
|
||||
const { DataTypes } = require('sequelize');
|
||||
|
||||
module.exports = function (sequelize) {
|
||||
const { verifySignedIn } = require('../../middleware/auth')(sequelize);
|
||||
const { verifyProjectVisibleFromRunId } = require('../../middleware/verifyVisible')(sequelize);
|
||||
const RunCase = defineRunCase(sequelize, DataTypes);
|
||||
|
||||
router.get('/', async (req, res) => {
|
||||
router.get('/', verifySignedIn, verifyProjectVisibleFromRunId, async (req, res) => {
|
||||
const { runId } = req.query;
|
||||
|
||||
if (!runId) {
|
||||
|
||||
@@ -4,9 +4,11 @@ const defineRunCase = require('../../models/runCases');
|
||||
const { DataTypes } = require('sequelize');
|
||||
|
||||
module.exports = function (sequelize) {
|
||||
const { verifySignedIn } = require('../../middleware/auth')(sequelize);
|
||||
const { verifyProjectReporterFromRunId } = require('../../middleware/verifyEditable')(sequelize);
|
||||
const RunCase = defineRunCase(sequelize, DataTypes);
|
||||
|
||||
router.post('/', async (req, res) => {
|
||||
router.post('/', verifySignedIn, verifyProjectReporterFromRunId, async (req, res) => {
|
||||
const runId = req.query.runId;
|
||||
const caseId = req.query.caseId;
|
||||
|
||||
|
||||
@@ -4,9 +4,11 @@ const defineRun = require('../../models/runs');
|
||||
const { DataTypes } = require('sequelize');
|
||||
|
||||
module.exports = function (sequelize) {
|
||||
const { verifySignedIn } = require('../../middleware/auth')(sequelize);
|
||||
const { verifyProjectReporterFromRunId } = require('../../middleware/verifyEditable')(sequelize);
|
||||
const Run = defineRun(sequelize, DataTypes);
|
||||
|
||||
router.delete('/:runId', async (req, res) => {
|
||||
router.delete('/:runId', verifySignedIn, verifyProjectReporterFromRunId, async (req, res) => {
|
||||
const runId = req.params.runId;
|
||||
try {
|
||||
const testrun = await Run.findByPk(runId);
|
||||
|
||||
@@ -5,8 +5,10 @@ const { DataTypes } = require('sequelize');
|
||||
|
||||
module.exports = function (sequelize) {
|
||||
const Run = defineRun(sequelize, DataTypes);
|
||||
const { verifySignedIn } = require('../../middleware/auth')(sequelize);
|
||||
const { verifyProjectReporterFromRunId } = require('../../middleware/verifyEditable')(sequelize);
|
||||
|
||||
router.put('/:runId', async (req, res) => {
|
||||
router.put('/:runId', verifySignedIn, verifyProjectReporterFromRunId, async (req, res) => {
|
||||
const runId = req.params.runId;
|
||||
const updateRun = req.body;
|
||||
try {
|
||||
|
||||
@@ -4,9 +4,11 @@ const defineRun = require('../../models/runs');
|
||||
const { DataTypes } = require('sequelize');
|
||||
|
||||
module.exports = function (sequelize) {
|
||||
const { verifySignedIn } = require('../../middleware/auth')(sequelize);
|
||||
const { verifyProjectVisibleFromProjectId } = require('../../middleware/verifyVisible')(sequelize);
|
||||
const Run = defineRun(sequelize, DataTypes);
|
||||
|
||||
router.get('/', async (req, res) => {
|
||||
router.get('/', verifySignedIn, verifyProjectVisibleFromProjectId, async (req, res) => {
|
||||
const { projectId } = req.query;
|
||||
|
||||
if (!projectId) {
|
||||
|
||||
@@ -4,11 +4,14 @@ const defineRun = require('../../models/runs');
|
||||
const { DataTypes } = require('sequelize');
|
||||
|
||||
module.exports = function (sequelize) {
|
||||
const { verifySignedIn } = require('../../middleware/auth')(sequelize);
|
||||
const { verifyProjectReporterFromProjectId } = require('../../middleware/verifyEditable')(sequelize);
|
||||
const Run = defineRun(sequelize, DataTypes);
|
||||
|
||||
router.post('/', async (req, res) => {
|
||||
router.post('/', verifySignedIn, verifyProjectReporterFromProjectId, async (req, res) => {
|
||||
try {
|
||||
const { name, configurations, description, state, projectId } = req.body;
|
||||
const projectId = req.query.projectId;
|
||||
const { name, configurations, description, state } = req.body;
|
||||
if (!name || !projectId) {
|
||||
return res.status(400).json({ error: 'Name and projectId are required' });
|
||||
}
|
||||
|
||||
@@ -5,10 +5,12 @@ const defineRunCase = require('../../models/runCases');
|
||||
const { DataTypes, literal } = require('sequelize');
|
||||
|
||||
module.exports = function (sequelize) {
|
||||
const { verifySignedIn } = require('../../middleware/auth')(sequelize);
|
||||
const { verifyProjectVisibleFromRunId } = require('../../middleware/verifyVisible')(sequelize);
|
||||
const Run = defineRun(sequelize, DataTypes);
|
||||
const RunCase = defineRunCase(sequelize, DataTypes);
|
||||
|
||||
router.get('/:runId', async (req, res) => {
|
||||
router.get('/:runId', verifySignedIn, verifyProjectVisibleFromRunId, async (req, res) => {
|
||||
const runId = req.params.runId;
|
||||
|
||||
if (!runId) {
|
||||
|
||||
Reference in New Issue
Block a user