<commit_before>/**
 *  Copyright (C) 2014 3D Repo Ltd
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.ap
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

var express = require('express');
var router = express.Router({mergeParams: true});
var middlewares = require('../middlewares/middlewares');

var C = require("../constants");
var responseCodes = require('../response_codes.js');
var Issue = require('../models/issue');
var utils = require('../utils');
var multer = require("multer");
var config = require("../config.js");

var User = require('../models/user');
var ModelHelper = require('../models/helper/model');

var stringToUUID = utils.stringToUUID;

router.get('/issues/:uid.json', middlewares.issue.canView, findIssueById);
router.get('/issues/:uid/thumbnail.png', middlewares.issue.canView, getThumbnail);

router.get('/issues.json', middlewares.issue.canView, listIssues);
router.get('/issues.bcfzip', middlewares.issue.canView, getIssuesBCF);
router.post('/issues.bcfzip', middlewares.issue.canCreate, importBCF);

router.get('/issues/:uid/viewpoints/:vid/screenshot.png', middlewares.issue.canView, getScreenshot);
router.get('/issues/:uid/viewpoints/:vid/screenshotSmall.png', middlewares.issue.canView, getScreenshotSmall);
router.get('/revision/:rid/issues.json', middlewares.issue.canView, listIssues);
router.get('/revision/:rid/issues.bcfzip', middlewares.issue.canView, getIssuesBCF);
router.post('/revision/:rid/issues.bcfzip', middlewares.issue.canCreate, importBCF);

//router.get('/issues/:sid.json', middlewares.issue.canView, listIssuesBySID);
router.get("/issues.html", middlewares.issue.canView, renderIssuesHTML);

router.get("/revision/:rid/issues.html", middlewares.issue.canView, renderIssuesHTML);

router.post('/issues.json', middlewares.connectQueue, middlewares.issue.canCreate, storeIssue);
router.put('/issues/:issueId.json', middlewares.connectQueue, middlewares.issue.canComment, updateIssue);

router.post('/revision/:rid/issues.json', middlewares.connectQueue, middlewares.issue.canCreate, storeIssue);
router.put('/revision/:rid/issues/:issueId.json', middlewares.connectQueue, middlewares.issue.canComment, updateIssue);

function storeIssue(req, res, next){
	'use strict';

	let place = utils.APIInfo(req);
	//let data = JSON.parse(req.body.data);
	let data = req.body;
	data.owner = req.session.user.username;
	data.sessionId = req.headers[C.HEADER_SOCKET_ID];
	
	data.revId = req.params.rid;

	Issue.createIssue({account: req.params.account, model: req.params.model}, data).then(issue => {

		// let resData = {
		// 	_id: issue._id,
		// 	account: req.params.account, 
		// 	model: req.params.model, 
		// 	issue_id : issue._id, 
		// 	number : issue.number, 
		// 	created : issue.created, 
		// 	scribble: data.scribble,
		// 	issue: issue
		// };

		responseCodes.respond(place, req, res, next, responseCodes.OK, issue);

	}).catch(err => {
		responseCodes.respond(place, req, res, next, err.resCode || utils.mongoErrorToResCode(err), err.resCode ? {} : err);
	});
}

function updateIssue(req, res, next){
	'use strict';

	let place = utils.APIInfo(req);
	//let data = JSON.parse(req.body.data);
	let data = req.body;
	data.owner = req.session.user.username;
	data.requester = req.session.user.username;
	data.revId = req.params.rid;
	data.sessionId = req.headers[C.HEADER_SOCKET_ID];

	let dbCol = {account: req.params.account, model: req.params.model};
	let issueId = req.params.issueId;
	let action;

	Issue.findById(dbCol, utils.stringToUUID(issueId), { 'viewpoints.screenshot': 0, 'thumbnail.content': 0 }).then(issue => {

		if(!issue){
			return Promise.reject({ resCode: responseCodes.ISSUE_NOT_FOUND });
		}

		if(data.hasOwnProperty('comment') && data.edit){
			action = issue.updateComment(data.commentIndex, data);

		} else if(data.sealed) {
			action = issue.updateComment(data.commentIndex, data);

		} else if(data.commentIndex >= 0 && data.delete) {
			action = issue.removeComment(data.commentIndex, data);

		} else if (data.hasOwnProperty('comment')){
			action = issue.updateComment(null, data);
		
		} else if (data.hasOwnProperty('closed') && data.closed){
			action = Promise.reject('This action is deprecated, use PUT issues/id.json {"status": "closed"}');

		} else if (data.hasOwnProperty('closed') && !data.closed){
			action = Promise.reject('This action is deprecated, use PUT issues/id.json {"status": "closed"}');

		} else {
			
			action = User.findByUserName(req.params.account).then(dbUser => {

				const sub = dbUser.customData.billing.subscriptions.findByAssignedUser(req.session.user.username);
				const job = sub && sub.job;
				const accountPerm = dbUser.customData.permissions.findByUser(req.session.user.username);
				return ModelHelper.isUserAdmin(req.params.account, req.params.model, req.session.user.username).then( isAdmin =>{
					const isTSAdmin = accountPerm && accountPerm.permissions.indexOf(C.PERM_TEAMSPACE_ADMIN) !== -1;
					const sameRoleAsOwner = issue.creator_role === job && issue.creator_role && job; 
					const canEditIssue = sameRoleAsOwner || 
					req.session.user.username === issue.owner || isAdmin || isTSAdmin;
					
					console.log(sameRoleAsOwner, req.session.user.username === issue.owner, isAdmin, isTSAdmin);

					if(!canEditIssue){
						return Promise.reject(responseCodes.ISSUE_UPDATE_PERMISSION_DECLINED);
					} else {
						return issue.updateAttrs(data);
					}
				}).catch(err =>{
						return Promise.reject(responseCodes.ISSUE_UPDATE_FAILED);					
				});


			});
		}

		return action;

	}).then(issue => {
		console.log(issue);
		let resData = {
			_id: issueId,
			account: req.params.account,
			model: req.params.model,
			issue: issue,
			issue_id : issueId,
			number: issue.number,
			owner: data.hasOwnProperty('comment') ?  data.owner : issue.owner,
			created: issue.created
		};<commit_msg>ISSUE #498 remove debug logging<commit_after>/**
 *  Copyright (C) 2014 3D Repo Ltd
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.ap
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

var express = require('express');
var router = express.Router({mergeParams: true});
var middlewares = require('../middlewares/middlewares');

var C = require("../constants");
var responseCodes = require('../response_codes.js');
var Issue = require('../models/issue');
var utils = require('../utils');
var multer = require("multer");
var config = require("../config.js");

var User = require('../models/user');
var ModelHelper = require('../models/helper/model');

var stringToUUID = utils.stringToUUID;

router.get('/issues/:uid.json', middlewares.issue.canView, findIssueById);
router.get('/issues/:uid/thumbnail.png', middlewares.issue.canView, getThumbnail);

router.get('/issues.json', middlewares.issue.canView, listIssues);
router.get('/issues.bcfzip', middlewares.issue.canView, getIssuesBCF);
router.post('/issues.bcfzip', middlewares.issue.canCreate, importBCF);

router.get('/issues/:uid/viewpoints/:vid/screenshot.png', middlewares.issue.canView, getScreenshot);
router.get('/issues/:uid/viewpoints/:vid/screenshotSmall.png', middlewares.issue.canView, getScreenshotSmall);
router.get('/revision/:rid/issues.json', middlewares.issue.canView, listIssues);
router.get('/revision/:rid/issues.bcfzip', middlewares.issue.canView, getIssuesBCF);
router.post('/revision/:rid/issues.bcfzip', middlewares.issue.canCreate, importBCF);

//router.get('/issues/:sid.json', middlewares.issue.canView, listIssuesBySID);
router.get("/issues.html", middlewares.issue.canView, renderIssuesHTML);

router.get("/revision/:rid/issues.html", middlewares.issue.canView, renderIssuesHTML);

router.post('/issues.json', middlewares.connectQueue, middlewares.issue.canCreate, storeIssue);
router.put('/issues/:issueId.json', middlewares.connectQueue, middlewares.issue.canComment, updateIssue);

router.post('/revision/:rid/issues.json', middlewares.connectQueue, middlewares.issue.canCreate, storeIssue);
router.put('/revision/:rid/issues/:issueId.json', middlewares.connectQueue, middlewares.issue.canComment, updateIssue);

function storeIssue(req, res, next){
	'use strict';

	let place = utils.APIInfo(req);
	//let data = JSON.parse(req.body.data);
	let data = req.body;
	data.owner = req.session.user.username;
	data.sessionId = req.headers[C.HEADER_SOCKET_ID];
	
	data.revId = req.params.rid;

	Issue.createIssue({account: req.params.account, model: req.params.model}, data).then(issue => {

		// let resData = {
		// 	_id: issue._id,
		// 	account: req.params.account, 
		// 	model: req.params.model, 
		// 	issue_id : issue._id, 
		// 	number : issue.number, 
		// 	created : issue.created, 
		// 	scribble: data.scribble,
		// 	issue: issue
		// };

		responseCodes.respond(place, req, res, next, responseCodes.OK, issue);

	}).catch(err => {
		responseCodes.respond(place, req, res, next, err.resCode || utils.mongoErrorToResCode(err), err.resCode ? {} : err);
	});
}

function updateIssue(req, res, next){
	'use strict';

	let place = utils.APIInfo(req);
	//let data = JSON.parse(req.body.data);
	let data = req.body;
	data.owner = req.session.user.username;
	data.requester = req.session.user.username;
	data.revId = req.params.rid;
	data.sessionId = req.headers[C.HEADER_SOCKET_ID];

	let dbCol = {account: req.params.account, model: req.params.model};
	let issueId = req.params.issueId;
	let action;

	Issue.findById(dbCol, utils.stringToUUID(issueId), { 'viewpoints.screenshot': 0, 'thumbnail.content': 0 }).then(issue => {

		if(!issue){
			return Promise.reject({ resCode: responseCodes.ISSUE_NOT_FOUND });
		}

		if(data.hasOwnProperty('comment') && data.edit){
			action = issue.updateComment(data.commentIndex, data);

		} else if(data.sealed) {
			action = issue.updateComment(data.commentIndex, data);

		} else if(data.commentIndex >= 0 && data.delete) {
			action = issue.removeComment(data.commentIndex, data);

		} else if (data.hasOwnProperty('comment')){
			action = issue.updateComment(null, data);
		
		} else if (data.hasOwnProperty('closed') && data.closed){
			action = Promise.reject('This action is deprecated, use PUT issues/id.json {"status": "closed"}');

		} else if (data.hasOwnProperty('closed') && !data.closed){
			action = Promise.reject('This action is deprecated, use PUT issues/id.json {"status": "closed"}');

		} else {
			
			action = User.findByUserName(req.params.account).then(dbUser => {

				const sub = dbUser.customData.billing.subscriptions.findByAssignedUser(req.session.user.username);
				const job = sub && sub.job;
				const accountPerm = dbUser.customData.permissions.findByUser(req.session.user.username);
				return ModelHelper.isUserAdmin(req.params.account, req.params.model, req.session.user.username).then( isAdmin =>{
					const isTSAdmin = accountPerm && accountPerm.permissions.indexOf(C.PERM_TEAMSPACE_ADMIN) !== -1;
					const sameRoleAsOwner = issue.creator_role === job && issue.creator_role && job; 
					const canEditIssue = sameRoleAsOwner || 
					req.session.user.username === issue.owner || isAdmin || isTSAdmin;
					
					if(!canEditIssue){
						return Promise.reject(responseCodes.ISSUE_UPDATE_PERMISSION_DECLINED);
					} else {
						return issue.updateAttrs(data);
					}
				}).catch(err =>{
						return Promise.reject(responseCodes.ISSUE_UPDATE_FAILED);					
				});


			});
		}

		return action;

	}).then(issue => {
		let resData = {
			_id: issueId,
			account: req.params.account,
			model: req.params.model,
			issue: issue,
			issue_id : issueId,
			number: issue.number,
			owner: data.hasOwnProperty('comment') ?  data.owner : issue.owner,
			created: issue.created
		};
{'fraction_non_alphanumeric': 0.15022333672909646, 'fraction_numerical': 0.0018023665856907766, 'mean_word_length': 4.335284280936455, 'pattern_counts': {'":': 4, '<': 5, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4975121', 'n_tokens_mistral': 4446, 'n_tokens_neox': 4134, 'n_words': 860}