File indexing completed on 2025-02-09 07:14:37
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 * Created: 19.06.2018 0024 */ 0025 class Default_Model_Ocs_Matrix 0026 { 0027 protected $messages; 0028 protected $auth; 0029 private $httpServer; 0030 private $image_mime_types = array( 0031 // images 0032 'png' => 'image/png', 0033 'jpe' => 'image/jpeg', 0034 'jpeg' => 'image/jpeg', 0035 'jpg' => 'image/jpeg', 0036 'gif' => 'image/gif', 0037 'bmp' => 'image/bmp', 0038 'ico' => 'image/vnd.microsoft.icon', 0039 'tiff' => 'image/tiff', 0040 'tif' => 'image/tiff', 0041 'svg' => 'image/svg+xml', 0042 'svgz' => 'image/svg+xml' 0043 ); 0044 0045 0046 /** 0047 * @inheritDoc 0048 */ 0049 public function __construct($config = null) 0050 { 0051 if (isset($config)) { 0052 $this->config = $config; 0053 } else { 0054 $this->config = Zend_Registry::get('config')->settings->server->chat; 0055 } 0056 $uri = $this->config->host; 0057 $this->httpServer = new Zend_Http_Client($uri, array('keepalive' => true, 'strictredirects' => true)); 0058 } 0059 0060 public function setAvatarFromArray($member_data) 0061 { 0062 if (empty($member_data)) { 0063 return false; 0064 } 0065 0066 $this->messages = array(); 0067 0068 try { 0069 $helperImage = new Default_View_Helper_Image(); 0070 $memberAvatarUrl = $helperImage->Image($member_data['profile_image_url']); 0071 0072 list($fileAvatar,$content_type) = $this->fetchAvatarFile($memberAvatarUrl); 0073 $mime_type = $this->checkValidMimeType($content_type) ? $content_type : $this->get_mime_content_type($member_data['profile_image_url']); 0074 $contentUri = $this->uploadAvatar($fileAvatar, $mime_type); 0075 $matrixUserId = $this->generateUserId(strtolower($member_data['username'])); 0076 $result = $this->setAvatarUrl($matrixUserId, $contentUri); 0077 if (false === $result) { 0078 $this->messages[] = "Fail "; 0079 0080 return false; 0081 } 0082 } catch (Exception $e) { 0083 $this->messages[] = "Fail : " . $e->getMessage(); 0084 0085 return false; 0086 } 0087 $this->messages[] = "set avatar file : Success"; 0088 0089 return true; 0090 } 0091 0092 private function fetchAvatarFile($profile_image_url) 0093 { 0094 $http_client = new Zend_Http_Client($profile_image_url); 0095 $response = $http_client->request(); 0096 if ($response->getStatus() < 200 OR $response->getStatus() >= 400) { 0097 $this->messages[] = 'Request failed.(' . $profile_image_url . ') OCS Matrix server send message: ' . $response->getBody(); 0098 0099 return false; 0100 } 0101 $filename = IMAGES_UPLOAD_PATH . 'tmp/' . md5($profile_image_url); 0102 file_put_contents($filename, $response->getBody()); 0103 $content_type = $response->getHeader('content-type'); 0104 0105 return array($filename,$content_type); 0106 } 0107 0108 private function get_mime_content_type($filename) 0109 { 0110 0111 $mime_types = array( 0112 0113 'txt' => 'text/plain', 0114 'htm' => 'text/html', 0115 'html' => 'text/html', 0116 'php' => 'text/html', 0117 'css' => 'text/css', 0118 'js' => 'application/javascript', 0119 'json' => 'application/json', 0120 'xml' => 'application/xml', 0121 'swf' => 'application/x-shockwave-flash', 0122 'flv' => 'video/x-flv', 0123 // images 0124 'png' => 'image/png', 0125 'jpe' => 'image/jpeg', 0126 'jpeg' => 'image/jpeg', 0127 'jpg' => 'image/jpeg', 0128 'gif' => 'image/gif', 0129 'bmp' => 'image/bmp', 0130 'ico' => 'image/vnd.microsoft.icon', 0131 'tiff' => 'image/tiff', 0132 'tif' => 'image/tiff', 0133 'svg' => 'image/svg+xml', 0134 'svgz' => 'image/svg+xml', 0135 // archives 0136 'zip' => 'application/zip', 0137 'rar' => 'application/x-rar-compressed', 0138 'exe' => 'application/x-msdownload', 0139 'msi' => 'application/x-msdownload', 0140 'cab' => 'application/vnd.ms-cab-compressed', 0141 // audio/video 0142 'mp3' => 'audio/mpeg', 0143 'qt' => 'video/quicktime', 0144 'mov' => 'video/quicktime', 0145 // adobe 0146 'pdf' => 'application/pdf', 0147 'psd' => 'image/vnd.adobe.photoshop', 0148 'ai' => 'application/postscript', 0149 'eps' => 'application/postscript', 0150 'ps' => 'application/postscript', 0151 // ms office 0152 'doc' => 'application/msword', 0153 'rtf' => 'application/rtf', 0154 'xls' => 'application/vnd.ms-excel', 0155 'ppt' => 'application/vnd.ms-powerpoint', 0156 // open office 0157 'odt' => 'application/vnd.oasis.opendocument.text', 0158 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', 0159 ); 0160 0161 $filename_parts = explode('.', $filename); 0162 $ext = strtolower(array_pop($filename_parts)); 0163 if (array_key_exists($ext, $mime_types)) { 0164 return $mime_types[$ext]; 0165 } else if (function_exists('finfo_open')) { 0166 $finfo = finfo_open(FILEINFO_MIME); 0167 $mimetype = finfo_file($finfo, $filename); 0168 finfo_close($finfo); 0169 0170 return $mimetype; 0171 } else { 0172 return 'image/png'; 0173 } 0174 } 0175 0176 private function checkValidMimeType($mime_type) 0177 { 0178 if (in_array(strtolower($mime_type), $this->image_mime_types)) { 0179 return true; 0180 } 0181 0182 return false; 0183 } 0184 0185 private function uploadAvatar($fileAvatar, $mime_type = 'image/png') 0186 { 0187 $auth = $this->authAdmin(); 0188 0189 $filename = basename($fileAvatar); 0190 $uri = $this->config->host . '/_matrix/media/v1/upload?filename=' . $filename; 0191 0192 $file_data = file_get_contents(realpath($fileAvatar)); 0193 $client = new Zend_Http_Client($uri); 0194 $client->setHeaders('Authorization', 'Bearer ' . $auth['access_token']); 0195 $client->setRawData($file_data, $mime_type); 0196 0197 $response = $client->request('POST'); 0198 0199 if ($response->getStatus() < 200 OR $response->getStatus() >= 400) { 0200 $this->messages[] = 'Request failed.(' . $fileAvatar . ') OCS Matrix server send message: ' . $response->getBody(); 0201 0202 return false; 0203 } 0204 0205 try { 0206 $body = Zend_Json_Decoder::decode($response->getBody()); 0207 } catch (Zend_Json_Exception $e) { 0208 Zend_Registry::get('logger')->err(__METHOD__ . ' - ' . $e->getMessage()); 0209 0210 return false; 0211 } 0212 0213 return $body['content_uri']; 0214 } 0215 0216 private function authAdmin() 0217 { 0218 $cache_name = "matrix_auth"; 0219 /** @var Zend_Cache_Core $cache */ 0220 $cache = Zend_Registry::get('cache'); 0221 0222 if (($result = $cache->load($cache_name))) { 0223 return $result; 0224 } 0225 0226 $method = Zend_Http_Client::POST; 0227 $uri = $this->config->host . "/_matrix/client/r0/login"; 0228 $username = $this->config->sudo_user; 0229 $pw = $this->config->sudo_user_pw; 0230 $data = array( 0231 'identifier' => array('type' => 'm.id.user', 'user' => $username), 0232 'initial_device_display_name' => 'ocs webserver', 0233 'password' => $pw, 0234 'type' => 'm.login.password' 0235 ); 0236 try { 0237 $result = $this->httpRequestWithoutToken($uri, $method, $data); 0238 } catch (Exception $e) { 0239 Zend_Registry::get('logger')->err(__METHOD__ . ' - ' . $e->getMessage()); 0240 } 0241 $cache->save($result, $cache_name, array()); 0242 $this->auth = $result; 0243 0244 return $result; 0245 } 0246 0247 private function httpRequestWithoutToken($uri, $method, $post_param) 0248 { 0249 $this->httpServer->resetParameters(true); 0250 $this->httpServer->setUri($uri); 0251 $this->httpServer->setHeaders('Content-Type', 'application/json'); 0252 $this->httpServer->setHeaders('Accept', 'application/json'); 0253 $this->httpServer->setHeaders('User-Agent', $this->config->user_agent); 0254 $this->httpServer->setMethod($method); 0255 if (isset($post_param)) { 0256 $jsonUserData = Zend_Json::encode($post_param); 0257 $this->httpServer->setRawData($jsonUserData, 'application/json'); 0258 } 0259 0260 $response = $this->httpServer->request(); 0261 if ($response->getStatus() < 200 OR $response->getStatus() >= 500) { 0262 $this->messages[] = 'Request failed.(' . $uri . ') OCS Matrix server send message: ' . $response->getBody(); 0263 0264 return false; 0265 } 0266 0267 try { 0268 return Zend_Json::decode($response->getBody()); 0269 } catch (Zend_Json_Exception $e) { 0270 Zend_Registry::get('logger')->err(__METHOD__ . ' - ' . $e->getMessage()); 0271 } 0272 0273 return false; 0274 } 0275 0276 private function generateUserId($username) 0277 { 0278 $auth = $this->authAdmin(); 0279 0280 return "@{$username}:{$auth['home_server']}"; 0281 } 0282 0283 private function setAvatarUrl($userId, $contentUri) 0284 { 0285 $uri = $this->config->host . "/_matrix/client/r0/profile/{$userId}/avatar_url"; 0286 $method = Zend_Http_Client::PUT; 0287 $data = array('avatar_url' => $contentUri); 0288 0289 $result = $this->httpRequest($uri, '', $method, $data); 0290 0291 return $result; 0292 } 0293 0294 /** 0295 * @param string $uri 0296 * @param string $uid 0297 * @param string $method 0298 * @param array|null $post_param 0299 * 0300 * @return bool|array 0301 * @throws Zend_Http_Client_Exception 0302 * @throws Zend_Json_Exception 0303 */ 0304 protected function httpRequest($uri, $uid, $method = Zend_Http_Client::GET, $post_param = null) 0305 { 0306 $auth = $this->authAdmin(); 0307 0308 $this->httpServer->resetParameters(); 0309 $this->httpServer->setUri($uri); 0310 $this->httpServer->setHeaders('Authorization', 'Bearer ' . $auth['access_token']); 0311 $this->httpServer->setHeaders('Content-Type', 'application/json'); 0312 $this->httpServer->setHeaders('Accept', 'application/json'); 0313 $this->httpServer->setHeaders('User-Agent', $this->config->user_agent); 0314 $this->httpServer->setMethod($method); 0315 if (isset($post_param)) { 0316 $jsonUserData = Zend_Json::encode($post_param); 0317 $this->httpServer->setRawData($jsonUserData, 'application/json'); 0318 } 0319 0320 $response = $this->httpServer->request(); 0321 if ($response->getStatus() < 200 OR $response->getStatus() >= 400) { 0322 $this->messages[] = 'Request failed.(' . $uri . ') OCS Matrix server send message: ' . $response->getBody(); 0323 0324 return false; 0325 } 0326 0327 $body = Zend_Json::decode($response->getBody()); 0328 0329 return $body; 0330 } 0331 0332 /** 0333 * @param array $member_data 0334 * @param bool $force 0335 * 0336 * @return bool|array 0337 * @throws Zend_Cache_Exception 0338 * @throws Zend_Exception 0339 * @throws Zend_Http_Client_Exception 0340 * @throws Zend_Json_Exception 0341 */ 0342 public function createUserFromArray($member_data, $force = false) 0343 { 0344 if (empty($member_data)) { 0345 return false; 0346 } 0347 0348 $this->messages = array(); 0349 0350 $usernameAvailable = $this->createUserAvailable($member_data['username']); 0351 0352 if ($usernameAvailable) { 0353 try { 0354 $method = Zend_Http_Client::POST; 0355 $uri = $this->config->host . "/_matrix/client/r0/register?kind=user"; 0356 $session = $this->fetchSessionInfo($uri, Zend_Http_Client::POST, array('auth' => array())); 0357 $data = array_merge($session, array('username' => $member_data['username'], 'password' => $member_data['password'])); 0358 $userLogin = $this->httpRequestWithoutToken($uri, $method, $data); 0359 if (false === $userLogin) { 0360 $this->messages[] = "Fail "; 0361 0362 return false; 0363 } 0364 $fileAvatar = $this->fetchAvatarFile($member_data['profile_image_url']); 0365 $contentUri = $this->uploadAvatar($fileAvatar); 0366 $result = $this->setAvatarUrl($userLogin['user_id'], $contentUri); 0367 if (false === $result) { 0368 $this->messages[] = "Fail "; 0369 0370 return false; 0371 } 0372 } catch (Exception $e) { 0373 $this->messages[] = "Fail : " . $e->getMessage(); 0374 0375 return false; 0376 } 0377 $this->messages[] = "Create : Success"; 0378 0379 return $userLogin; 0380 } 0381 0382 $this->messages[] = 'Fail : username already exists.'; 0383 0384 return false; 0385 } 0386 0387 private function createUserAvailable($username) 0388 { 0389 try { 0390 $result = $this->httpRequest("{$this->config->host}/_matrix/client/r0/register/available?username={$username}", $username); 0391 } catch (Zend_Exception $e) { 0392 Zend_Registry::get('logger')->err(__METHOD__ . ' - ' . $e->getMessage()); 0393 } 0394 0395 return (isset($result['available']) && $result['available'] == true) ? true : false; 0396 } 0397 0398 private function fetchSessionInfo($uri, $method = Zend_Http_Client::POST, $post_param = null) 0399 { 0400 $response = $this->httpRequestWithoutToken($uri, $method, $post_param); 0401 0402 if ($response) { 0403 return array('auth' => array('type' => $response['flows'][0]['stages'][0], 'session' => $response['session'])); 0404 } 0405 0406 return array(); 0407 } 0408 0409 /** 0410 * @return mixed 0411 */ 0412 public function getMessages() 0413 { 0414 return $this->messages; 0415 } 0416 0417 private function requestAccess($uri, $uid, $method, $post_param) 0418 { 0419 $this->httpServer->resetParameters(true); 0420 $this->httpServer->setUri($uri); 0421 $this->httpServer->setHeaders('Content-Type', 'application/json'); 0422 $this->httpServer->setHeaders('Accept', 'application/json'); 0423 $this->httpServer->setHeaders('User-Agent', $this->config->user_agent); 0424 $this->httpServer->setMethod($method); 0425 if (isset($post_param)) { 0426 $jsonUserData = Zend_Json::encode($post_param); 0427 $this->httpServer->setRawData($jsonUserData, 'application/json'); 0428 } 0429 0430 $response = $this->httpServer->request(); 0431 if ($response->getStatus() < 200 OR $response->getStatus() >= 400) { 0432 $this->messages[] = 'Request failed.(' . $uri . ') OCS Matrix server send message: ' . $response->getBody(); 0433 0434 return false; 0435 } 0436 0437 $body = Zend_Json::decode($response->getBody()); 0438 0439 return $body; 0440 } 0441 0442 }