| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- <?php
- /**
- * The control file of sso module of ZenTaoPMS.
- *
- * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
- * @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
- * @author Yidong Wang <yidong@cnezsoft.com>
- * @package sso
- * @version $Id: control.php 4460 2013-02-26 02:28:02Z chencongzhi520@gmail.com $
- * @link https://www.zentao.net
- */
- class sso extends control
- {
- /**
- * SSO login.
- *
- * @param string $type notify|return
- * @access public
- * @return void
- */
- public function login($type = 'notify')
- {
- $referer = empty($_GET['referer']) ? '' : $this->get->referer;
- $locate = empty($referer) ? getWebRoot() : base64_decode($referer);
- $this->app->loadConfig('sso');
- if(!$this->config->sso->turnon) return print($this->locate($locate));
- if($type != 'return') return $this->ssoZen->locateNotifyLink($this->config->sso->addr, $referer);
- $this->ssoZen->idenfyFromSSO($locate);
- return $this->locate($this->createLink('user', 'login', empty($referer) ? '' : "referer=$referer"));
- }
- /**
- * SSO logout.
- *
- * @param string $type
- * @access public
- * @return void
- */
- public function logout($type = 'notify')
- {
- if($type != 'return')
- {
- $userIP = helper::getRemoteIp();
- $token = $this->get->token;
- $auth = $this->ssoZen->computeAuth($token);
- $callback = urlencode(common::getSysURL() . inlink('logout', "type=return"));
- $location = $this->config->sso->addr;
- $sign = strpos($location, '&') !== false ? '&' : '?';
- $location = rtrim($location, $sign) . "{$sign}token={$token}&auth={$auth}&userIP={$userIP}&callback={$callback}";
- return $this->locate($location);
- }
- if($this->get->status == 'success')
- {
- session_destroy();
- helper::setcookie('za', false);
- helper::setcookie('zp', false);
- return $this->locate($this->createLink('user', 'login'));
- }
- return $this->locate($this->createLink('user', 'logout'));
- }
- /**
- * Ajax set config.
- *
- * @access public
- * @return void
- */
- public function ajaxSetConfig()
- {
- if(!$this->app->user->admin) return print('deny');
- if($_POST)
- {
- $ssoConfig = new stdclass();
- $ssoConfig->turnon = 1;
- $ssoConfig->addr = $this->post->addr;
- $ssoConfig->code = trim($this->post->code);
- $ssoConfig->key = trim($this->post->key);
- $this->loadModel('setting')->setItems('system.sso', $ssoConfig);
- if(dao::isError()) return print('fail');
- return print('success');
- }
- }
- /**
- * Bind user.
- *
- * @param string $referer
- * @access public
- * @return void
- */
- public function bind($referer = '')
- {
- if(!$this->session->ssoData) return;
- $ssoData = $this->session->ssoData;
- if($ssoData->auth != $this->computeAuth($ssoData->token)) return;
- $this->loadModel('user');
- if($_POST)
- {
- $user = $this->sso->bind();
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $user->last = date(DT_DATETIME1);
- $this->user->login($user);
- unset($_SESSION['ssoData']);
- return $this->send(array('result' => 'success', 'load' => helper::safe64Decode($referer)));
- }
- $this->view->title = $this->lang->sso->bind;
- $this->view->users = $this->user->getPairs('noclosed|nodeleted');
- $this->view->data = $ssoData;
- $this->display();
- }
- /**
- * Get pairs of user.
- *
- * @access public
- * @return void
- */
- public function getUserPairs()
- {
- if(!$this->sso->checkKey()) return false;
- $users = $this->loadModel('user')->getPairs('noclosed|nodeleted');
- echo json_encode($users);
- }
- /**
- * Get bind users with ranzhi.
- *
- * @access public
- * @return void
- */
- public function getBindUsers()
- {
- if(!$this->sso->checkKey()) return false;
- $users = $this->sso->getBindUsers();
- echo json_encode($users);
- }
- /**
- * Bind user from ranzhi.
- *
- * @access public
- * @return void
- */
- public function bindUser()
- {
- if($_POST)
- {
- $this->dao->update(TABLE_USER)->set('ranzhi')->eq('')->where('ranzhi')->eq($this->post->ranzhiAccount)->exec();
- $this->dao->update(TABLE_USER)->set('ranzhi')->eq($this->post->ranzhiAccount)->where('account')->eq($this->post->zentaoAccount)->exec();
- if(dao::isError()) return print(implode("\n", dao::getError()));
- return print('success');
- }
- }
- /**
- * Create user from ranzhi.
- *
- * @access public
- * @return void
- */
- public function createUser()
- {
- if($_POST)
- {
- $user = $this->ssoZen->buildUserForCreate();
- $result = $this->sso->createUser($user);
- if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'id' => $result['id']));
- if($result['status'] != 'success') return print($result['data']);
- return print('success');
- }
- }
- /**
- * Get todo list for ranzhi.
- *
- * @param string $account
- * @access public
- * @return void
- */
- public function getTodoList($account = '')
- {
- if(!$this->sso->checkKey()) return false;
- $user = $this->dao->select('*')->from(TABLE_USER)->where('ranzhi')->eq($account)->andWhere('deleted')->eq(0)->fetch();
- if($user) $account = $user->account;
- $datas = array();
- $datas['task'] = $this->dao->select("id,name")->from(TABLE_TASK)->where('assignedTo')->eq($account)->andWhere('status')->in('wait,doing')->andWhere('deleted')->eq(0)->fetchPairs();
- $datas['bug'] = $this->dao->select("id,title")->from(TABLE_BUG)->where('assignedTo')->eq($account)->andWhere('status')->eq('active')->andWhere('deleted')->eq(0)->fetchPairs();
- echo json_encode($datas);
- }
- /**
- * Get the link to the Feishu single sign-on configuration.
- *
- * @access public
- * @return void
- */
- public function getFeishuSSO()
- {
- $httpType = ((isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == 'on') or (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';
- $applicationHome = $httpType . $_SERVER['HTTP_HOST'] . $this->createLink('sso', 'feishuAuthen');
- $redirectLink = $httpType . $_SERVER['HTTP_HOST'] . $this->createLink('sso', 'feishuLogin');
- echo $this->lang->sso->homeURL . $applicationHome;
- echo '<br>';
- echo $this->lang->sso->redirectURL . $redirectLink;
- }
- /**
- * Get the pre-authorization code for Feishu code.
- *
- * @access public
- * @return void
- */
- public function feishuAuthen()
- {
- $params = $_SERVER["QUERY_STRING"];
- parse_str($params, $params);
- $webhookID = isset($params['id']) ? (int)$params['id'] : 0;
- $httpType = ((isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == 'on') or (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';
- $redirectURI = $httpType . $_SERVER['HTTP_HOST'] . $this->createLink('sso', 'feishuLogin');
- if($webhookID) $redirectURI .= (strpos($redirectURI, '?') === false ? '?' : '&') . "id={$webhookID}";
- $feishuConfig = $this->loadModel('webhook')->getByType('feishuuser', $webhookID);
- if(empty($feishuConfig)) $this->showError($this->lang->sso->feishuConfigEmpty);
- $appConfig = json_decode($feishuConfig->secret);
- $appID = $appConfig->appId;
- $url = sprintf($this->config->sso->feishuAuthAPI, urlencode($redirectURI), $appID);
- $this->locate($url);
- }
- /**
- * Get the identity of the logged-in user.
- *
- * @access public
- * @return void
- */
- public function feishuLogin()
- {
- $params = $_SERVER["QUERY_STRING"];
- parse_str($params, $params);
- $webhookID = isset($params['id']) ? (int)$params['id'] : 0;
- $code = isset($params['code']) ? $params['code'] : '';
- $feishuConfig = $this->loadModel('webhook')->getByType('feishuuser', $webhookID);
- if(empty($feishuConfig)) $this->showError($this->lang->sso->feishuConfigEmpty);
- $appConfig = json_decode($feishuConfig->secret);
- /* Obtain the access credentials of the Feishu app. */
- $appResult = $this->ssoZen->getFeishuAccessToken($appConfig);
- if($appResult['result'] == 'fail') return $this->showError($appResult['message']);
- $accessToken = $appResult['token'];
- /* Verify the identity of the logged in user. */
- $tokenResult = $this->ssoZen->getFeishuUserToken($code, $accessToken);
- if($tokenResult['result'] == 'fail') return $this->showError($tokenResult['message']);
- $userToken = $tokenResult['token'];
- /* Get login user information. */
- $userResult = $this->ssoZen->getBindFeishuUser($userToken, $feishuConfig);
- if($userResult['result'] == 'fail') return $this->showError($userResult['message']);
- $user = $userResult['user'];
- $this->session->set('rand', '');
- $user = $this->loadModel('user')->identify($user->account, $user->password);
- $this->user->login($user);
- $this->locate($this->createLink('my', 'index'));
- }
- /**
- * Display the error message.
- *
- * @param string $message
- * @access public
- * @return void
- */
- public function showError($message = '')
- {
- $this->view->title = $this->lang->sso->deny;
- $this->view->message = $message;
- $this->display('sso', 'error');
- }
- }
|