diff --git a/db/update7.1.sql b/db/update7.1.sql new file mode 100644 index 0000000000..1be11a61b7 --- /dev/null +++ b/db/update7.1.sql @@ -0,0 +1,3 @@ +ALTER TABLE `zt_product` ADD `order` mediumint unsigned NOT NULL AFTER `createdVersion`; +ALTER TABLE `zt_project` ADD `order` mediumint unsigned NOT NULL AFTER `whitelist`; +ALTER TABLE `zt_group` ADD `acl` text COLLATE 'utf8_general_ci' NOT NULL; diff --git a/db/zentao.sql b/db/zentao.sql index 36c3cc9b0c..5b13d9c0ea 100644 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -285,6 +285,7 @@ CREATE TABLE IF NOT EXISTS `zt_group` ( `name` char(30) NOT NULL, `role` char(30) NOT NULL default '', `desc` char(255) NOT NULL default '', + `acl` text NOT NULL default '', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- DROP TABLE IF EXISTS `zt_grouppriv`; @@ -346,6 +347,8 @@ CREATE TABLE IF NOT EXISTS `zt_product` ( `createdBy` varchar(30) NOT NULL, `createdDate` datetime NOT NULL, `createdVersion` varchar(20) NOT NULL, + `order` mediumint(8) unsigned NOT NULL, + `name` varchar(90) NOT NULL, `deleted` enum('0','1') NOT NULL default '0', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; @@ -390,6 +393,7 @@ CREATE TABLE IF NOT EXISTS `zt_project` ( `team` varchar(30) NOT NULL, `acl` enum('open','private','custom') NOT NULL default 'open', `whitelist` varchar(255) NOT NULL, + `order` mediumint(8) unsigned NOT NULL, `deleted` enum('0','1') NOT NULL default '0', PRIMARY KEY (`id`), KEY `project` (`type`,`parent`,`begin`,`end`,`status`,`statge`,`pri`) diff --git a/module/common/control.php b/module/common/control.php index 9f01f6537b..8ac281c97c 100644 --- a/module/common/control.php +++ b/module/common/control.php @@ -85,15 +85,29 @@ class common extends control */ public static function hasPriv($module, $method) { - global $app; + global $app, $lang; /* Check is the super admin or not. */ $account = ',' . $app->user->account . ','; if(strpos($app->company->admins, $account) !== false) return true; /* If not super admin, check the rights. */ - $rights = $app->user->rights; - if(isset($rights[strtolower($module)][strtolower($method)])) return true; + $rights = $app->user->rights['rights']; + $acls = $app->user->rights['acls']; + $module = strtolower($module); + $method = strtolower($method); + if(isset($rights[$module][$method])) + { + if(empty($acls)) return true; + $menu = isset($lang->menugroup->$module) ? $lang->menugroup->$module : $module; + $menu = strtolower($menu); + if(!isset($lang->$menu->menu)) return true; + if($menu == 'my' or $menu == 'index' or $module == 'tree') return true; + if($module == 'company' and $method == 'dynamic') return true; + if($module == 'action' and $method == 'editcomment') return true; + if(!isset($acls['views'][$menu])) return false; + return true; + } return false; } diff --git a/module/common/model.php b/module/common/model.php index dc95c2c3b5..d3baa83cdc 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -454,28 +454,26 @@ class commonModel extends model /* Sort the subMenu according to menuOrder. */ if(isset($lang->$moduleName->menuOrder)) { - $menus = $submenus; + $menus = json_decode(json_encode($submenus), true); $submenus = new stdclass(); ksort($lang->$moduleName->menuOrder, SORT_ASC); - if(isset($menus->list)) + if(isset($menus['list'])) { - $submenus->list = $menus->list; - unset($menus->list); + $submenus->list = $menus['list']; + unset($menus['list']); } foreach($lang->$moduleName->menuOrder as $order) { - if(($order != 'list') && isset($menus->$order)) + if(($order != 'list') && isset($menus[$order])) { - $subOrder = $menus->$order; - unset($menus->$order); + $subOrder = $menus[$order]; + unset($menus[$order]); $submenus->$order = $subOrder; } } - foreach($menus as $key => $menu) - { - $submenus->$key = $menu; - } + + foreach($menus as $key => $menu) $submenus->$key = $menu; } /* The beginning of the menu. */ diff --git a/module/group/control.php b/module/group/control.php index 2f1ffb00b9..37cc443ac0 100644 --- a/module/group/control.php +++ b/module/group/control.php @@ -119,6 +119,34 @@ class group extends control $this->display(); } + /** + * manageView + * + * @param int $groupID + * @access public + * @return void + */ + public function manageView($groupID) + { + if($_POST) + { + $result = $this->group->updateView($groupID); + die(js::alert($result ? $this->lang->group->successSaved : $this->lang->group->errorNotSaved)); + } + + $group = $this->group->getById($groupID); + if($group->acl) $group->acl = json_decode($group->acl, true); + + $this->view->title = $this->lang->company->common . $this->lang->colon . $group->name . $this->lang->colon . $this->lang->group->manageView; + $this->view->position[] = $group->name; + $this->view->position[] = $this->lang->group->manageView; + + $this->view->group = $group; + $this->view->products = $this->loadModel('product')->getPairs(); + $this->view->projects = $this->loadModel('project')->getPairs(); + $this->display(); + } + /** * Manage privleges of a group. * diff --git a/module/group/css/manageview.css b/module/group/css/manageview.css new file mode 100644 index 0000000000..c676152bef --- /dev/null +++ b/module/group/css/manageview.css @@ -0,0 +1 @@ +.group-item {display:block; width:93px; float:left} diff --git a/module/group/js/manageview.js b/module/group/js/manageview.js new file mode 100644 index 0000000000..359b5b00e7 --- /dev/null +++ b/module/group/js/manageview.js @@ -0,0 +1,30 @@ +function setNoChecked() +{ + var noCheckValue = ''; + $(':checkbox').each(function(){ + if(!$(this).attr('checked') && $(this).next('span').attr('id') != undefined) noCheckValue = noCheckValue + ',' + $(this).next('span').attr('id'); + }) + $('#noChecked').val(noCheckValue); +} +function toggleProduct() +{ + $('#productBox').toggle($('#product').prop("checked")); +} + +function toggleProject() +{ + $('#projectBox').toggle($('#project').prop("checked")); +} + +$('input:checkbox[name^="allchecker"]').change(function() +{ + setTimeout(function(){toggleProduct(),toggleProject()}, 50); +}); +$('#product').change(function(){toggleProduct();}) +$('#project').change(function(){toggleProject();}) + +$(function() +{ + toggleProduct(); + toggleProject(); +}) diff --git a/module/group/lang/en.php b/module/group/lang/en.php index ccb62755f9..915df7901b 100644 --- a/module/group/lang/en.php +++ b/module/group/lang/en.php @@ -15,6 +15,7 @@ $lang->group->create = 'Create'; $lang->group->edit = 'Edit'; $lang->group->copy = 'Copy'; $lang->group->delete = 'Delete'; +$lang->group->manageView = 'Manage view'; $lang->group->managePriv = 'Privilege'; $lang->group->managePrivByGroup = 'Privilege'; $lang->group->managePrivByModule = 'Manage privilege by module'; @@ -25,6 +26,9 @@ $lang->group->unlinkMember = 'Remove member'; $lang->group->confirmDelete = 'Are you sure to delete this group?'; $lang->group->successSaved = 'Success saved.'; $lang->group->errorNotSaved = 'Not saved, please make sure you have selected some actions and groups.'; +$lang->group->visitProduct = 'Visit product'; +$lang->group->visitProject = 'Visit project'; +$lang->group->noticeVisit = 'All elected representatives have no access restrictions'; $lang->group->id = 'Id'; $lang->group->name = 'Name'; diff --git a/module/group/lang/zh-cn.php b/module/group/lang/zh-cn.php index c970aa457e..d8344b2d45 100644 --- a/module/group/lang/zh-cn.php +++ b/module/group/lang/zh-cn.php @@ -15,6 +15,7 @@ $lang->group->create = '新增分组'; $lang->group->edit = '编辑分组'; $lang->group->copy = '复制分组'; $lang->group->delete = '删除分组'; +$lang->group->manageView = '视图维护'; $lang->group->managePriv = '权限维护'; $lang->group->managePrivByGroup = '权限维护'; $lang->group->managePrivByModule = '按模块分配权限'; @@ -25,6 +26,9 @@ $lang->group->unlinkMember = '移除用户'; $lang->group->confirmDelete = '您确定删除该用户分组吗?'; $lang->group->successSaved = '成功保存'; $lang->group->errorNotSaved = '没有保存,请确认选择了权限数据。'; +$lang->group->visitProduct = '可访问的产品'; +$lang->group->visitProject = '可访问的项目'; +$lang->group->noticeVisit = '全不选代表没有访问限制'; $lang->group->id = '编号'; $lang->group->name = '分组名称'; diff --git a/module/group/model.php b/module/group/model.php index 11dd9d63cc..3d731e1627 100644 --- a/module/group/model.php +++ b/module/group/model.php @@ -256,6 +256,24 @@ class groupModel extends model return true; } + /** + * Update view priv + * + * @param int $groupID + * @access public + * @return bool + */ + public function updateView($groupID) + { + $actions = $this->post->actions; + if(!isset($actions['views']['product']) and isset($actions['products'])) unset($actions['products']); + if(!isset($actions['views']['project']) and isset($actions['projects'])) unset($actions['projects']); + + $actions = empty($actions) ? '' : json_encode($actions); + $this->dao->update(TABLE_GROUP)->set('acl')->eq($actions)->where('id')->eq($groupID)->exec(); + return dao::isError() ? false : true; + } + /** * Update privilege by module. * diff --git a/module/group/view/browse.html.php b/module/group/view/browse.html.php index 1e4891d41b..9ee1f380ec 100644 --- a/module/group/view/browse.html.php +++ b/module/group/view/browse.html.php @@ -29,7 +29,7 @@ group->name;?> group->desc;?> group->users;?> - actions;?> + actions;?> @@ -42,6 +42,7 @@ group->managepriv = $lang->group->managePrivByGroup;?> + id", '', 'list', 'eye-open');?> id", '', 'list', 'lock');?> group->managemember = $lang->group->manageMember;?> id", '', 'list', 'group', '', 'iframe', 'yes');?> diff --git a/module/group/view/manageview.html.php b/module/group/view/manageview.html.php new file mode 100644 index 0000000000..c736ccf867 --- /dev/null +++ b/module/group/view/manageview.html.php @@ -0,0 +1,58 @@ + + * @package group + * @version $Id: managepriv.html.php 1517 2011-03-07 10:02:57Z wwccss $ + * @link http://www.zentao.net + */ +?> + +
+ + + + + + + + + + + + + + + + + + + +
+ group->module;?> + + + menu as $menu):?> + + + +
+ +
+ +
selectAll . html::selectAll('', 'checkbox')?> + save); + echo html::linkButton($lang->goback, $this->createLink('group', 'browse')); + echo html::hidden('foo'); // Just a hidden var, to make sure $_POST is not empty. + echo $lang->group->noticeVisit; + ?> +
+
+ diff --git a/module/product/model.php b/module/product/model.php index 3cf8c0b1af..11c6c7feeb 100644 --- a/module/product/model.php +++ b/module/product/model.php @@ -97,6 +97,9 @@ class productModel extends model $account = ',' . $this->app->user->account . ','; if(strpos($this->app->company->admins, $account) !== false) return true; + $acls = $this->app->user->rights['acls']; + if(!empty($acls['products'])) return !in_array($product->id, $acls['products']) ? false : true; + /* Product is open, return true. */ if($product->acl == 'open') return true; diff --git a/module/project/model.php b/module/project/model.php index 0015555458..8261764666 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -29,6 +29,9 @@ class projectModel extends model $account = ',' . $this->app->user->account . ','; if(strpos($this->app->company->admins, $account) !== false) return true; + $acls = $this->app->user->rights['acls']; + if(!empty($acls['projects'])) return !in_array($project->id, $acls['projects']) ? false : true; + /* If project is open, return true. */ if($project->acl == 'open') return true; diff --git a/module/user/model.php b/module/user/model.php index 37a4749631..8e9502e6c6 100644 --- a/module/user/model.php +++ b/module/user/model.php @@ -538,22 +538,46 @@ class userModel extends model $rights = array(); if($account == 'guest') { + $acl = $this->dao->select('acl')->from(TABLE_GROUP)->where('name')->eq('guest')->fetch('acl'); + $acls = empty($acl) ? array() : json_decode($acl, true); + $sql = $this->dao->select('module, method')->from(TABLE_GROUP)->alias('t1')->leftJoin(TABLE_GROUPPRIV)->alias('t2') ->on('t1.id = t2.group')->where('t1.name')->eq('guest'); } else { + $groups = $this->dao->select('t1.acl')->from(TABLE_GROUP)->alias('t1') + ->leftJoin(TABLE_USERGROUP)->alias('t2')->on('t1.id=t2.group') + ->where('t2.account')->eq($account) + ->fetchAll(); + $acls = array(); + foreach($groups as $group) + { + if(empty($group->acl)) continue; + $acl = json_decode($group->acl, true); + if(empty($acls)) + { + $acls = $acl; + continue; + } + + $acls['views'] = array_merge($acls['views'], $acl['views']); + if(!empty($acl['products'])) $acls['products'] = !empty($acls['products']) ? array_merge($acls['products'], $acl['products']) : $acl['products']; + if(!empty($acl['projects'])) $acls['projects'] = !empty($acls['projects']) ? array_merge($acls['projects'], $acl['projects']) : $acl['projects']; + } + $sql = $this->dao->select('module, method')->from(TABLE_USERGROUP)->alias('t1')->leftJoin(TABLE_GROUPPRIV)->alias('t2') ->on('t1.group = t2.group') ->where('t1.account')->eq($account); } + $stmt = $sql->query(); - if(!$stmt) return $rights; + if(!$stmt) return array('rights' => $rights, 'acls' => $acls); while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $rights[strtolower($row['module'])][strtolower($row['method'])] = true; } - return $rights; + return array('rights' => $rights, 'acls' => $acls); } /**