File indexing completed on 2024-06-23 05:51:30

0001 <?php
0002 
0003 /**
0004  *  ocs-webserver
0005  *
0006  *  Copyright 2016 by pling GmbH.
0007  *
0008  *    This file is part of ocs-webserver.
0009  *
0010  *    This program is free software: you can redistribute it and/or modify
0011  *    it under the terms of the GNU Affero General Public License as
0012  *    published by the Free Software Foundation, either version 3 of the
0013  *    License, or (at your option) any later version.
0014  *
0015  *    This program is distributed in the hope that it will be useful,
0016  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
0017  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0018  *    GNU Affero General Public License for more details.
0019  *
0020  *    You should have received a copy of the GNU Affero General Public License
0021  *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
0022  **/
0023 class Default_Model_Ocs_HttpTransport_OAuthServer
0024 {
0025 
0026     protected $messages;
0027     protected $httpClient;
0028     private $_config;
0029     private $_cache;
0030 
0031     /**
0032      *
0033      * @param Zend_Config $config
0034      *
0035      * @throws Zend_Cache_Exception
0036      * @throws Zend_Exception
0037      * @throws Zend_Http_Client_Exception
0038      * @throws Zend_Uri_Exception
0039      */
0040     public function __construct(Zend_Config $config)
0041     {
0042         $this->_config = $config;
0043         if (empty($this->_config)) {
0044             throw new Zend_Exception('No config present');
0045         }
0046 
0047         $this->_cache = $this->initCache();
0048         $uri = $this->_config->host;
0049         $this->httpClient = new Zend_Http_Client($uri,array('keepalive' => true, 'strictredirects' => true, 'timeout' => 120));
0050         $this->httpClient->setCookieJar();
0051     }
0052 
0053     /**
0054      * @return Zend_Cache_Core
0055      * @throws Zend_Cache_Exception
0056      */
0057     protected function initCache()
0058     {
0059         $frontendOptions = array(
0060             'lifetime'                => null,
0061             'automatic_serialization' => true
0062         );
0063 
0064         $backendOptions = array(
0065             'cache_dir'        => APPLICATION_CACHE,
0066             'file_name_prefix' => 'ocs_id'
0067         );
0068 
0069         return Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
0070     }
0071 
0072     /**
0073      * @param array $userdata
0074      *
0075      * @return bool
0076      * @throws Zend_Cache_Exception
0077      * @throws Zend_Exception
0078      * @throws Zend_Http_Client_Exception
0079      */
0080     public function pushHttpUserData($userdata, $options = null)
0081     {
0082         $this->messages = array();
0083         $access_token = $this->getAccessToken();
0084         $map_user_data = array(
0085             'user' => array(
0086                 'id'             => $userdata['external_id'],
0087                 'ocs_user_id'    => $userdata['ocs_user_id'],
0088                 'username'       => $userdata['username'],
0089                 'password'       => $userdata['password'],
0090                 'email'          => $userdata['email'],
0091                 'emailVerified'  => $userdata['emailVerified'],
0092                 'is_hive'        => $userdata['is_hive'],
0093                 'creationTime'   => $userdata['creationTime'],
0094                 'lastUpdateTime' => $userdata['lastUpdateTime'],
0095                 'avatarUrl'      => $userdata['avatarUrl'],
0096                 'biography'      => $userdata['biography'],
0097                 'admin'          => $userdata['admin'],
0098             )
0099         );
0100         if ((false == $userdata['is_active']) OR (true == $userdata['is_deleted'])) {
0101             $map_user_data['user']['disabledReason'] = 'user account disabled';
0102         }
0103 
0104         if (isset($options) AND is_array($options)) {
0105             $map_user_data['options'] = $options;
0106         }
0107 
0108         $jsonUserData = Zend_Json::encode($map_user_data);
0109         $httpClient = new Zend_Http_Client($this->_config->create_user_url);
0110         $httpClient->setMethod(Zend_Http_Client::POST);
0111         $httpClient->setHeaders('Authorization', 'Bearer ' . $access_token);
0112         $httpClient->setHeaders('Content-Type', 'application/json');
0113         $httpClient->setHeaders('Accept', 'application/json');
0114         $httpClient->setRawData($jsonUserData, 'application/json');
0115 
0116         $response = $httpClient->request();
0117 
0118         //Zend_Registry::get('logger')->debug("----------\n".__METHOD__ . " - request:\n" . $httpClient->getLastRequest());
0119         //Zend_Registry::get('logger')->debug("----------\n".__METHOD__ . " - response:\n" . $response->asString());
0120         Zend_Registry::get('logger')->debug(__METHOD__ . ' - request: ' . $jsonUserData);
0121         Zend_Registry::get('logger')->debug(__METHOD__ . ' - response: ' . $response->getBody());
0122 
0123         if ($response->getStatus() != 200) {
0124             throw new Zend_Exception('push user data failed. OCS ID server send message: ' . $response->getBody() . PHP_EOL
0125                                      . $jsonUserData . PHP_EOL);
0126         }
0127 
0128         $this->messages[] = $response->getBody();
0129 
0130         return true;
0131     }
0132 
0133     /**
0134      * @return mixed
0135      * @throws Zend_Cache_Exception
0136      * @throws Zend_Exception
0137      * @throws Zend_Http_Client_Exception
0138      */
0139     protected function getAccessToken()
0140     {
0141         $cache_name = 'id_server_token' . $this->_config->client_id;
0142         $token = $this->_cache->load($cache_name);
0143         if (false === $token) {
0144             $token = $this->requestHttpAccessToken();
0145             $token->expire_at = microtime(true) + $token->expires_in;
0146             $this->_cache->save($token, $cache_name, array(), false);
0147         }
0148         Zend_Registry::get('logger')->debug(__METHOD__ . " - microtime:" . microtime(true) . " expire_at: "
0149                                             . print_r($token->expire_at, true));
0150         if (isset($token) AND (microtime(true) > $token->expire_at)) {
0151             $token = $this->requestHttRefreshToken($token->refresh_token);
0152             $token->expire_at = microtime(true) + $token->expires_in;
0153             $this->_cache->save($token, $cache_name, array(), false);
0154         }
0155 
0156         return $token->access_token;
0157     }
0158 
0159     /**
0160      * @return mixed
0161      * @throws Zend_Exception
0162      * @throws Zend_Http_Client_Exception
0163      */
0164     protected function requestHttpAccessToken()
0165     {
0166         $httpClient = new Zend_Http_Client($this->_config->token_url);
0167         //$adapter = new Zend_Http_Client_Adapter_Socket();
0168         //$adapter->setStreamContext(array('ssl' => array('verify_peer' => false,'allow_self_signed' => true,'capture_peer_cert' => false)));
0169         //$httpClient->setAdapter($adapter);
0170         $httpClient->setMethod(Zend_Http_Client::POST);
0171         $httpClient->setHeaders('Content-Type', 'application/x-www-form-urlencoded');
0172         $httpClient->setHeaders('Accept', 'application/json');
0173         $httpClient->setParameterPost(array(
0174             //'username'      => $this->_config->username,
0175             //'password'      => $this->_config->userpass,
0176             'client_id'     => $this->_config->client_id,
0177             'client_secret' => $this->_config->client_secret,
0178             'grant_type'    => 'client_credentials'
0179             //'grant_type'    => 'password',
0180             //'scope'         => 'profile openid user:create user:delete'
0181         ));
0182 
0183         $response = $httpClient->request();
0184 
0185         Zend_Registry::get('logger')->debug(__METHOD__ . " - request: " . $httpClient->getUri(true));
0186         Zend_Registry::get('logger')->debug(__METHOD__ . " - response: " . $response->getRawBody());
0187 
0188         if ($response->getStatus() != 200) {
0189             throw new Zend_Exception('request access token failed. OCS ID server send message: ' . $response->getRawBody());
0190         }
0191 
0192         $data = $this->parseResponse($response);
0193 
0194         return $data;
0195     }
0196 
0197     /**
0198      * @param Zend_Http_Response $response
0199      *
0200      * @return mixed
0201      * @throws Zend_Json_Exception
0202      */
0203     protected function parseResponse(Zend_Http_Response $response)
0204     {
0205         $data = Zend_Json::decode($response->getBody(), Zend_Json::TYPE_OBJECT);
0206 
0207         return $data;
0208     }
0209 
0210     /**
0211      * @param $refresh_token
0212      *
0213      * @return mixed
0214      * @throws Zend_Exception
0215      * @throws Zend_Http_Client_Exception
0216      * @throws Zend_Json_Exception
0217      */
0218     protected function requestHttRefreshToken($refresh_token)
0219     {
0220         $httpClient = new Zend_Http_Client($this->_config->token_url);
0221         $httpClient->setMethod(Zend_Http_Client::POST);
0222         $httpClient->setHeaders('Content-Type', 'application/x-www-form-urlencoded');
0223         $httpClient->setHeaders('Accept', 'application/json');
0224         $httpClient->setParameterPost(array(
0225             'client_id'     => $this->_config->client_id,
0226             'client_secret' => $this->_config->client_secret,
0227             'grant_type'    => 'refresh_token',
0228             'refresh_token' => $refresh_token
0229         ));
0230 
0231         $response = $httpClient->request();
0232 
0233         Zend_Registry::get('logger')->debug(__METHOD__ . " - request: " . $httpClient->getUri(true));
0234         Zend_Registry::get('logger')->debug(__METHOD__ . " - response: " . $response->getRawBody());
0235 
0236         if ($response->getStatus() != 200) {
0237             throw new Zend_Exception('request refresh token failed. OCS ID server send message: ' . $response->getBody());
0238         }
0239 
0240         $data = $this->parseResponse($response);
0241 
0242         return $data;
0243     }
0244 
0245     /**
0246      * @return mixed
0247      */
0248     public function getMessages()
0249     {
0250         return $this->messages;
0251     }
0252 
0253     /**
0254      * @param string     $uri
0255      * @param string     $uid
0256      * @param string     $method
0257      * @param array|null $post_param
0258      *
0259      * @return bool|array
0260      * @throws Zend_Cache_Exception
0261      * @throws Zend_Exception
0262      * @throws Zend_Http_Client_Exception
0263      * @throws Zend_Json_Exception
0264      */
0265     public function httpRequest($uri, $uid, $method = Zend_Http_Client::GET, $post_param = null)
0266     {
0267         $access_token = $this->getAccessToken();
0268         $this->httpClient->resetParameters();
0269         $this->httpClient->setUri($uri);
0270         $this->httpClient->setHeaders('Authorization', 'Bearer ' . $access_token);
0271         $this->httpClient->setHeaders('Content-Type', 'application/json');
0272         $this->httpClient->setHeaders('Accept', 'application/json');
0273         $this->httpClient->setHeaders('User-Agent', $this->_config->user_agent);
0274         $this->httpClient->setMethod($method);
0275         if (isset($post_param)) {
0276             $jsonUserData = Zend_Json::encode($post_param);
0277             $this->httpClient->setRawData($jsonUserData, 'application/json');
0278         }
0279 
0280         $response = $this->httpClient->request();
0281         if ($response->getStatus() < 200 OR $response->getStatus() >= 500) {
0282             $this->messages[] = 'Request failed.(' . $uri . ') OCS OAuth server send message: ' . $response->getBody();
0283 
0284             return false;
0285         }
0286 
0287         $body = Zend_Json::decode($response->getBody());
0288 
0289         if (array_key_exists("message", $body) OR array_key_exists("error", $body)) {
0290             $this->messages[] = "id: {$uid} ($uri) - " . $response->getBody();
0291 
0292             return false;
0293         }
0294 
0295         return $body;
0296     }
0297 
0298     public function resetMessages()
0299     {
0300         $this->messages = array();
0301     }
0302 
0303 }