* finish task #2363,2364.

This commit is contained in:
wangyidong
2015-11-05 17:27:59 +08:00
parent 015401d1e0
commit e003ed01f0
14 changed files with 245 additions and 5 deletions
+2 -1
View File
@@ -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`; ALTER TABLE `zt_story` ADD `plan` text COLLATE 'utf8_general_ci' NOT NULL AFTER `module`;
UPDATE `zt_story` SET `plan`='' WHERE `plan`='0'; 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`;
+1 -1
View File
@@ -480,7 +480,7 @@ class router
{ {
foreach($_COOKIE as $cookieKey => $cookieValue) 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]);
} }
} }
+1
View File
@@ -151,6 +151,7 @@ class commonModel extends model
if($module == 'block' and $method == 'main') return true; if($module == 'block' and $method == 'main') return true;
if($module == 'sso' and $method == 'login') return true; if($module == 'sso' and $method == 'login') return true;
if($module == 'sso' and $method == 'logout') return true; if($module == 'sso' and $method == 'logout') return true;
if($module == 'sso' and $method == 'bind') return true;
if($this->loadModel('user')->isLogon()) if($this->loadModel('user')->isLogon())
{ {
+2 -1
View File
@@ -49,7 +49,7 @@ js::set('confirmDelete', $lang->user->confirmDelete);
<th><?php common::printOrderLink('join', $orderBy, $vars, $lang->user->join);?></th> <th><?php common::printOrderLink('join', $orderBy, $vars, $lang->user->join);?></th>
<th><?php common::printOrderLink('last', $orderBy, $vars, $lang->user->last);?></th> <th><?php common::printOrderLink('last', $orderBy, $vars, $lang->user->last);?></th>
<th><?php common::printOrderLink('visits', $orderBy, $vars, $lang->user->visits);?></th> <th><?php common::printOrderLink('visits', $orderBy, $vars, $lang->user->visits);?></th>
<th class='w-80px'><?php echo $lang->actions;?></th> <th class='w-90px'><?php echo $lang->actions;?></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -87,6 +87,7 @@ js::set('confirmDelete', $lang->user->confirmDelete);
{ {
common::printIcon('user', 'unlock', "userID=$user->account", '', 'list', '', "hiddenwin"); common::printIcon('user', 'unlock', "userID=$user->account", '', 'list', '', "hiddenwin");
} }
if($user->bindRanzhi) common::printIcon('user', 'unbind', "userID=$user->account", '', 'list', 'unlink', "hiddenwin");
?> ?>
</td> </td>
</tr> </tr>
+3
View File
@@ -658,6 +658,7 @@ $lang->resource->user->profile = 'profile';
$lang->resource->user->batchEdit = 'batchEdit'; $lang->resource->user->batchEdit = 'batchEdit';
$lang->resource->user->manageContacts = 'manageContacts'; $lang->resource->user->manageContacts = 'manageContacts';
$lang->resource->user->deleteContacts = 'deleteContacts'; $lang->resource->user->deleteContacts = 'deleteContacts';
$lang->resource->user->unbind = 'unbind';
$lang->user->methodOrder[5] = 'create'; $lang->user->methodOrder[5] = 'create';
$lang->user->methodOrder[7] = 'batchCreate'; $lang->user->methodOrder[7] = 'batchCreate';
@@ -674,6 +675,7 @@ $lang->user->methodOrder[55] = 'profile';
$lang->user->methodOrder[60] = 'batchEdit'; $lang->user->methodOrder[60] = 'batchEdit';
$lang->user->methodOrder[65] = 'manageContacts'; $lang->user->methodOrder[65] = 'manageContacts';
$lang->user->methodOrder[70] = 'deleteContacts'; $lang->user->methodOrder[70] = 'deleteContacts';
$lang->user->methodOrder[75] = 'unbind';
/* Tree. */ /* Tree. */
$lang->resource->tree = new stdclass(); $lang->resource->tree = new stdclass();
@@ -1094,3 +1096,4 @@ $lang->changelog['7.3'][] = 'mail-sendCloud';
$lang->changelog['7.3'][] = 'mail-sendcloudUser'; $lang->changelog['7.3'][] = 'mail-sendcloudUser';
$lang->changelog['7.4'][] = 'release-changeStatus'; $lang->changelog['7.4'][] = 'release-changeStatus';
$lang->changelog['7.4'][] = 'user-unbind';
+47 -2
View File
@@ -56,8 +56,12 @@ class sso extends control
$token = $data->token; $token = $data->token;
if($data->auth == md5($code . $userIP . $token . $key)) if($data->auth == md5($code . $userIP . $token . $key))
{ {
$user = $this->loadModel('user')->getById($data->account); $user = $this->sso->getBindUser($data->account);
if(!$user) $this->locate($this->createLink('user', 'login', empty($referer) ? '' : "referer=$referer")); if(!$user)
{
$this->session->set('ssoData', $data);
$this->locate($this->createLink('sso', 'bind', "referer=" . helper::safe64Encode($locate)));
}
$this->user->cleanLocked($user->account); $this->user->cleanLocked($user->account);
/* Authorize him and save to session. */ /* Authorize him and save to session. */
@@ -136,4 +140,45 @@ class sso extends control
die('success'); 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();
}
} }
+11
View File
@@ -15,14 +15,25 @@ $lang->sso->turnon = '是否打开';
$lang->sso->code = '代号'; $lang->sso->code = '代号';
$lang->sso->key = '密钥'; $lang->sso->key = '密钥';
$lang->sso->addr = '接口地址'; $lang->sso->addr = '接口地址';
$lang->sso->bind = '用户绑定';
$lang->sso->addrNotice = '比如:http://www.ranzhi.com/sys/sso-check.html'; $lang->sso->addrNotice = '比如:http://www.ranzhi.com/sys/sso-check.html';
$lang->sso->turnonList = array(); $lang->sso->turnonList = array();
$lang->sso->turnonList[1] = '打开'; $lang->sso->turnonList[1] = '打开';
$lang->sso->turnonList[0] = '关闭'; $lang->sso->turnonList[0] = '关闭';
$lang->sso->bindType = '绑定方式';
$lang->sso->bindUser = '绑定用户';
$lang->sso->bindTypeList['bind'] = '绑定已有用户';
$lang->sso->bindTypeList['add'] = '添加新用户';
$lang->sso->help = <<<EOD $lang->sso->help = <<<EOD
<p>1、接口地址的填写,如果是PATH_INFO http://然之网址/sys/sso-check.html,如果是GEThttp://然之网址/sys/index.php?m=sso&f=check</p> <p>1、接口地址的填写,如果是PATH_INFO http://然之网址/sys/sso-check.html,如果是GEThttp://然之网址/sys/index.php?m=sso&f=check</p>
<p>2、代号和密钥必须与然之后台设置的一致。</p> <p>2、代号和密钥必须与然之后台设置的一致。</p>
<p>3、然之的用户名必须和禅道里面的一致,否则无法从然之关联登录禅道</p> <p>3、然之的用户名必须和禅道里面的一致,否则无法从然之关联登录禅道</p>
EOD; EOD;
$lang->sso->bindNotice = '添加的新用户暂时没有权限,需要联系禅道管理员,给该用户分配权限。';
$lang->sso->bindNoPassword = '密码不能为空';
$lang->sso->bindNoUser = '该用户的登录密码错误,或该用户不存在!';
$lang->sso->bindHasAccount = '该用户名已经存在,请更换用户名,或直接绑定到该用户。';
+56
View File
@@ -13,4 +13,60 @@ class ssoModel extends model
if(empty($this->config->sso->key)) return false; if(empty($this->config->sso->key)) return false;
return $this->get->hash == $this->config->sso->key; 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;
}
} }
+79
View File
@@ -0,0 +1,79 @@
<?php
/**
* The bind view file of sso module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package sso
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.lite.html.php';?>
<?php include '../../common/view/chosen.html.php';?>
<div class='container mw-700px'>
<div class= 'panel'>
<div class='panel-heading'><strong><?php echo $lang->sso->bind?></strong></div>
<form method='post' target='hiddenwin' id='bindForm'>
<table class='table table-form'>
<tr>
<th class='w-100px'><?php echo $lang->sso->bindType?></th>
<td><?php echo html::radio('bindType', $lang->sso->bindTypeList, 'bind')?></td>
<td></td>
</tr>
<tr class='params bind'>
<th><?php echo $lang->sso->bindUser?></th>
<td><?php echo html::select('bindUser', $users, $data->account, "class='form-control chosen'")?></td>
</tr>
<tr class='params bind'>
<th><?php echo $lang->user->password?></th>
<td><?php echo html::input('bindPassword', '', "class='form-control'")?></td>
</tr>
<tr class='params add hide'>
<th><?php echo $lang->user->account?></th>
<td><?php echo html::input('account', $data->account, "class='form-control'")?></td>
</tr>
<tr class='params add hide'>
<th><?php echo $lang->user->password?></th>
<td><?php echo html::input('password1', '', "class='form-control'")?></td>
</tr>
<tr class='params add hide'>
<th><?php echo $lang->user->password2?></th>
<td><?php echo html::input('password2', '', "class='form-control'")?></td>
</tr>
<tr class='params add hide'>
<th><?php echo $lang->user->realname?></th>
<td><?php echo html::input('realname', $data->realname, "class='form-control'")?></td>
</tr>
<tr class='params add hide'>
<th><?php echo $lang->user->gender?></th>
<td><?php echo html::radio('gender', $lang->user->genderList, $data->gender)?></td>
</tr>
<tr class='params add hide'>
<th><?php echo $lang->user->email?></th>
<td><?php echo html::input('email', $data->email, "class='form-control'")?></td>
</tr>
<tr class='params add hide'>
<th></th>
<td colspan='2'><span style='color:red'><?php echo $lang->sso->bindNotice?></span></td>
</tr>
<tr>
<th></th>
<td><?php echo html::submitButton()?></td>
</tr>
</table>
</form>
</div>
</div>
<script>
$(function()
{
$('#bindForm input[id^="bindType"]').change(function()
{
$('#bindForm table tr.params').addClass('hide');
$('#bindForm table tr.' + $(this).val()).removeClass('hide');
})
})
</script>
<?php include '../../common/view/footer.lite.html.php';?>
+1
View File
@@ -225,6 +225,7 @@ class treeModel extends model
foreach($parentModules as $parentModuleID) foreach($parentModules as $parentModuleID)
{ {
if(empty($parentModuleID)) continue; if(empty($parentModuleID)) continue;
if(empty($modules[$parentModuleID])) continue;
$moduleName .= $modules[$parentModuleID]->name . '/'; $moduleName .= $modules[$parentModuleID]->name . '/';
} }
$moduleName = rtrim($moduleName, '/'); $moduleName = rtrim($moduleName, '/');
+21
View File
@@ -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. * User login, identify him and authorize him.
* *
+3
View File
@@ -42,6 +42,7 @@ $lang->user->join = '入职时间';
$lang->user->visits = '访问次数'; $lang->user->visits = '访问次数';
$lang->user->ip = '最后IP'; $lang->user->ip = '最后IP';
$lang->user->last = '最后登录'; $lang->user->last = '最后登录';
$lang->user->bindRanzhi = '然之账号';
$lang->user->status = '状态'; $lang->user->status = '状态';
$lang->user->ditto = '同上'; $lang->user->ditto = '同上';
$lang->user->originalPassword = '原密码'; $lang->user->originalPassword = '原密码';
@@ -59,6 +60,7 @@ $lang->user->unlock = "解锁用户";
$lang->user->update = "编辑用户"; $lang->user->update = "编辑用户";
$lang->user->delete = "删除用户"; $lang->user->delete = "删除用户";
$lang->user->browse = "浏览用户"; $lang->user->browse = "浏览用户";
$lang->user->unbind = "解除然之绑定";
$lang->user->login = "用户登录"; $lang->user->login = "用户登录";
$lang->user->mobileLogin = "手机访问"; $lang->user->mobileLogin = "手机访问";
$lang->user->userView = "人员视图"; $lang->user->userView = "人员视图";
@@ -70,6 +72,7 @@ $lang->user->deny = "访问受限";
$lang->user->confirmDelete = "您确定删除该用户吗?"; $lang->user->confirmDelete = "您确定删除该用户吗?";
$lang->user->confirmActivate = "您确定激活该用户吗?"; $lang->user->confirmActivate = "您确定激活该用户吗?";
$lang->user->confirmUnlock = "您确定解除该用户的锁定状态吗?"; $lang->user->confirmUnlock = "您确定解除该用户的锁定状态吗?";
$lang->user->confirmUnbind = "您确定解除该用户跟然之的绑定吗?";
$lang->user->relogin = "重新登录"; $lang->user->relogin = "重新登录";
$lang->user->asGuest = "游客访问"; $lang->user->asGuest = "游客访问";
$lang->user->goback = "返回前一页"; $lang->user->goback = "返回前一页";
+12
View File
@@ -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(); $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. * Get contact list of a user.
* *
+6
View File
@@ -126,6 +126,12 @@
<th><?php echo $lang->user->zipcode;?></th> <th><?php echo $lang->user->zipcode;?></th>
<td><?php echo $user->zipcode;?></td> <td><?php echo $user->zipcode;?></td>
</tr> </tr>
<?php if($user->bindRanzhi):?>
<tr>
<th><?php echo $lang->user->bindRanzhi;?></th>
<td><?php echo $user->bindRanzhi;?></td>
</tr>
<?php endif;?>
</table> </table>
</div> </div>
<?php include '../../common/view/footer.html.php';?> <?php include '../../common/view/footer.html.php';?>