diff --git a/application/module/Open/Client.php b/application/module/Open/Client.php new file mode 100644 index 00000000..2bfc6ff6 --- /dev/null +++ b/application/module/Open/Client.php @@ -0,0 +1,172 @@ +db = \Zend_Registry::get('db'); + }else{ + $this->db = $db; + } + + $this->config = \Zend_Registry::get('config'); + + $this->table = new \Helpers\Table(); + + $this->target = $target; + + $Listener = new Listener(); + @$this->events()->attachAggregate($Listener); + } + + public function events(\Zend_EventManager_EventCollection $events = NULL) + { + if ($events !== NULL) { + $this->events = $events; + } elseif ($this->events === NULL) { + $this->events = new \Zend_EventManager_EventManager(__CLASS__); + } + return $this->events; + } + + public function initSource() + { + $this->source = new Source('heihedata'); + } + + public function getSource() + { + return $this->source; + } + + //创建获取Code的URL + public function makeRequestCodeUrl($target = NULL) + { + if(empty($this->source)) + { + $this->initSource(); + } + + if(empty($target)) + { + $target = $this->target; + } + + $main_target = $this->source->getTarget($target); + + if($main_target === false) + { + return "此登录接口可能不存在"; + } + + $source = $this->source->getSource($target); + + if($source === false) + { + return "此登录接口暂不可用"; + } + + $main_url = $main_target['code']; + + $param = array( + $source->param['id'] => $source->config['id'], + $source->param['secret'] => $source->config['secret'], + $source->param['callback'] => $source->config['callback'], + $source->param['code_response'] => $main_target['code_response'] + ); + + if(isset($source->config['other'])) + { + $param = array_merge($param,$source->config['other']); + } + + $url = $main_url."?".http_build_query($param); + + return $url; + + } + + //获得token + public function requestToken($code,$target = NULL) + { + if(empty($target)) + { + $target = $this->target; + } + + if(empty($code)) + { + return "未获得您的授权码"; + } + + $main_target = $this->source->getTarget($target); + $client = $this->source->getSource($target); + + if($client === false) + { + return "请求发生错误,登录接口不存在或者可能不再适用"; + } + + $main_url = $main_target['token']; + $param = array( + $client->param['id'] => $client->config['id'], + $client->param['secret'] => $client->config['secret'], + $client->param['grant_type'] => $main_target['grant_type'], + $client->param['callback'] => $client->config['callback'], + $client->param['code'] => $code + ); + + $curl = new Curl(); + $curl->port = 443; + $curl->initOptions(array('verifyssl'=>false)); + $data = $curl->request($main_url,$param,"POST"); + + $cache_data = json_decode($data['response'],true); + + if(!isset($cache_data['expires_in'])) + { + return "未获得授权信息,请重试链接"; + } + + return $cache_data; + + } + + //储存token信息 + public function storageTokenData($type,$token) + { + if(empty($type)) + { + return "接口类型错误"; + } + + if(empty($token)) + { + return "登录信息有误,请重新登录"; + } + + $param = compact("type","token"); + + $results = $this->events()->trigger('tokenStorage', $this, $param); + return $cache_data = $results->bottom(); + + } + + + +} \ No newline at end of file diff --git a/application/module/Open/Event/AppEvent.php b/application/module/Open/Event/AppEvent.php new file mode 100644 index 00000000..9985c74d --- /dev/null +++ b/application/module/Open/Event/AppEvent.php @@ -0,0 +1,10 @@ +db = \Zend_Registry::get('db'); + }else{ + $this->db = $db; + } + + $this->config = \Zend_Registry::get('config'); + $this->table = new Table(); + } + + //检查app参数 + public function appCheckParam(\Zend_EventManager_Event $e) + { + $data = $e->getParam('data'); + + if(!is_array($data)) + { + return "参数错误"; + } + + if(empty($data['subject'])) + { + return "请输入应用名称"; + } + + if(empty($data['client_domain'])) + { + return "请填写应用使用的域名,不带www"; + } + + if(empty($data['redirect_uri'])) + { + return "请输入授权成功后的回调地址"; + } + + $sql = "SELECT id FROM {$this->table->oauth_clients} WHERE subject='{$data['subject']}'"; + $rs = $this->db->query($sql); + $row = $rs->fetch(); + + if(!empty($row['id'])) + { + return "此应用名称已存在,请重新输入"; + } + + return true; + } + + //处理app参数数据 + public function appProcessData(\Zend_EventManager_Event $e) + { + $data = $e->getParam('data'); + $id = $e->getParam('id'); + + if(empty($id)) + { + $data['client_id'] = $this->create_client_guid(__CLASS__); + $data['client_secret'] = strtoupper(substr(md5($data['client_id'].$data['client_domain'].$data['redirect_uri'].time()),10,24)); + } + $data['user_id'] = view::User('id'); + + return $data; + } + + //创建App成功后 + public function appCreated(\Zend_EventManager_Event $e) + { + $id = $e->getParam('id'); + $data = $e->getParam('data'); + + return true; + } + + //App编辑成功后 + public function appEdited(\Zend_EventManager_Event $e) + { + $id = $e->getParam('id'); + $data = $e->getParam('data'); + + return true; + } + + public function create_client_guid($namespace = '') { + static $guid = ''; + $uid = uniqid("", true); + $data = $namespace; + if(isset($_SERVER['REQUEST_TIME'])) + $data .= $_SERVER['REQUEST_TIME']; + + if(isset($_SERVER['HTTP_USER_AGENT'])) + $data .= $_SERVER['HTTP_USER_AGENT']; + + if(isset($_SERVER['LOCAL_ADDR'])) + $data .= $_SERVER['LOCAL_ADDR']; + + if(isset($_SERVER['LOCAL_PORT'])) + $data .= $_SERVER['LOCAL_PORT']; + + if(isset($_SERVER['REMOTE_ADDR'])) + $data .= $_SERVER['REMOTE_ADDR']; + + if(isset($_SERVER['REMOTE_PORT'])) + $data .= $_SERVER['REMOTE_PORT']; + + $data .= time(); + + $hash = strtoupper(hash('ripemd128', $uid . $guid . md5($data))); + $guid = '' . + substr($hash, 0, 8) . + '-' . + substr($hash, 8, 4) . + '-' . + substr($hash, 12, 4) . + '-' . + substr($hash, 16, 4) . + '-' . + substr($hash, 20, 12) . + ''; + return $guid; + } + +} diff --git a/application/module/Open/Handler/ClientHandler.php b/application/module/Open/Handler/ClientHandler.php new file mode 100644 index 00000000..b3cd8a2f --- /dev/null +++ b/application/module/Open/Handler/ClientHandler.php @@ -0,0 +1,83 @@ +db = \Zend_Registry::get('db'); + }else{ + $this->db = $db; + } + + $this->config = \Zend_Registry::get('config'); + $this->table = new Table(); + } + + //获得Handler,type必须与 \Open\Source中同步,否则会出现错误 + // + public function getHandler($type,$data) + { + if($type == 'escience') + { + return new \Open\Handler\ClientTokenHandler\Escience($data); + } + + if($type == 'sina') + { + return new \Open\Handler\ClientTokenHandler\Sina($data); + } + + return false; + } + + //存储token信息 + public function tokenAndDataStorage(\Zend_EventManager_Event $e) + { + $type = $e->getParam('type'); + $data = $e->getParam('token'); + + $handler = $this->getHandler($type,$data); + + if($status = $handler->doit() === true) + { + return true; + }else{ + return $status; + } + } + + //检查用户账户是否存在 + //存在就返回用户信息,不存在返回false + //通用事件,通过各个 TokenHandler中内置Listener直接挂载,不需要引入整个ClientListener + public function userCheck(\Zend_EventManager_Event $e) + { + $email = $e->getParam('email'); + + $user = new Users(); + $current = $user->userExists($email); + + if($current === false) + { + return false; + } + + return $current; + } + +} diff --git a/application/module/Open/Handler/ClientTokenHandler/Escience.php b/application/module/Open/Handler/ClientTokenHandler/Escience.php new file mode 100644 index 00000000..4c13a8e2 --- /dev/null +++ b/application/module/Open/Handler/ClientTokenHandler/Escience.php @@ -0,0 +1,182 @@ +db = \Zend_Registry::get('db'); + }else{ + $this->db = $db; + } + + $this->config = \Zend_Registry::get('config'); + $this->table = new Table(); + + //预处理token信息 + $status = $this->preProcess($token); + } + + //考虑加一个接口,每个Token操作类中必须包含此函数 + public function doit() + { + //makeUserStorage在先,必须的 + $status = $this->makeUserStorage(); + + if($status!==true) + { + return $status; + } + + $status = $this->makeTokenStorage(); + + if($status !== true) + { + return $status; + } + + return true; + } + + //预处理 + public function preProcess($tokenData) + { + if(!is_array($tokenData)) + { + return "参数错误"; + } + + $this->userInfo = json_decode($tokenData['userInfo'],true); + + unset($tokenData['userInfo']); + + $this->token = $tokenData; + + return true; + } + + //检查用户信息,如果没有用户自动注册,有用户就自动绑定。 + public function makeUserStorage() + { + $uid = view::User('id'); + + if(is_numeric($uid) && $uid > 0) + { + $this->userid = $uid; + return "您已经登录,无需重复登录"; + } + + if(empty($this->userid)) + { + $current_oauth_email = $this->userInfo['cstnetId']; + + $user = new Users(TRUE); + $current = $user->userExists($current_oauth_email); + + if($current === false) + //自动注册用户 + { + $data = array( + $user->account->FieldUsername => $current_oauth_email, + $user->account->FieldEmail => $current_oauth_email, + $user->account->FieldPasword => 0, + $user->account->FieldRealname => $this->userInfo['truename'], + ); + + $dbh = new dbh(); + + $id = $dbh->insert($user->account->memberTable,$data,true); + + //登录 + $user->account->storeLogin(array( + $user->account->FieldUsername => $data[$user->account->FieldUsername], + $user->account->FieldPasword => $data[$user->account->FieldPasword] + )); + + $this->userid = $id; + + return true; + } + + //帮用户自动登录 + else{ + + $user->account->storeLogin(array( + $user->account->FieldUsername => $current[$user->account->FieldUsername], + $user->account->FieldPasword => $current[$user->account->FieldPasword] + )); + + $this->userid = $current[$user->account->FieldIndex]; + + return true; + } + + } + + } + + //生成写入token表的数据 + //有token记录就更新,没有再插入 + public function makeTokenStorage() + { + $data = array( + 'access_token' => $this->token['access_token'], + 'refresh_token' => $this->token['refresh_token'], + 'expires_in' => $this->token['expires_in'], + 'userid' => $this->userid, + "response_data" => json_encode($this->userInfo,JSON_NUMERIC_CHECK), + "source" => "escience" + ); + + //查看用户用escience登录的记录是否存在 + $sql = "SELECT * FROM {$this->table->oauth_token} WHERE userid={$this->userid} AND source='{$data['source']}' LIMIT 1"; + $rs = $this->db->query($sql); + $row = $rs->fetch(); + + $dbh = new dbh(); + + if(isset($row['id'])) + { + $status = $dbh->update($this->table->oauth_token,$data," id={$row['id']} AND userid={$this->userid} "); + if($status) + { + return true; + }else{ + return "更新授权信息时发生错误,请重新登录"; + } + }else{ + $status = $dbh->insert($this->table->oauth_token,$data); + if($status) + { + return true; + }else{ + return "记录授权信息时发生错误,请重新登录"; + } + } + + return true; + } + + +} diff --git a/application/module/Open/Handler/OauthHandler.php b/application/module/Open/Handler/OauthHandler.php new file mode 100644 index 00000000..5a5da972 --- /dev/null +++ b/application/module/Open/Handler/OauthHandler.php @@ -0,0 +1,46 @@ +db = \Zend_Registry::get('db'); + }else{ + $this->db = $db; + } + + $this->config = \Zend_Registry::get('config'); + $this->table = new Table(); + } + + public function checkParam(\Zend_EventManager_Event $e) + { + $data = $e->getParam('data'); + + if(!is_array($data)) + { + return "参数错误"; + } + + + + return true; + } + + + +} diff --git a/application/module/Open/Handler/OpenHandler.php b/application/module/Open/Handler/OpenHandler.php new file mode 100644 index 00000000..aa0dc5e0 --- /dev/null +++ b/application/module/Open/Handler/OpenHandler.php @@ -0,0 +1,46 @@ +db = \Zend_Registry::get('db'); + }else{ + $this->db = $db; + } + + $this->config = \Zend_Registry::get('config'); + $this->table = new Table(); + } + + public function checkParam(\Zend_EventManager_Event $e) + { + $data = $e->getParam('data'); + + if(!is_array($data)) + { + return "参数错误"; + } + + + + return true; + } + + + +} diff --git a/application/module/Open/Listener/AppListener.php b/application/module/Open/Listener/AppListener.php new file mode 100644 index 00000000..41628b18 --- /dev/null +++ b/application/module/Open/Listener/AppListener.php @@ -0,0 +1,28 @@ +event = new \Zend_EventManager_EventManager(); + } + + public function attach(\Zend_EventManager_EventCollection $events) + { + $Handler = new Handler(); + $events->attach('app.checkParam', array($Handler, 'appCheckParam'), 100); + $events->attach('app.processData', array($Handler, 'appProcessData'), 100); + $events->attach('app.created', array($Handler, 'appCreated'), 100); + $events->attach('app.eidted', array($Handler, 'appEdited'), 100); + } + + public function detach(\Zend_EventManager_EventCollection $events) + { + + } + +} \ No newline at end of file diff --git a/application/module/Open/Listener/ClientListener.php b/application/module/Open/Listener/ClientListener.php new file mode 100644 index 00000000..2ff2ad3e --- /dev/null +++ b/application/module/Open/Listener/ClientListener.php @@ -0,0 +1,26 @@ +event = new \Zend_EventManager_EventManager(); + } + + public function attach(\Zend_EventManager_EventCollection $events) + { + $Handler = new Handler(); + $events->attach('tokenStorage', array($Handler, 'tokenAndDataStorage'), 100); + $events->attach('user.check', array($Handler, 'userCheck'), 100); + } + + public function detach(\Zend_EventManager_EventCollection $events) + { + + } + +} \ No newline at end of file diff --git a/application/module/Open/Listener/OauthListener.php b/application/module/Open/Listener/OauthListener.php new file mode 100644 index 00000000..65056b9d --- /dev/null +++ b/application/module/Open/Listener/OauthListener.php @@ -0,0 +1,25 @@ +event = new \Zend_EventManager_EventManager(); + } + + public function attach(\Zend_EventManager_EventCollection $events) + { + $Handler = new OauthHandler(); + $events->attach('submit.checkParam', array($Handler, 'checkParam'), 100); + } + + public function detach(\Zend_EventManager_EventCollection $events) + { + + } + +} \ No newline at end of file diff --git a/application/module/Open/Listener/OpenListener.php b/application/module/Open/Listener/OpenListener.php new file mode 100644 index 00000000..64a06730 --- /dev/null +++ b/application/module/Open/Listener/OpenListener.php @@ -0,0 +1,25 @@ +event = new \Zend_EventManager_EventManager(); + } + + public function attach(\Zend_EventManager_EventCollection $events) + { + $Handler = new Handler(); + $events->attach('submit.checkParam', array($Handler, 'checkParam'), 100); + } + + public function detach(\Zend_EventManager_EventCollection $events) + { + + } + +} \ No newline at end of file diff --git a/application/module/Open/OAuth2.php b/application/module/Open/OAuth2.php new file mode 100644 index 00000000..f31d6f37 --- /dev/null +++ b/application/module/Open/OAuth2.php @@ -0,0 +1,31 @@ +db = \Zend_Registry::get('db'); + }else{ + $this->db = $db; + } + + $this->config = \Zend_Registry::get('config'); + $this->table = new Table(); + + } + + //用户使用谷歌账号登陆 + public function googleClient() + { + + } +} \ No newline at end of file diff --git a/application/module/Open/OAuth2/Server.php b/application/module/Open/OAuth2/Server.php new file mode 100644 index 00000000..05508c18 --- /dev/null +++ b/application/module/Open/OAuth2/Server.php @@ -0,0 +1,76 @@ +db = \Zend_Registry::get('db'); + }else{ + $this->db = $db; + } + + $this->config = \Zend_Registry::get('config'); + $this->table = new Table(); + } + + //根据ID或者Client_id获得app的信息 + public function getClientInfo($id) + { + if(empty($id)) + { + return "无效参数"; + } + + if(is_numeric($id)) + { + $field = "id"; + }else{ + $field = "client_id"; + } + + $sql = "SELECT * FROM {$this->table->oauth_clients} WHERE $field=? LIMIT 1"; + $sth = $this->db->prepare($sql); + $sth->execute(array($id)); + $row = $sth->fetch(); + + return $row; + } + + //验证App + public function clientCredentials($client_id,$client_secret) + { + + $client = $this->getClientInfo($client_id); + + if(empty($client['id'])) + { + return "此应用ID未被证实"; + } + + if($client['status'] == -1) + { + return "此应用已关闭"; + } + + if($client['client_secret'] !== $client_secret) + { + return "Invalid client secret"; + } + + return true; + } + + +} \ No newline at end of file diff --git a/application/module/Open/Source.php b/application/module/Open/Source.php new file mode 100644 index 00000000..51e82760 --- /dev/null +++ b/application/module/Open/Source.php @@ -0,0 +1,126 @@ +source = new stdClass(); + $this->target = new stdClass(); + + $this->website = $website; + + $this->initSourceConfig(); + $this->initTarget(); + } + + //获得当前绑定的站点 + public function getCurrentSite(){ + return $this->website; + } + + //设置绑定的站点 + public function setCurrentSite($website){ + $this->website = $website; + $this->initSourceConfig(); + } + + private function initSourceConfig() + { + if(!in_array($this->website,$this->sourceType)) + { + return false; + } + + // Escience + // passport.escience.cn + $this->source->escience = new stdClass(); + $this->source->escience->param = array( + "id" => "client_id", + "secret" => "client_secret", + "code_response" => "response_type", + "grant_type" => "grant_type", + "callback" => "redirect_uri", + "code"=>"code" + ); + + if($this->website == 'westdc'){ + + $this->source->escience->config = array( + 'id' => '71852', + 'secret' => 'ad7gd3jZgbzhQM6vIh9vPnQFZQoTGHZI', + 'index' => 'http://westdc.westgis.ac.cn', + 'callback' => 'http://westdc.westgis.ac.cn/account/callback/type/escience', + 'other' => array( + 'theme'=>'full' + ) + ); + + } + + if($this->website == 'heihedata'){ + + $this->source->escience->config = array( + 'id' => '78969', + 'secret' => 'iTGKdCkUPakA2hza2TJ4XZ4cnwlh8Hqz', + 'index' => 'http://www.heihedata.org', + 'callback' => 'http://www.heihedata.org/account/callback/type/escience', + 'other' => array( + 'theme'=>'full' + ) + ); + + } + + } + + //获得一个源 + public function getSource($type = "") + { + if(empty($type)) + { + return $this->source; + }else{ + if(isset($this->source->$type)) + { + return $this->source->$type; + }else{ + return false; + } + } + } + + //Oauth2登录目标 + private function initTarget(){ + $this->target->escience = array( + 'name' => '中国科技网通行证', + 'code' => 'http://passport.escience.cn/oauth2/authorize', + 'token' => 'https://passport.escience.cn/oauth2/token', + 'code_response' => 'code', + 'grant_type' => 'authorization_code', + ); + } + + //获得Oauth2登录模板 + public function getTarget($type = "") + { + if(empty($type)) + { + return $this->target; + }else{ + if(isset($this->target->$type)) + { + return $this->target->$type; + }else{ + return false; + } + } + } + +} \ No newline at end of file diff --git a/application/module/Open/server.php b/application/module/Open/server.php index ee0b7408..3406b448 100644 --- a/application/module/Open/server.php +++ b/application/module/Open/server.php @@ -29,22 +29,9 @@ class Server extends \Zend_Controller_Plugin_Abstract } } - public function bootstrap() + public function getCode() { - $dsn = "pgsql:dbname={$this->config->db->params->dbname};host={$this->config->db->params->host}"; - $storage = new \OAuth2\Storage\Pdo(array('dsn' => $dsn, 'username' => $this->config->db->params->username, 'password' => $this->config->db->params->password)); - - $server = new \OAuth2\Server($storage); - - $server->addGrantType(new \OAuth2\GrantType\ClientCredentials($storage)); - - $server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($storage)); - - //应用授权 - //$server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send(); - - return $server; } } \ No newline at end of file