* Finish task #8122,#8117,#8115,#8114,#8113.

This commit is contained in:
Yagami
2020-10-16 16:45:55 +08:00
parent 55e1126f0b
commit f21ea4477f
4 changed files with 223 additions and 117 deletions
+2 -2
View File
@@ -1676,8 +1676,8 @@ EOD;
if(!empty($app->user->admin) || strpos($app->company->admins, ",{$app->user->account},") !== false) return true;
/* If is the program admin, have all program privs. */
$inProgram = isset($lang->navGroup->$module) && $lang->navGroup->$module == 'program';
if($inProgram && strpos(",{$app->user->rights['programs']},", ",{$app->session->PRJ},") !== false) return true;
$inProject = isset($lang->navGroup->$module) && $lang->navGroup->$module == 'project';
if($inProject && strpos(",{$app->user->rights['projects']},", ",{$app->session->PRJ},") !== false) return true;
/* If not super admin, check the rights. */
$rights = $app->user->rights['rights'];
+2 -2
View File
@@ -100,7 +100,7 @@ $lang->program->PRJAclList['open'] = "公开(有项目视图权限,即可
$lang->program->PRJAclList['private'] = "私有(项目团队成员和干系人可访问)";
$lang->program->PGMPRJAclList['open'] = "全部公开(有项目视图权限,即可访问)";
$lang->program->PGMPRJAclList['openinside'] = "项目集内公开(项目集负责人和干系人,即可访问)";
$lang->program->PGMPRJAclList['openinside'] = "项目集内公开(所有上级项目集负责人和干系人,本项目团队成员和干系人可访问)";
$lang->program->PGMPRJAclList['private'] = "私有(项目团队成员和干系人可访问)";
$lang->program->PRJAuthList['extend'] = '继承(取项目权限与组织权限的并集)';
@@ -212,7 +212,7 @@ $lang->program->PGMAclList['open'] = "公开(有项目集视图权限,即
$lang->program->PGMAclList['private'] = "私有(项目集负责人和干系人可访问)";
$lang->program->subPGMAclList['open'] = "全部公开(有项目集视图权限,即可访问)";
$lang->program->subPGMAclList['openinside'] = "项目集内公开 (所有上级项目集干系人,即可访问)";
$lang->program->subPGMAclList['openinside'] = "项目集内公开 (所有上级项目集干系人、本项目集负责人和干系人可访问)";
$lang->program->subPGMAclList['private'] = "私有(本项目集负责人和干系人可访问)";
$lang->program->PGMAuthList['extend'] = '继承(取项目权限与组织权限的并集)';
+4 -4
View File
@@ -389,7 +389,7 @@ class projectModel extends model
$this->dao->insert(TABLE_DOCLIB)->data($lib)->exec();
$this->loadModel('user');
if($project->acl != 'open') $this->user->updateUserView($projectID, 'project');
if($project->acl != 'open') $this->user->updateUserView($projectID, 'sprint');
if(isset($_POST['products'])) $this->user->updateUserView($this->post->products, 'product');
if(!dao::isError()) $this->loadModel('score')->create('program', 'createguide', $projectID);
@@ -457,7 +457,7 @@ class projectModel extends model
}
/* Fix bug#3074, Update views for team members. */
$this->loadModel('user')->updateUserView($projectID, 'project', $changedAccounts);
$this->loadModel('user')->updateUserView($projectID, 'sprint', $changedAccounts);
$products = $this->getProducts($projectID, false);
if($products) $this->user->updateUserView(array_keys($products), 'product', $changedAccounts);
@@ -540,7 +540,7 @@ class projectModel extends model
}
}
}
$this->user->updateUserView($projectID, 'project', $changedAccounts);
$this->user->updateUserView($projectID, 'sprint', $changedAccounts);
if(dao::isError()) die(js::error('project#' . $projectID . dao::getError(true)));
$allChanges[$projectID] = common::createChanges($oldProject, $project);
@@ -3264,7 +3264,7 @@ class projectModel extends model
*/
public function updateUserView($projectID)
{
$this->loadModel('user')->updateUserView($projectID, 'project');
$this->loadModel('user')->updateUserView($projectID, 'sprint');
$products = $this->getProducts($projectID, $withBranch = false);
if(!empty($products)) $this->user->updateUserView(array_keys($products), 'product');
}
+215 -109
View File
@@ -827,63 +827,57 @@ class userModel extends model
->andWhere('t1.role')->ne('PRJadmin')
->andWhere('t1.role')->ne('limited')
->fetchAll();
/* Init variables. */
$acls = array();
$viewAllow = false;
$programAllow = false;
$projectAllow = false;
$productAllow = false;
$sprintAllow = false;
$stageAllow = false;
$viewAllow = false;
$actionAllow = false;
foreach($groups as $group)
{
$acl = json_decode($group->acl, true);
if($group->PRJ)
if(empty($group->acl))
{
if(empty($group->acl))
{
$projectAllow = true;
$productAllow = true;
$viewAllow = true;
$actionAllow = true;
break;
}
if(empty($acl['projects'])) $projectAllow = true;
if(empty($acl['products'])) $productAllow = true;
if(empty($acl['views'])) $viewAllow = true;
if(!isset($acl['actions'])) $actionAllow = true;
if(empty($acls) and !empty($acl))
{
$acls = $acl;
continue;
}
if(!empty($acl['projects'])) $acls['projects'] = !empty($acls['projects']) ? array_merge($acls['projects'], $acl['projects']) : $acl['projects'];
if(!empty($acl['products'])) $acls['products'] = !empty($acls['products']) ? array_merge($acls['products'], $acl['products']) : $acl['products'];
if(!empty($acl['views'])) $acls['views'] = array_merge($acls['views'], $acl['views']);
if(!empty($acl['actions'])) $acls['actions'] = !empty($acls['actions']) ? ($acl['actions'] + $acls['actions']) : $acl['actions'];
$programAllow = true;
$projectAllow = true;
$productAllow = true;
$sprintAllow = false;
$stageAllow = false;
$viewAllow = true;
$actionAllow = true;
break;
}
else
if(empty($acl['programs'])) $programAllow = true;
if(empty($acl['projects'])) $projectAllow = true;
if(empty($acl['products'])) $productAllow = true;
if(empty($acl['sprints'])) $sprintAllow = true;
if(empty($acl['stages'])) $stageAllow = true;
if(empty($acl['views'])) $viewAllow = true;
if(!isset($acl['actions'])) $actionAllow = true;
if(empty($acls) and !empty($acl))
{
if(empty($group->acl))
{
$programAllow = true;
break;
}
if(empty($acl['programs'])) $programAllow = true;
if(empty($acls) and !empty($acl))
{
$acls = $acl;
continue;
}
if(!empty($acl['programs'])) $acls['programs'] = !empty($acls['programs']) ? array_merge($acls['programs'], $acl['programs']) : $acl['programs'];
$acls = $acl;
continue;
}
if(!empty($acl['programs'])) $acls['programs'] = !empty($acls['programs']) ? array_merge($acls['programs'], $acl['programs']) : $acl['programs'];
if(!empty($acl['projects'])) $acls['projects'] = !empty($acls['projects']) ? array_merge($acls['projects'], $acl['projects']) : $acl['projects'];
if(!empty($acl['products'])) $acls['products'] = !empty($acls['products']) ? array_merge($acls['products'], $acl['products']) : $acl['products'];
if(!empty($acl['sprints'])) $acls['sprints'] = !empty($acls['sprints']) ? array_merge($acls['sprints'], $acl['sprints']) : $acl['sprints'];
if(!empty($acl['stages'])) $acls['stages'] = !empty($acls['stages']) ? array_merge($acls['stages'], $acl['stages']) : $acl['stages'];
if(!empty($acl['views'])) $acls['views'] = array_merge($acls['views'], $acl['views']);
if(!empty($acl['actions'])) $acls['actions'] = !empty($acls['actions']) ? ($acl['actions'] + $acls['actions']) : $acl['actions'];
}
if($programAllow) $acls['programs'] = array();
if($projectAllow) $acls['projects'] = array();
if($productAllow) $acls['products'] = array();
if($sprintAllow) $acls['sprints'] = array();
if($stageAllow) $acls['stages'] = array();
if($viewAllow) $acls['views'] = array();
if($actionAllow) unset($acls['actions']);
@@ -903,8 +897,8 @@ class userModel extends model
/* Get can manage programs by user. */
$PRJadminGroupID = $this->dao->select('id')->from(TABLE_GROUP)->where('role')->eq('PRJadmin')->fetch('id');
$canManagePrograms = $this->dao->select('PRJ')->from(TABLE_USERGROUP)->where('`group`')->eq($PRJadminGroupID)->andWhere('account')->eq($account)->fetch('PRJ');
return array('rights' => $rights, 'acls' => $acls, 'programs' => $canManagePrograms);
$canManageProjects = $this->dao->select('PRJ')->from(TABLE_USERGROUP)->where('`group`')->eq($PRJadminGroupID)->andWhere('account')->eq($account)->fetch('PRJ');
return array('rights' => $rights, 'acls' => $acls, 'projects' => $canManageProjects);
}
/**
@@ -1370,67 +1364,96 @@ class userModel extends model
$groups = $this->dao->select('`group`')->from(TABLE_USERGROUP)->where('account')->eq($account)->fetchPairs('group', 'group');
$groups = ',' . join(',', $groups) . ',';
static $allProducts, $allPrograms, $allProjects, $projectProducts, $teams;
if($allPrograms === null) $allPrograms = $this->dao->select('id,PO,PM,QD,RD,acl,whitelist')->from(TABLE_PROJECT)->where('type')->eq('project')->fetchAll('id');
/* Init objects.*/
static $allProducts, $allPrograms, $allProjects, $allSprints, $allStages, $projectProducts, $teams, $stakeholders;
if($allProducts === null) $allProducts = $this->dao->select('id,PO,QD,RD,createdBy,acl,whitelist')->from(TABLE_PRODUCT)->where('acl')->ne('open')->fetchAll('id');
if($allProjects === null) $allProjects = $this->dao->select('id,PO,PM,QD,RD,acl')->from(TABLE_PROJECT)->where('acl')->ne('open')->andWhere('type')->eq('project')->fetchAll('id');
if($allPrograms === null) $allPrograms = $this->dao->select('id,PO,PM,QD,RD,acl')->from(TABLE_PROJECT)->where('acl')->ne('open')->andWhere('type')->eq('program')->fetchAll('id');
if($allSprints === null) $allSprints = $this->dao->select('id,PO,PM,QD,RD,acl')->from(TABLE_PROJECT)->where('acl')->eq('private')->andWhere('type')->eq('sprint')->fetchAll('id');
if($allStages === null) $allStages = $this->dao->select('id,PO,PM,QD,RD,acl')->from(TABLE_PROJECT)->where('acl')->eq('private')->andWhere('type')->eq('stage')->fetchAll('id');
if($projectProducts === null)
{
$stmt = $this->dao->select('project,product')->from(TABLE_PROJECTPRODUCT)->query();
while($projectProduct = $stmt->fetch())
{
$projectProducts[$projectProduct->product][$projectProduct->project] = $projectProduct->project;
}
}
if($teams === null)
{
$stmt = $this->dao->select('root,account')->from(TABLE_TEAM)->where('type')->eq('project')->query();
$stmt = $this->dao->select('root,account')->from(TABLE_TEAM)->where('type')->in('project,sprint,stage')->query();
while($team = $stmt->fetch()) $teams[$team->root][$team->account] = $team->account;
}
if($stakeholders === null)
{
$stmt = $this->dao->select('objectID,account')->from(TABLE_STAKEHOLDER)->query();
while($stakeholder = $stmt->fetch()) $stakeholders[$stakeholder->objectID][$stakeholder->account] = $stakeholder->account;
}
$userView = new stdclass();
$userView->account = $account;
$userView->programs = array();
$programs = array();
if($isAdmin)
{
$userView->programs = join(',', array_keys($allPrograms));
}
else
{
foreach($allPrograms as $id => $program)
{
$programTeams = isset($teams[$id]) ? $teams[$id] : array();
if($this->checkProjectPriv($program, $account, $groups, $programTeams)) $programs[$id] = $id;
}
$userView->programs = join(',', $programs);
}
$allProducts = $this->dao->select('id,PO,QD,RD,createdBy,acl,whitelist')->from(TABLE_PRODUCT)->where('program')->in($programs)->fetchAll('id');
$allProjects = $this->dao->select('id,PO,PM,QD,RD,acl,whitelist')->from(TABLE_PROJECT)->where('parent')->in($programs)->fetchAll('id');
if($projectProducts === null)
{
$stmt = $this->dao->select('project,product')->from(TABLE_PROJECTPRODUCT)->query();
while($projectProduct = $stmt->fetch())
{
$projectProducts[$projectProduct->product][$projectProduct->project] = $projectProduct->project;
}
}
$userView->products = array();
$userView->projects = array();
$userView->sprints = array();
$userView->stages = array();
if($isAdmin)
{
{
$userView->programs = join(',', array_keys($allPrograms));
$userView->products = join(',', array_keys($allProducts));
$userView->projects = join(',', array_keys($allProjects));
}
else
{
$userView->sprints = join(',', array_keys($allSprints));
$userView->stages = join(',', array_keys($allStages));
}
else
{
$programs = array();
foreach($allPrograms as $id => $program)
{
$stakeholders = isset($stakeholders[$id]) ? $stakeholders[$id] : array();
if($this->checkProgramPriv($program, $account, $stakeholders)) $programs[$id] = $id;
}
$userView->programs = join(',', $programs);
$products = array();
foreach($allProducts as $id => $product)
{
if($this->checkProductPriv($product, $account, $groups, zget($projectProducts, $id, array()), $teams)) $products[$id] = $id;
}
{
$stakeholders = isset($stakeholders[$product->program]) ? $stakeholders[$product->program] : array();
if($this->checkProductPriv($product, $account, $groups, $teams, $stakeholders)) $products[$id] = $id;
}
$userView->products = join(',', $products);
$projects = array();
foreach($allProjects as $id => $project)
{
{
$projectTeams = isset($teams[$id]) ? $teams[$id] : array();
$stakeholders = isset($stakeholders[$id]) ? $stakeholders[$id] : array();
if($this->checkProjectPriv($project, $account, $groups, $projectTeams)) $projects[$id] = $id;
}
}
$userView->projects = join(',', $projects);
}
$sprints = array();
foreach($allSprints as $id => $sprint)
{
$sprintTeams = isset($teams[$id]) ? $teams[$id] : array();
$stakeholders = isset($stakeholders[$sprint->project]) ? $stakeholders[$sprint->project] : array();
if($this->checkSprintPriv($sprint, $account, $stakeholders, $sprintTeams)) $sprints[$id] = $id;
}
$userView->projects = join(',', $projects);
$stages = array();
foreach($allStages as $id => $stage)
{
$stageTeams = isset($teams[$id]) ? $teams[$id] : array();
$stakeholders = isset($stakeholders[$sprint->project]) ? $stakeholders[$sprint->project] : array();
if($this->checkStagePriv($project, $account, $stakeholders, $stageTeams)) $stages[$id] = $id;
}
$userView->stages = join(',', $stages);
}
$this->dao->replace(TABLE_USERVIEW)->data($userView)->exec();
}
@@ -1442,52 +1465,57 @@ class userModel extends model
*
* @param string $account
* @param array $acls
* @param string $programs
* @param string $projects
* @access public
* @return object
*/
public function grantUserView($account = '', $acls = array(), $programs = '')
public function grantUserView($account = '', $acls = array(), $projects = '')
{
if(empty($account)) $account = $this->session->user->account;
if(empty($account)) return array();
if(empty($acls) and !empty($this->session->user->rights['acls'])) $acls = $this->session->user->rights['acls'];
if(!$programs and isset($this->session->user->rights['programs'])) $programs = $this->session->user->rights['programs'];
if(!$projects and isset($this->session->user->rights['projects'])) $projects = $this->session->user->rights['projects'];
/* If userview is empty, init it.*/
$userView = $this->dao->select('*')->from(TABLE_USERVIEW)->where('account')->eq($account)->fetch();
if(empty($userView)) $userView = $this->computeUserView($account);
$openedPrograms = $this->dao->select('id')->from(TABLE_PROJECT)
->where('acl')->eq('open')
->andWhere('type')->eq('project')
->fetchAll('id');
/* Get opened projects, programs, products and set it to userview.*/
$openedPrograms = $this->dao->select('id')->from(TABLE_PROJECT)->where('acl')->eq('open')->andWhere('type')->eq('program')->fetchAll('id');
$openedProjects = $this->dao->select('id')->from(TABLE_PROJECT)->where('acl')->eq('open')->andWhere('type')->eq('project')->fetchAll('id');
$openedProducts = $this->dao->select('id')->from(TABLE_PRODUCT)->where('acl')->eq('open')->fetchAll('id');
$openedPrograms = join(',', array_keys($openedPrograms));
$openedProducts = join(',', array_keys($openedProducts));
$openedProjects = join(',', array_keys($openedProjects));
$openedPrograms = join(',', array_keys($openedPrograms));
$userView->programs = rtrim($userView->programs, ',') . ',' . $openedPrograms;
$userView->products = rtrim($userView->products, ',') . ',' . $openedProducts;
$userView->projects = rtrim($userView->projects, ',') . ',' . $openedProjects;
if(isset($_SESSION['user']->admin)) $isAdmin = $this->session->user->admin;
if(!isset($isAdmin)) $isAdmin = strpos($this->app->company->admins, ",{$account},") !== false;
if(!empty($acls['programs']) and !$isAdmin)
{
$grantPrograms = '';
/* If is program admin, set programID to userview. */
if($programs) $acls['programs'] = array_merge($acls['programs'], explode(',', $programs));
foreach($acls['programs'] as $programID)
{
if(strpos(",{$userView->programs},", ",{$programID},") !== false) $grantPrograms .= ",{$programID}";
}
$userView->programs = $grantPrograms;
}
$programIds = explode(',', $userView->programs);
$openedProducts = $this->dao->select('id')->from(TABLE_PRODUCT)->where('acl')->eq('open')->andWhere('program')->in($programIds)->fetchAll('id');
$openedProjects = $this->dao->select('id')->from(TABLE_PROJECT)->where('acl')->eq('open')->andWhere('parent')->in($programIds)->fetchAll('id');
$openedProducts = join(',', array_keys($openedProducts));
$openedProjects = join(',', array_keys($openedProjects));
$userView->projects = rtrim($userView->projects, ',') . ',' . $openedProjects;
$userView->products = rtrim($userView->products, ',') . ',' . $openedProducts;
if(!empty($acls['projects']) and !$isAdmin)
{
$grantProjects = '';
/* If is project admin, set projectID to userview. */
if($projects) $acls['projects'] = array_merge($acls['projects'], explode(',', $projects));
foreach($acls['projects'] as $projectID)
{
if(strpos(",{$userView->projects},", ",{$projectID},") !== false) $grantProjects .= ",{$projectID}";
}
$userView->projects = $grantProjects;
}
if(!empty($acls['products']) and !$isAdmin)
{
$grantProducts = '';
@@ -1497,19 +1525,41 @@ class userModel extends model
}
$userView->products = $grantProducts;
}
if(!empty($acls['projects']) and !$isAdmin)
/* Set opened sprints and stages into userview.*/
$openedSprints = $this->dao->select('id')->from(TABLE_PROJECT)->where('acl')->eq('open')->andWhere('type')->eq('sprint')->andWhere('project')->in($userView->projects)->fetchAll('id');
$openedStages = $this->dao->select('id')->from(TABLE_PROJECT)->where('acl')->eq('open')->andWhere('type')->eq('stage')->andWhere('project')->in($userView->projects)->fetchAll('id');
$openedSprints = join(',', array_keys($openedSprints));
$openedStages = join(',', array_keys($openedStages));
$userView->sprints = rtrim($userView->sprints, ',') . ',' . $openedSprints;
$userView->stages = rtrim($userView->stages, ',') . ',' . $openedStages;
if(!empty($acls['sprints']) and !$isAdmin)
{
$grantProjects = '';
foreach($acls['projects'] as $projectID)
$grantSprints= '';
foreach($acls['sprints'] as $sprintID)
{
if(strpos(",{$userView->projects},", ",{$projectID},") !== false) $grantProjects .= ",{$projectID}";
if(strpos(",{$userView->sprints},", ",{$sprintID},") !== false) $grantSprints .= ",{$sprintID}";
}
$userView->projects = $grantProjects;
$userView->sprints = $grantSprints;
}
if(!empty($acls['stages']) and !$isAdmin)
{
$grantStages = '';
foreach($acls['stages'] as $stageID)
{
if(strpos(",{$userView->stages},", ",{$stageID},") !== false) $grantStages .= ",{$stageID}";
}
$userView->stages = $grantStages;
}
$userView->products = trim($userView->products, ',');
$userView->programs = trim($userView->programs, ',');
$userView->projects = trim($userView->projects, ',');
$userView->sprints = trim($userView->sprints, ',');
$userView->stages = trim($userView->stages, ',');
return $userView;
}
@@ -1808,7 +1858,7 @@ class userModel extends model
$stage->project = $projectID;
}
/* Get self stakeholders.*/
/* Get parent project stakeholders.*/
$stakeholderGroup = $this->loadModel('stakeholder')->getStakeholderGroup($projectIdList);
/* Get auth users.*/
@@ -1877,7 +1927,7 @@ class userModel extends model
$sprint->project = $projectID;
}
/* Get self stakeholders.*/
/* Get parent project stakeholders.*/
$stakeholderGroup = $this->loadModel('stakeholder')->getStakeholderGroup($projectIdList);
/* Get auth users.*/
@@ -1958,9 +2008,35 @@ class userModel extends model
if(isset($teams[$account])) return true;
if(isset($stakeholders[$account])) return true;
/* Parent program managers. */
if($project->type == 'project' && $project->parent != 0 && $project->acl == 'openinside')
{
$path = trim($project->path, ",$project->id,");
$programs = $this->dao->select('id,openedBy,PM,PO,QD,RD')->from(TABLE_PROJECT)->where('id')->in($path)->fetchAll();
foreach($programs as $program)
{
if($program->PO == $account OR $program->QD == $account OR $program->RD == $account OR $program->PM == $account) return true;
}
}
return false;
}
/**
* Check stage priv.
*
* @param object $project
* @param string $account
* @param string $groups
* @param array $teams
* @access public
* @return bool
*/
public function checkStagePriv($stage, $account, $stakeholders, $teams)
{
return $this->checkProjectPriv($stage, $account, $stakeholders, $teams);
}
/**
* Check sprint priv.
*
@@ -2032,6 +2108,22 @@ class userModel extends model
$users += $stakeholders ? $stakeholders : array();
$users += $teams ? $teams : array();
/* Parent program managers. */
if($project->type == 'project' && $project->parent != 0 && $project->acl == 'openinside')
{
$path = trim($project->path, ",$project->id,");
$programs = $this->dao->select('id,openedBy,PM,PO,QD,RD')->from(TABLE_PROJECT)->where('id')->in($path)->fetchAll();
foreach($programs as $program)
{
$users[$program->openedBy] = $program->openedBy;
$users[$program->PM] = $program->PM;
$users[$program->PO] = $program->PO;
$users[$program->QD] = $program->QD;
$users[$program->RD] = $program->RD;
}
}
return $users;
}
@@ -2057,6 +2149,20 @@ class userModel extends model
return $users;
}
/**
* Get stage auth users.
*
* @param object $stage
* @param array $stakeholders
* @param array $teams
* @access public
* @return array
*/
public function getStageAuthUsers($stage, $stakeholders, $teams)
{
return $this->getProjectAuthUsers($stage, $stakeholders, $teams);
}
/**
* Get sprint auth users.
*