diff --git a/db/update7.3.sql b/db/update7.3.sql
index d0bb6df09b..ac692dc0cd 100644
--- a/db/update7.3.sql
+++ b/db/update7.3.sql
@@ -27,4 +27,5 @@ ALTER TABLE `zt_story` ADD INDEX `product` (`product`, `module`, `type`, `pri`),
ALTER TABLE `zt_story` ADD `plan` text COLLATE 'utf8_general_ci' NOT NULL AFTER `module`;
UPDATE `zt_story` SET `plan`='' WHERE `plan`='0';
-LTER TABLE `zt_release` DROP INDEX `name`;
+ALTER TABLE `zt_release` DROP INDEX `name`;
+ALTER TABLE `zt_user` ADD `bindRanzhi` char(30) COLLATE 'utf8_general_ci' NOT NULL AFTER `locked`;
diff --git a/framework/router.class.php b/framework/router.class.php
index 9c5701968f..317cab0ed0 100755
--- a/framework/router.class.php
+++ b/framework/router.class.php
@@ -480,7 +480,7 @@ class router
{
foreach($_COOKIE as $cookieKey => $cookieValue)
{
- if(preg_match('/[^a-zA-Z0-9=_- ,`+\/\.]/', $cookieValue)) unset($_COOKIE[$cookieKey]);
+ if(preg_match('/[^a-zA-Z0-9=_\- ,`+\/\.]/', $cookieValue)) unset($_COOKIE[$cookieKey]);
}
}
diff --git a/module/common/model.php b/module/common/model.php
index e468b1cf9a..c4c3cedfa4 100644
--- a/module/common/model.php
+++ b/module/common/model.php
@@ -151,6 +151,7 @@ class commonModel extends model
if($module == 'block' and $method == 'main') return true;
if($module == 'sso' and $method == 'login') return true;
if($module == 'sso' and $method == 'logout') return true;
+ if($module == 'sso' and $method == 'bind') return true;
if($this->loadModel('user')->isLogon())
{
diff --git a/module/company/view/browse.html.php b/module/company/view/browse.html.php
index 23a6d5b0d2..1a9550751f 100644
--- a/module/company/view/browse.html.php
+++ b/module/company/view/browse.html.php
@@ -49,7 +49,7 @@ js::set('confirmDelete', $lang->user->confirmDelete);
user->join);?> |
user->last);?> |
user->visits);?> |
- actions;?> |
+ actions;?> |
@@ -87,6 +87,7 @@ js::set('confirmDelete', $lang->user->confirmDelete);
{
common::printIcon('user', 'unlock', "userID=$user->account", '', 'list', '', "hiddenwin");
}
+ if($user->bindRanzhi) common::printIcon('user', 'unbind', "userID=$user->account", '', 'list', 'unlink', "hiddenwin");
?>
diff --git a/module/group/lang/resource.php b/module/group/lang/resource.php
index f66101d999..03052b8986 100644
--- a/module/group/lang/resource.php
+++ b/module/group/lang/resource.php
@@ -658,6 +658,7 @@ $lang->resource->user->profile = 'profile';
$lang->resource->user->batchEdit = 'batchEdit';
$lang->resource->user->manageContacts = 'manageContacts';
$lang->resource->user->deleteContacts = 'deleteContacts';
+$lang->resource->user->unbind = 'unbind';
$lang->user->methodOrder[5] = 'create';
$lang->user->methodOrder[7] = 'batchCreate';
@@ -674,6 +675,7 @@ $lang->user->methodOrder[55] = 'profile';
$lang->user->methodOrder[60] = 'batchEdit';
$lang->user->methodOrder[65] = 'manageContacts';
$lang->user->methodOrder[70] = 'deleteContacts';
+$lang->user->methodOrder[75] = 'unbind';
/* Tree. */
$lang->resource->tree = new stdclass();
@@ -1094,3 +1096,4 @@ $lang->changelog['7.3'][] = 'mail-sendCloud';
$lang->changelog['7.3'][] = 'mail-sendcloudUser';
$lang->changelog['7.4'][] = 'release-changeStatus';
+$lang->changelog['7.4'][] = 'user-unbind';
diff --git a/module/sso/control.php b/module/sso/control.php
index aa9c42402d..50ecd4192a 100644
--- a/module/sso/control.php
+++ b/module/sso/control.php
@@ -56,8 +56,12 @@ class sso extends control
$token = $data->token;
if($data->auth == md5($code . $userIP . $token . $key))
{
- $user = $this->loadModel('user')->getById($data->account);
- if(!$user) $this->locate($this->createLink('user', 'login', empty($referer) ? '' : "referer=$referer"));
+ $user = $this->sso->getBindUser($data->account);
+ if(!$user)
+ {
+ $this->session->set('ssoData', $data);
+ $this->locate($this->createLink('sso', 'bind', "referer=" . helper::safe64Encode($locate)));
+ }
$this->user->cleanLocked($user->account);
/* Authorize him and save to session. */
@@ -136,4 +140,45 @@ class sso extends control
die('success');
}
}
+
+ /**
+ * Bind user.
+ *
+ * @param string $referer
+ * @access public
+ * @return void
+ */
+ public function bind($referer = '')
+ {
+ if(!$this->session->ssoData) die();
+
+ $ssoData = $this->session->ssoData;
+ $userIP = $this->server->remote_addr;
+ $code = $this->config->sso->code;
+ $key = $this->config->sso->key;
+ if($ssoData->auth != md5($code . $userIP . $ssoData->token . $key))die();
+
+ $this->loadModel('user');
+ if($_POST)
+ {
+ $user = $this->sso->bind();
+ if(dao::isError()) die(js::error(dao::getError()));
+
+ /* Authorize him and save to session. */
+ $user->rights = $this->user->authorize($user->account);
+ $user->groups = $this->user->getGroups($user->account);
+ $this->dao->update(TABLE_USER)->set('visits = visits + 1')->set('ip')->eq($userIP)->set('last')->eq($last)->where('account')->eq($user->account)->exec();
+
+ $user->last = date(DT_DATETIME1, $last);
+ $this->session->set('user', $user);
+ $this->app->user = $this->session->user;
+ $this->loadModel('action')->create('user', $user->id, 'login');
+ unset($_SESSION['ssoData']);
+ die(js::locate(helper::safe64Decode($referer), 'parent'));
+ }
+ $this->view->title = $this->lang->sso->bind;
+ $this->view->users = $this->user->getPairs('nodeleted|noclosed');
+ $this->view->data = $ssoData;
+ $this->display();
+ }
}
diff --git a/module/sso/lang/zh-cn.php b/module/sso/lang/zh-cn.php
index 6bbaaa824f..c6390dff6e 100644
--- a/module/sso/lang/zh-cn.php
+++ b/module/sso/lang/zh-cn.php
@@ -15,14 +15,25 @@ $lang->sso->turnon = '是否打开';
$lang->sso->code = '代号';
$lang->sso->key = '密钥';
$lang->sso->addr = '接口地址';
+$lang->sso->bind = '用户绑定';
$lang->sso->addrNotice = '比如:http://www.ranzhi.com/sys/sso-check.html';
$lang->sso->turnonList = array();
$lang->sso->turnonList[1] = '打开';
$lang->sso->turnonList[0] = '关闭';
+$lang->sso->bindType = '绑定方式';
+$lang->sso->bindUser = '绑定用户';
+
+$lang->sso->bindTypeList['bind'] = '绑定已有用户';
+$lang->sso->bindTypeList['add'] = '添加新用户';
+
$lang->sso->help = <<1、接口地址的填写,如果是PATH_INFO :http://然之网址/sys/sso-check.html,如果是GET:http://然之网址/sys/index.php?m=sso&f=check
2、代号和密钥必须与然之后台设置的一致。
3、然之的用户名必须和禅道里面的一致,否则无法从然之关联登录禅道
EOD;
+$lang->sso->bindNotice = '添加的新用户暂时没有权限,需要联系禅道管理员,给该用户分配权限。';
+$lang->sso->bindNoPassword = '密码不能为空';
+$lang->sso->bindNoUser = '该用户的登录密码错误,或该用户不存在!';
+$lang->sso->bindHasAccount = '该用户名已经存在,请更换用户名,或直接绑定到该用户。';
diff --git a/module/sso/model.php b/module/sso/model.php
index 75e354ce22..037623ff32 100644
--- a/module/sso/model.php
+++ b/module/sso/model.php
@@ -13,4 +13,60 @@ class ssoModel extends model
if(empty($this->config->sso->key)) return false;
return $this->get->hash == $this->config->sso->key;
}
+
+ /**
+ * Get bind user.
+ *
+ * @param string $user
+ * @access public
+ * @return object
+ */
+ public function getBindUser($user)
+ {
+ return $this->dao->select('*')->from(TABLE_USER)->where('bindRanzhi')->eq($user)->andWhere('deleted')->eq('0')->fetch();
+ }
+
+ /**
+ * Bind user.
+ *
+ * @access public
+ * @return object
+ */
+ public function bind()
+ {
+ $data = fixer::input('post')->get();
+ if($data->bindType == 'bind')
+ {
+ if(empty($data->bindPassword))die(js::alert($this->lang->sso->bindNoPassword));
+ $password = md5($data->bindPassword);
+ $user = $this->dao->select('*')->from(TABLE_USER)->where('account')->eq($data->bindUser)->andWhere('password')->eq($password)->andWhere('deleted')->eq('0')->fetch();
+ if(empty($user))die(js::alert($this->lang->sso->bindNoUser));
+ $user->bindRanzhi = $this->session->ssoData->account;
+ $this->dao->update(TABLE_USER)->set('bindRanzhi')->eq($user->bindRanzhi)->where('id')->eq($user->id)->exec();
+ }
+ elseif($data->bindType == 'add')
+ {
+ if(!$this->loadModel('user')->checkPassword()) return;
+ $user = $this->dao->select('*')->from(TABLE_USER)->where('account')->eq($data->account)->fetch();
+ if($user) die(js::alert($this->lang->sso->bindHasAccount));
+
+ $user = new stdclass();
+ $user->account = $data->account;
+ $user->password = md5($data->password1);
+ $user->realname = $data->realname;
+ $user->gender = isset($data->gender) ? $data->gender : '';
+ $user->email = $data->email;
+ $user->bindRanzhi = $this->session->ssoData->account;
+
+ $this->dao->insert(TABLE_USER)->data($user)
+ ->autoCheck()
+ ->batchCheck($this->config->user->create->requiredFields, 'notempty')
+ ->check('account', 'unique')
+ ->check('account', 'account')
+ ->checkIF($user->email != false, 'email', 'email')
+ ->exec();
+ }
+
+ return $user;
+ }
}
diff --git a/module/sso/view/bind.html.php b/module/sso/view/bind.html.php
new file mode 100644
index 0000000000..452e2297af
--- /dev/null
+++ b/module/sso/view/bind.html.php
@@ -0,0 +1,79 @@
+
+ * @package sso
+ * @version $Id$
+ * @link http://www.zentao.net
+ */
+?>
+
+
+
+
+
diff --git a/module/tree/model.php b/module/tree/model.php
index e29e6ee436..091eb17381 100644
--- a/module/tree/model.php
+++ b/module/tree/model.php
@@ -225,6 +225,7 @@ class treeModel extends model
foreach($parentModules as $parentModuleID)
{
if(empty($parentModuleID)) continue;
+ if(empty($modules[$parentModuleID])) continue;
$moduleName .= $modules[$parentModuleID]->name . '/';
}
$moduleName = rtrim($moduleName, '/');
diff --git a/module/user/control.php b/module/user/control.php
index 8ca7c4122c..c229006477 100644
--- a/module/user/control.php
+++ b/module/user/control.php
@@ -589,6 +589,27 @@ class user extends control
}
}
+ /**
+ * Unbind Ranzhi
+ *
+ * @param string $account
+ * @param string $confirm
+ * @access public
+ * @return void
+ */
+ public function unbind($account, $confirm = 'no')
+ {
+ if($confirm == 'no')
+ {
+ die(js::confirm($this->lang->user->confirmUnbind, $this->createLink('user', 'unbind', "account=$account&confirm=yes")));
+ }
+ else
+ {
+ $this->user->unbind($account);
+ die(js::locate($this->createLink('company', 'browse'), 'parent'));
+ }
+ }
+
/**
* User login, identify him and authorize him.
*
diff --git a/module/user/lang/zh-cn.php b/module/user/lang/zh-cn.php
index 23472ce23e..a45505cbc6 100644
--- a/module/user/lang/zh-cn.php
+++ b/module/user/lang/zh-cn.php
@@ -42,6 +42,7 @@ $lang->user->join = '入职时间';
$lang->user->visits = '访问次数';
$lang->user->ip = '最后IP';
$lang->user->last = '最后登录';
+$lang->user->bindRanzhi = '然之账号';
$lang->user->status = '状态';
$lang->user->ditto = '同上';
$lang->user->originalPassword = '原密码';
@@ -59,6 +60,7 @@ $lang->user->unlock = "解锁用户";
$lang->user->update = "编辑用户";
$lang->user->delete = "删除用户";
$lang->user->browse = "浏览用户";
+$lang->user->unbind = "解除然之绑定";
$lang->user->login = "用户登录";
$lang->user->mobileLogin = "手机访问";
$lang->user->userView = "人员视图";
@@ -70,6 +72,7 @@ $lang->user->deny = "访问受限";
$lang->user->confirmDelete = "您确定删除该用户吗?";
$lang->user->confirmActivate = "您确定激活该用户吗?";
$lang->user->confirmUnlock = "您确定解除该用户的锁定状态吗?";
+$lang->user->confirmUnbind = "您确定解除该用户跟然之的绑定吗?";
$lang->user->relogin = "重新登录";
$lang->user->asGuest = "游客访问";
$lang->user->goback = "返回前一页";
diff --git a/module/user/model.php b/module/user/model.php
index 09dc197159..abb5a01d2b 100644
--- a/module/user/model.php
+++ b/module/user/model.php
@@ -781,6 +781,18 @@ class userModel extends model
$this->dao->update(TABLE_USER)->set('fails')->eq(0)->set('locked')->eq('0000-00-00 00:00:00')->where('account')->eq($account)->exec();
}
+ /**
+ * Unbind Ranzhi
+ *
+ * @param string $account
+ * @access public
+ * @return void
+ */
+ public function unbind($account)
+ {
+ $this->dao->update(TABLE_USER)->set('bindRanzhi')->eq('')->where('account')->eq($account)->exec();
+ }
+
/**
* Get contact list of a user.
*
diff --git a/module/user/view/profile.html.php b/module/user/view/profile.html.php
index 0ffea53a2c..f5a3d36626 100644
--- a/module/user/view/profile.html.php
+++ b/module/user/view/profile.html.php
@@ -126,6 +126,12 @@
user->zipcode;?> |
zipcode;?> |
+ bindRanzhi):?>
+
+ | user->bindRanzhi;?> |
+ bindRanzhi;?> |
+
+