This commit is contained in:
liugang
2018-07-10 18:20:27 +08:00
12 changed files with 150 additions and 53 deletions
+1 -1
View File
@@ -2430,7 +2430,7 @@ class bugModel extends model
$canBatchResolve = common::hasPriv('bug', 'batchResolve');
$canBatchAssignTo = common::hasPriv('bug', 'batchAssignTo');
$canBatchAction = $canBatchEdit or $canBatchConfirm or $canBatchClose or $canBatchActivate or $canBatchChangeBranch or $canBatchChangeModule or $canBatchResolve or $canBatchAssignTo or $canBatchCancel;
$canBatchAction = $canBatchEdit or $canBatchConfirm or $canBatchClose or $canBatchActivate or $canBatchChangeBranch or $canBatchChangeModule or $canBatchResolve or $canBatchAssignTo;
$canView = common::hasPriv('bug', 'view');
$bugLink = inlink('view', "bugID=$bug->id");
+1 -1
View File
@@ -1363,7 +1363,7 @@ EOD;
if(strpos(",{$limitedProjects},", ",$objectID,") !== false) $limitedProject = true;
if(empty($app->user->rights['rights']['my']['limited']) && !$limitedProject) return true;
}
if(empty($app->user->rights['rights']['my']['limited'])) return true;
if(!is_null($method) && strpos($method, 'batch') === 0) return false;
if(!is_null($method) && strpos($method, 'link') === 0) return false;
+2 -1
View File
@@ -12,4 +12,5 @@
#menuEditor li > a .item-hidden-icon {display: none; margin-left: 3px;}
#menuEditor .dropdown-menu > li > a .item-hidden-icon {margin-left: 10px;}
#menuEditor li.menu-hidden > a .item-hidden-icon {display: inline-block;}
#menuEditor .nav > li.menu-hidden > a {opacity: .7; border: 1px dashed #ddd; background: rgba(0,0,0,.1); margin: 0 2px;}
#menuEditor .nav > li.menu-hidden > a {opacity: .7; border: 1px dashed #ddd; background: rgba(0,0,0,.1); margin: 0 2px;}
#menuEditor .nav > li.menu-hidden > a > .dropdown{display: inline-block;}
+104 -27
View File
@@ -35,11 +35,16 @@ class docModel extends model
if($libID)
{
$lib = $this->getLibById($libID);
if($this->checkPriv($lib))
if(!$this->checkPrivLib($lib))
{
$type = $lib->product ? 'product' : 'custom';
$type = $lib->project ? 'project' : $type;
echo(js::alert($this->lang->doc->accessDenied));
$loginLink = $this->config->requestType == 'GET' ? "?{$this->config->moduleVar}=user&{$this->config->methodVar}=login" : "user{$this->config->requestFix}login";
if(strpos($this->server->http_referer, $loginLink) !== false) die(js::locate(inlink('index')));
die(js::locate('back'));
}
$type = $lib->product ? 'product' : 'custom';
$type = $lib->project ? 'project' : $type;
}
$mainLib = $type == 'custom' ? $this->lang->doc->customAB : $mainLib;
@@ -191,7 +196,7 @@ class docModel extends model
* @access public
* @return array
*/
public function getLibs($type = '')
public function getLibs($type = '', $extra = '')
{
if($type == 'product' or $type == 'project')
{
@@ -215,11 +220,49 @@ class docModel extends model
$libPairs = array();
while($lib = $stmt->fetch())
{
if($this->checkPriv($lib)) $libPairs[$lib->id] = $lib->name;
if($this->checkPrivLib($lib, $extra)) $libPairs[$lib->id] = $lib->name;
}
return $libPairs;
}
/**
* Get grant libs by doc.
*
* @access public
* @return array
*/
public function getPrivLibsByDoc()
{
static $libs;
if($libs === null)
{
$libs = array();
$stmt = $this->dao->select('lib,groups,users')->from(TABLE_DOC)->where('acl')->ne('open')->andWhere("(groups != '' or users != '')")->query();
$account = ",{$this->app->user->account},";
$userGroups = $this->app->user->groups;
while($lib = $stmt->fetch())
{
if(strpos(",$lib->users,", $account) !== false)
{
$libs[$lib->lib] = $lib->lib;
}
else
{
foreach($userGroups as $groupID)
{
if(strpos(",$lib->groups,", ",$groupID,") !== false)
{
$libs[$lib->lib] = $lib->lib;
break;
}
}
}
}
}
return $libs;
}
/**
* Create a library.
*
@@ -377,7 +420,7 @@ class docModel extends model
->fetchAll('id');
foreach($docs as $docID => $doc)
{
if(!$this->checkPriv($doc)) unset($docs[$docID]);
if(!$this->checkPrivDoc($doc)) unset($docs[$docID]);
}
$docs = $this->dao->select('*')->from(TABLE_DOC)
->where('id')->in(array_keys($docs))
@@ -481,7 +524,7 @@ class docModel extends model
$docIdList = array();
while($doc = $stmt->fetch())
{
if($this->checkPriv($doc)) $docIdList[$doc->id] = $doc->id;
if($this->checkPrivDoc($doc)) $docIdList[$doc->id] = $doc->id;
}
return $docIdList;
}
@@ -498,7 +541,7 @@ class docModel extends model
{
$doc = $this->dao->select('*')->from(TABLE_DOC)->where('id')->eq((int)$docID)->fetch();
if(!$doc) return false;
if(!$this->checkPriv($doc))
if(!$this->checkPrivDoc($doc))
{
echo(js::alert($this->lang->doc->accessDenied));
$loginLink = $this->config->requestType == 'GET' ? "?{$this->config->moduleVar}=user&{$this->config->methodVar}=login" : "user{$this->config->requestFix}login";
@@ -803,13 +846,14 @@ class docModel extends model
}
/**
* Check priv.
* Check priv for lib.
*
* @param object $object
* @param string $extra
* @access public
* @return bool
*/
public function checkPriv($object, $type = 'lib')
public function checkPrivLib($object, $extra = '')
{
if($this->app->user->admin) return true;
@@ -817,29 +861,26 @@ class docModel extends model
if(!empty($object->product) and !empty($acls['products']) and !in_array($object->product, $acls['products'])) return false;
if(!empty($object->project) and !empty($acls['projects']) and !in_array($object->project, $acls['projects'])) return false;
if(isset($object->lib))
{
static $libs;
if(empty($libs)) $libs = $this->getLibs('all');
if(!isset($libs[$object->lib])) return false;
}
if($object->acl == 'open') return true;
$account = ',' . $this->app->user->account . ',';
if(isset($object->addedBy) and $object->addedBy == $this->app->user->account) return true;
if($object->acl == 'private' and strpos(",$object->users,", $account) !== false) return true;
if(strpos(",$object->users,", $account) !== false) return true;
if($object->acl == 'custom')
{
if(strpos(",$object->users,", $account) !== false) return true;
$userGroups = $this->app->user->groups;
foreach($userGroups as $groupID)
{
if(strpos(",$object->groups,", ",$groupID,") !== false) return true;
}
}
if(isset($object->lib)) return false;
if(strpos($extra, 'notdoc') === false)
{
static $extraDocLibs;
if($extraDocLibs === null) $extraDocLibs = $this->getPrivLibsByDoc();
if(isset($extraDocLibs[$object->id])) return true;
}
if($object->project)
{
@@ -858,6 +899,42 @@ class docModel extends model
return false;
}
/**
* Check priv for doc.
*
* @param object $object
* @access public
* @return bool
*/
public function checkPrivDoc($object)
{
if($this->app->user->admin) return true;
static $extraDocLibs;
if($extraDocLibs === null) $extraDocLibs = $this->getPrivLibsByDoc();
static $libs;
if($libs === null) $libs = $this->getLibs('all', 'notdoc');
if(isset($libs[$object->lib]) and isset($extraDocLibs[$object->lib])) unset($extraDocLibs[$object->lib]);
if(!isset($libs[$object->lib]) and !isset($extraDocLibs[$object->lib])) return false;
if($object->acl == 'open' and !isset($extraDocLibs[$object->lib])) return true;
$account = ',' . $this->app->user->account . ',';
if(isset($object->addedBy) and $object->addedBy == $this->app->user->account) return true;
if(strpos(",$object->users,", $account) !== false) return true;
if($object->acl == 'custom')
{
$userGroups = $this->app->user->groups;
foreach($userGroups as $groupID)
{
if(strpos(",$object->groups,", ",$groupID,") !== false) return true;
}
}
return false;
}
/**
* Get all libs by type.
*
@@ -1017,7 +1094,7 @@ class docModel extends model
{
if($limit && $i > $limit) break;
$key = ($type == 'product' or $type == 'project') ? $type : 'id';
if($this->checkPriv($docLib) and !isset($libs[$docLib->$key]))
if($this->checkPrivLib($docLib) and !isset($libs[$docLib->$key]))
{
$libs[$docLib->$key] = $docLib->name;
$i++;
@@ -1062,7 +1139,7 @@ class docModel extends model
{
foreach($libs as $lib)
{
if($this->checkPriv($lib)) $buildGroups[$objectID][$lib->id] = $lib->name;
if($this->checkPrivLib($lib)) $buildGroups[$objectID][$lib->id] = $lib->name;
}
if($type == 'product' and isset($hasProject[$objectID]) and common::hasPriv('doc', 'allLibs')) $buildGroups[$objectID]['project'] = $this->lang->doclib->project;
if(common::hasPriv('doc', 'showFiles')) $buildGroups[$objectID]['files'] = $this->lang->doclib->files;
@@ -1104,7 +1181,7 @@ class docModel extends model
$libs = array();
foreach($objectLibs as $lib)
{
if($this->checkPriv($lib)) $libs[$lib->id] = $lib;
if($this->checkPrivLib($lib)) $libs[$lib->id] = $lib;
}
$itemCounts = $this->statLibCounts(array_keys($libs));
@@ -1154,7 +1231,7 @@ class docModel extends model
$docCounts = array();
foreach($docs as $doc)
{
if(!$this->checkPriv($doc)) continue;
if(!$this->checkPrivDoc($doc)) continue;
if(!isset($docCounts[$doc->lib])) $docCounts[$doc->lib] = 0;
$docCounts[$doc->lib] ++;
}
@@ -1272,7 +1349,7 @@ class docModel extends model
$docGroups = array();
foreach($docs as $doc)
{
if($this->checkPriv($doc)) $docGroups[$doc->module][$doc->id] = $doc;
if($this->checkPrivDoc($doc)) $docGroups[$doc->module][$doc->id] = $doc;
}
}
@@ -1326,7 +1403,7 @@ class docModel extends model
if(empty($libID)) return '';
$lib = $this->getLibById($libID);
if(!$this->checkPriv($lib))
if(!$this->checkPrivLib($lib))
{
echo(js::alert($this->lang->doc->accessDenied));
$loginLink = $this->config->requestType == 'GET' ? "?{$this->config->moduleVar}=user&{$this->config->methodVar}=login" : "user{$this->config->requestFix}login";
+8 -8
View File
@@ -542,13 +542,13 @@ class fileModel extends model
if($pos === false)
{
$data[$row][$col] .= "\n" . $line;
$data[$row][$col] = str_replace(',', ',', trim($data[$row][$col], '"'));
$data[$row][$col] = str_replace(',', ',', $data[$row][$col]);
continue;
}
else
{
$data[$row][$col] .= "\n" . substr($line, 0, $pos + 1);
$data[$row][$col] = trim(str_replace(',', ',', trim($data[$row][$col], '"')));
$data[$row][$col] .= "\n" . substr($line, 0, $pos);
$data[$row][$col] = trim(str_replace(',', ',', $data[$row][$col]));
$line = substr($line, $pos + 2);
$col++;
}
@@ -561,20 +561,20 @@ class fileModel extends model
/* the cell has '"', the delimiter is '",'. */
if($line{0} == '"')
{
$pos = strpos($line, '",');
$pos = strpos($line, '",');
if($pos === false)
{
$data[$row][$col] = $line;
$data[$row][$col] = substr($line, 1);
/* if line is not empty, then the data of cell is not end. */
if(strlen($line) >= 1) continue 2;
$line = '';
}
else
{
$data[$row][$col] = substr($line, 0, $pos + 1);
$data[$row][$col] = substr($line, 1, $pos - 1);
$line = substr($line, $pos + 2);
}
$data[$row][$col] = str_replace(',', ',', trim($data[$row][$col], '"'));
$data[$row][$col] = str_replace(',', ',', $data[$row][$col]);
}
else
{
@@ -593,7 +593,7 @@ class fileModel extends model
}
}
$data[$row][$col] = trim(str_replace(',', ',', trim($data[$row][$col], '"')));
$data[$row][$col] = trim(str_replace(',', ',', $data[$row][$col]));
$col++;
}
}
+7 -4
View File
@@ -78,10 +78,13 @@ $sessionString .= session_name() . '=' . session_id();
echo html::a($this->createLink('file', 'download', "fileID=$file->id") . $sessionString, $fileTitle . " ({$fileSize})", '_blank', "onclick=\"return downloadFile($file->id, '$file->extension', $imageWidth)\"");
echo "<span class='right-icon'>&nbsp; ";
common::printLink('file', 'edit', "fileID=$file->id", $lang->file->edit, '', "data-width='400' class='edit iframe text-primary' title='{$lang->file->edit}'");
if(common::hasPriv('file', 'delete')) echo html::a('###', $lang->delete, '', "class='text-primary' onclick='deleteFile($file->id)' title='$lang->delete'");
echo '</span>';
if(common::hasPriv($file->objectType, 'edit', $file->objectID))
{
echo "<span class='right-icon'>&nbsp; ";
common::printLink('file', 'edit', "fileID=$file->id", $lang->file->edit, '', "data-width='400' class='edit iframe text-primary' title='{$lang->file->edit}'");
if(common::hasPriv('file', 'delete')) echo html::a('###', $lang->delete, '', "class='text-primary' onclick='deleteFile($file->id)' title='$lang->delete'");
echo '</span>';
}
echo '</li>';
}
}
+10 -6
View File
@@ -337,6 +337,8 @@ $lang->resource->project->updateOrder = 'updateOrder';
$lang->resource->project->kanban = 'kanban';
$lang->resource->project->printKanban = 'printKanban';
$lang->resource->project->tree = 'tree';
$lang->resource->project->treeTask = 'treeTask';
$lang->resource->project->treeStory = 'treeStory';
$lang->resource->project->all = 'all';
$lang->resource->project->kanbanHideCols = 'kanbanHideCols';
$lang->resource->project->kanbanColsColor = 'kanbanColsColor';
@@ -382,12 +384,14 @@ $lang->project->methodOrder[170] = 'updateOrder';
$lang->project->methodOrder[175] = 'kanban';
$lang->project->methodOrder[180] = 'printKanban';
$lang->project->methodOrder[185] = 'tree';
$lang->project->methodOrder[190] = 'all';
$lang->project->methodOrder[195] = 'kanbanHideCols';
$lang->project->methodOrder[200] = 'kanbanColsColor';
$lang->project->methodOrder[205] = 'export';
$lang->project->methodOrder[210] = 'storyKanban';
$lang->project->methodOrder[215] = 'storySort';
$lang->project->methodOrder[190] = 'tree';
$lang->project->methodOrder[195] = 'tree';
$lang->project->methodOrder[200] = 'all';
$lang->project->methodOrder[205] = 'kanbanHideCols';
$lang->project->methodOrder[210] = 'kanbanColsColor';
$lang->project->methodOrder[215] = 'export';
$lang->project->methodOrder[220] = 'storyKanban';
$lang->project->methodOrder[225] = 'storySort';
/* Task. */
$lang->resource->task = new stdclass();
+8
View File
@@ -50,6 +50,14 @@ $('#end').on('change', function()
$("input:radio[name='delta']").attr("checked", false);
});
$('form').submit(function()
{
$('#submit').click(function()
{
return false;
});
})
$('#future').on('change', function()
{
if($(this).prop('checked'))
+2
View File
@@ -145,6 +145,8 @@ $lang->project->importPlanStories = 'Link Story From Plan';
$lang->project->importBug = 'Import Bugs';
$lang->project->updateOrder = 'Sort';
$lang->project->tree = 'Tree';
$lang->project->treeTask = 'Show Task';
$lang->project->treeStory = 'Show Story';
$lang->project->storyKanban = 'Story Kanban';
$lang->project->storySort = 'Sort Story';
$lang->project->importPlanStory = '' . $lang->projectCommon . ' is created!\nDo you want to iport stories linked to the plan?';
+2
View File
@@ -145,6 +145,8 @@ $lang->project->importPlanStories = '按计划关联需求';
$lang->project->importBug = '导入Bug';
$lang->project->updateOrder = '排序';
$lang->project->tree = '树状图';
$lang->project->treeTask = '只看任务';
$lang->project->treeStory = '只看需求';
$lang->project->storyKanban = '需求看板';
$lang->project->storySort = '需求排序';
$lang->project->importPlanStory = '创建' . $lang->projectCommon . '成功!\n是否导入计划关联的相关需求?';
+2 -2
View File
@@ -1112,7 +1112,7 @@ class testcase extends control
$case->stepExpect = '';
$case->real = '';
$result = isset($results[$case->id]) ? $results[$case->id] : array();
if($case->lastRunResult == 'fail' and !isset($relatedSteps[$case->id]) and !empty($result)) $case->real = $result[0]['real'];
$case->real = $result[0]['real'];
if(isset($relatedSteps[$case->id]))
{
$i = $childId = 0;
@@ -1133,7 +1133,7 @@ class testcase extends control
$sign = (in_array($this->post->fileType, array('html', 'xml'))) ? '<br />' : "\n";
$case->stepDesc .= $stepId . ". " . $step->desc . $sign;
$case->stepExpect .= $stepId . ". " . $step->expect . $sign;
if($case->lastRunResult == 'fail') $case->real .= $stepId . ". " . (isset($result[$step->id]) ? $result[$step->id]['real'] : '') . $sign;
$case->real .= $stepId . ". " . (isset($result[$step->id]) ? $result[$step->id]['real'] : '') . $sign;
$childId ++;
}
}
+3 -3
View File
@@ -767,9 +767,9 @@ class userModel extends model
if(!empty($acl['projects'])) $acls['projects'] = !empty($acls['projects']) ? array_merge($acls['projects'], $acl['projects']) : $acl['projects'];
}
if($productAllow && empty($acls['products'])) $acls['products'] = array();
if($projectAllow && empty($acls['projects'])) $acls['projects'] = array();
if($viewAllow && empty($acl['views'])) $acls['views'] = array();
if($productAllow) $acls['products'] = array();
if($projectAllow) $acls['projects'] = array();
if($viewAllow) $acls['views'] = array();
$sql = $this->dao->select('module, method')->from(TABLE_USERGROUP)->alias('t1')->leftJoin(TABLE_GROUPPRIV)->alias('t2')
->on('t1.group = t2.group')