File indexing completed on 2025-02-09 07:14:36

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_Gitlab
0026 {
0027     /** @var  Zend_Cache_Core */
0028     protected $cache;
0029     protected $config;
0030     protected $messages;
0031     /** @var Zend_Http_Client */
0032     protected $httpClient;
0033 
0034     /**
0035      * @inheritDoc
0036      */
0037     public function __construct($config = null)
0038     {
0039         if (isset($config)) {
0040             $this->config = $config;
0041         } else {
0042             $this->config = Zend_Registry::get('config')->settings->server->opencode;
0043         }
0044         $uri = $this->config->host;
0045         $this->httpClient = $this->getHttpClient($uri);
0046 
0047         $this->cache = Zend_Registry::get('cache');
0048         $this->messages = array();
0049     }
0050 
0051     /**
0052      * @param $uri
0053      * @return Zend_Http_Client
0054      * @throws Default_Model_Ocs_Gitlab_Exception
0055      */
0056     protected function getHttpClient($uri)
0057     {
0058         try {
0059             if (empty($uri)) {
0060                 return new Zend_Http_Client(null, array('keepalive' => true, 'strictredirects' => true));
0061             }
0062 
0063             return new Zend_Http_Client($uri, array('keepalive' => true, 'strictredirects' => true));
0064         } catch (Zend_Exception $e) {
0065             throw new Default_Model_Ocs_Gitlab_Exception('Can not create http client for uri: ' . $uri, 0, $e);
0066         }
0067     }
0068 
0069     /**
0070      * @param int|array $member_data
0071      *
0072      * @return bool
0073      * @throws Default_Model_Ocs_Exception
0074      * @throws Zend_Exception
0075      */
0076     public function unblockUserProjects($member_data)
0077     {
0078         if (is_int($member_data)) {
0079             $member_data = $this->getMemberData($member_data, false);
0080         }
0081 
0082         if (empty($member_data)) {
0083             return false;
0084         }
0085 
0086         $user = $this->getUser($member_data['external_id'], $member_data['username']);
0087         if (false === $user) {
0088             return false;
0089         }
0090 
0091         $uri = $this->config->host . "/api/v4/users/{$user['id']}/projects";
0092         $method = Zend_Http_Client::GET;
0093         $uid = $member_data['member_id'];
0094         try {
0095             $response = $this->httpRequest($uri, $uid, $method);
0096             if (false === $response) {
0097                 $this->messages[] = "Fail ";
0098 
0099                 return false;
0100             }
0101         } catch (Zend_Exception $e) {
0102             $this->messages[] = "Fail " . $e->getMessage();
0103 
0104             return false;
0105         }
0106 
0107         $memberLog = new Default_Model_MemberDeactivationLog();
0108         foreach ($response as $project) {
0109             $log_data =
0110                 $memberLog->getLogEntries($member_data['member_id'],
0111                     Default_Model_MemberDeactivationLog::OBJ_TYPE_GITLAB_PROJECT,
0112                     $project['id']);
0113             if (false === $log_data) {
0114                 continue;
0115             }
0116             $object_data = json_decode($log_data['object_data'], true);
0117             $visibility = $object_data['visibility'];
0118 
0119             $uri = $this->config->host . "/api/v4/projects/{$project['id']}";
0120             $method = Zend_Http_Client::PUT;
0121             $uid = $member_data['member_id'];
0122             $data = array('visibility' => $visibility);
0123             try {
0124                 $response = $this->httpRequest($uri, $uid, $method, $data);
0125                 if (false === $response) {
0126                     $this->messages[] = "Fail " . $uri;
0127 
0128                     continue;
0129                 }
0130             } catch (Zend_Exception $e) {
0131                 $this->messages[] = "Fail " . $e->getMessage();
0132 
0133                 return false;
0134             }
0135             $this->messages[] = "Successful unblock user project: {$project['id']}";
0136 
0137             $memberLog->deleteLog($member_data['member_id'],
0138                 Default_Model_MemberDeactivationLog::OBJ_TYPE_GITLAB_PROJECT,
0139                 $project['id']);
0140         }
0141 
0142         return true;
0143     }
0144 
0145     /**
0146      * @param int  $member_id
0147      *
0148      * @param bool $onlyActive
0149      *
0150      * @return array
0151      * @throws Default_Model_Ocs_Exception
0152      */
0153     private function getMemberData($member_id, $onlyActive = true)
0154     {
0155 
0156         $onlyActiveFilter = '';
0157         if ($onlyActive) {
0158             $onlyActiveFilter =
0159                 " AND `m`.`is_active` = 1 AND `m`.`is_deleted` = 0 AND `me`.`email_checked` IS NOT NULL AND `me`.`email_deleted` = 0";
0160         }
0161         $sql = "
0162             SELECT `mei`.`external_id`,`m`.`member_id`, `m`.`username`, `me`.`email_address`, `m`.`password`, `m`.`roleId`, `m`.`firstname`, `m`.`lastname`, `m`.`profile_image_url`, `m`.`biography`, `m`.`created_at`, `m`.`changed_at`, `m`.`source_id`
0163             FROM `member` AS `m`
0164             LEFT JOIN `member_email` AS `me` ON `me`.`email_member_id` = `m`.`member_id` AND `me`.`email_primary` = 1
0165             LEFT JOIN `member_external_id` AS `mei` ON `mei`.`member_id` = `m`.`member_id`
0166             WHERE `m`.`member_id` = :memberId {$onlyActiveFilter}
0167             ORDER BY `m`.`member_id` DESC
0168         ";
0169 
0170         $result = Zend_Db_Table::getDefaultAdapter()->fetchRow($sql, array('memberId' => $member_id));
0171         if (count($result) == 0) {
0172             throw new Default_Model_Ocs_Exception('member with id ' . $member_id . ' could not found.');
0173         }
0174 
0175         return $result;
0176     }
0177 
0178     /**
0179      * @param $extern_uid
0180      * @param $username
0181      *
0182      * @return array|false
0183      * @throws Zend_Exception
0184      */
0185     public function getUser($extern_uid, $username)
0186     {
0187         $user_by_uid = $this->getUserByExternUid($extern_uid);
0188 
0189         if (false === empty($user_by_uid)) {
0190             return $user_by_uid;
0191         }
0192         $this->messages[] = "external id not found. external_id: " . $extern_uid;
0193 
0194         $user_by_dn = $this->getUserByDN(urlencode($username));
0195 
0196         if (false === empty($user_by_dn)) {
0197             return $user_by_dn;
0198         }
0199         $this->messages[] = "ldap dn not found. username: " . $username;
0200 
0201         $user_by_name = $this->getUserWithName(urlencode($username));
0202 
0203         if (false === empty($user_by_name)) {
0204             return $user_by_name;
0205         }
0206         $this->messages[] = "username not found. username: " . $username;
0207 
0208         return false;
0209     }
0210 
0211     /**
0212      * @param string $extern_uid
0213      *
0214      * @return array
0215      * @throws Zend_Exception
0216      */
0217     public function getUserByExternUid($extern_uid)
0218     {
0219         $uri = $this->config->host . "/api/v4/users?extern_uid={$extern_uid}&provider=" . $this->config->provider_name;
0220         $body = $this->httpRequest($uri, $extern_uid);
0221 
0222         if (count($body) == 0) {
0223             return array();
0224         }
0225 
0226         Zend_Registry::get('logger')->debug(__METHOD__ . " - body: " . $body);
0227 
0228         return $body[0];
0229     }
0230 
0231     /**
0232      * @param string     $uri
0233      * @param string     $uid
0234      * @param string     $method
0235      * @param array|null $post_param
0236      *
0237      * @return bool|array
0238      */
0239     protected function httpRequest($uri, $uid, $method = Zend_Http_Client::GET, $post_param = null)
0240     {
0241         $body = array();
0242         try {
0243             $this->httpClient->setUri($uri);
0244         } catch (Zend_Http_Client_Exception $e) {
0245             $this->messages[] = 'Request failed.(' . $uri . ') setUri error message: ' . $e->getMessage();
0246 
0247             return false;
0248         } catch (Zend_Uri_Exception $e) {
0249             $this->messages[] = 'Request failed.(' . $uri . ') setUri error message: ' . $e->getMessage();
0250 
0251             return false;
0252         }
0253         $this->httpClient->resetParameters();
0254         try {
0255             $this->httpClient->setHeaders('Private-Token', $this->config->private_token);
0256             $this->httpClient->setHeaders('Sudo', $this->config->user_sudo);
0257             $this->httpClient->setHeaders('User-Agent', $this->config->user_agent);
0258             $this->httpClient->setMethod($method);
0259         } catch (Zend_Http_Client_Exception $e) {
0260             $this->messages[] = 'Request failed.(' . $uri . ') setHeaders error message: ' . $e->getMessage();
0261 
0262             return false;
0263         }
0264         if (isset($post_param)) {
0265             $this->httpClient->setParameterPost($post_param);
0266         }
0267 
0268         try {
0269             $response = $this->httpClient->request();
0270         } catch (Zend_Http_Client_Exception $e) {
0271             $this->messages[] = 'Request failed.(' . $uri . ') request error message: ' . $e->getMessage();
0272 
0273             return false;
0274         }
0275         if ($response->getStatus() < 200 OR $response->getStatus() >= 500) {
0276             $this->messages[] = 'Request failed.(' . $uri . ') OCS Forum server send message: ' . $response->getBody();
0277 
0278             return false;
0279         }
0280 
0281         try {
0282             $body = Zend_Json::decode($response->getBody());
0283         } catch (Zend_Json_Exception $e) {
0284             $this->messages[] = 'Request failed.(' . $uri . ') Zend_Json::decode error message: ' . $e->getMessage();
0285         }
0286 
0287         if ($body && is_array($body) && array_key_exists("message", $body)) {
0288             $this->messages[] = "id: {$uid} ($uri) - " . Zend_Json::encode($body["message"]);
0289         }
0290 
0291         return $body;
0292     }
0293 
0294     /**
0295      * @param $username
0296      *
0297      * @return array
0298      * @throws Zend_Exception
0299      */
0300     public function getUserByDN($username)
0301     {
0302         $user_id = $this->buildUserDn($username);
0303         $uri = $this->config->host . "/api/v4/users?extern_uid={$user_id}&provider=ldapmain";
0304 
0305         $body = $this->httpRequest($uri, $username);
0306 
0307         if (count($body) == 0) {
0308             return array();
0309         }
0310 
0311         Zend_Registry::get('logger')->debug(__METHOD__ . " - body: " . $body);
0312 
0313         return $body[0];
0314     }
0315 
0316     /**
0317      * @param string $extern_uid
0318      *
0319      * @return string
0320      * @throws Zend_Exception
0321      */
0322     private function buildUserDn($extern_uid)
0323     {
0324         $username = mb_strtolower($extern_uid);
0325         $baseDn = Default_Model_Ocs_Ldap::getBaseDn();
0326         $dn = "cn={$username},{$baseDn}";
0327 
0328         return $dn;
0329     }
0330 
0331     /**
0332      * @param string $username
0333      *
0334      * @return array
0335      * @throws Zend_Exception
0336      */
0337     public function getUserWithName($username)
0338     {
0339         $uri = $this->config->host . "/api/v4/users?username=" . $username;
0340         $body = $this->httpRequest($uri, $username);
0341 
0342         if (count($body) == 0) {
0343             return array();
0344         }
0345 
0346         Zend_Registry::get('logger')->debug(__METHOD__ . " - body: " . print_r($body,true));
0347 
0348         return $body[0];
0349     }
0350 
0351     /**
0352      * @param array $member_data
0353      * @return bool
0354      * @throws Default_Model_Ocs_Exception
0355      * @throws Zend_Exception
0356      */
0357     public function blockUserProjects($member_data)
0358     {
0359         if (is_int($member_data)) {
0360             $member_data = $this->getMemberData($member_data, false);
0361         }
0362 
0363         if (empty($member_data)) {
0364             return false;
0365         }
0366 
0367         $user = $this->getUser($member_data['external_id'], $member_data['username']);
0368         if (false === $user) {
0369             return false;
0370         }
0371 
0372         $uri = $this->config->host . "/api/v4/users/{$user['id']}/projects";
0373         $method = Zend_Http_Client::GET;
0374         $uid = $member_data['member_id'];
0375         try {
0376             $response = $this->httpRequest($uri, $uid, $method);
0377             if (false === $response) {
0378                 $this->messages[] = "Fail ";
0379 
0380                 return false;
0381             }
0382         } catch (Zend_Exception $e) {
0383             $this->messages[] = "Fail " . $e->getMessage();
0384 
0385             return false;
0386         }
0387 
0388         foreach ($response as $project) {
0389             $memberLog = new Default_Model_MemberDeactivationLog();
0390             $memberLog->addLogData($member_data['member_id'],
0391                 Default_Model_MemberDeactivationLog::OBJ_TYPE_GITLAB_PROJECT,
0392                 $project['id'], json_encode($project));
0393 
0394             $uri = $this->config->host . "/api/v4/projects/{$project['id']}";
0395             $method = Zend_Http_Client::PUT;
0396             $uid = $member_data['member_id'];
0397             $data = array('visibility' => 'private');
0398             try {
0399                 $response = $this->httpRequest($uri, $uid, $method, $data);
0400                 if (false === $response) {
0401                     $this->messages[] = "Fail " . $uri;
0402 
0403                     continue;
0404                 }
0405             } catch (Zend_Exception $e) {
0406                 $this->messages[] = "Fail " . $e->getMessage();
0407 
0408                 return false;
0409             }
0410 
0411             $this->messages[] = "Successful block user project: {$project['id']}";
0412         }
0413 
0414         return true;
0415     }
0416 
0417     /**
0418      * @param int|array $member_data
0419      *
0420      * @return bool
0421      * @throws Default_Model_Ocs_Exception
0422      * @throws Zend_Exception
0423      */
0424     public function blockUser($member_data)
0425     {
0426         if (is_int($member_data)) {
0427             $member_data = $this->getMemberData($member_data, false);
0428         }
0429 
0430         if (empty($member_data)) {
0431             return false;
0432         }
0433 
0434         $user = $this->getUser($member_data['external_id'], $member_data['username']);
0435         if (false === $user) {
0436 
0437             return false;
0438         }
0439 
0440         $uri = $this->config->host . "/api/v4/users/{$user['id']}/block";
0441         $method = Zend_Http_Client::POST;
0442         $uid = $member_data['member_id'];
0443 
0444         try {
0445             $response = $this->httpRequest($uri, $uid, $method);
0446             if (false === $response) {
0447                 $this->messages[] = "Fail ";
0448 
0449                 return false;
0450             }
0451         } catch (Zend_Exception $e) {
0452             $this->messages[] = "Fail " . $e->getMessage();
0453 
0454             return false;
0455         }
0456 
0457         $this->messages[] = "Successful block user: {$member_data['username']}";
0458 
0459         $memberLog = new Default_Model_MemberDeactivationLog();
0460         $memberLog->addLog($member_data['member_id'], Default_Model_MemberDeactivationLog::OBJ_TYPE_GITLAB_USER,
0461             $user['id']);
0462 
0463         return true;
0464     }
0465 
0466     /**
0467      * @param int|array $member_data
0468      *
0469      * @return bool
0470      * @throws Default_Model_Ocs_Exception
0471      * @throws Zend_Exception
0472      */
0473     public function unblockUser($member_data)
0474     {
0475         if (is_int($member_data)) {
0476             $member_data = $this->getMemberData($member_data, false);
0477         }
0478 
0479         if (empty($member_data)) {
0480             return false;
0481         }
0482 
0483         $user = $this->getUser($member_data['external_id'], $member_data['username']);
0484         if (false === $user) {
0485             return false;
0486         }
0487 
0488         $uri = $this->config->host . "/api/v4/users/{$user['id']}/unblock";
0489         $method = Zend_Http_Client::POST;
0490         $uid = $member_data['member_id'];
0491 
0492         try {
0493             $response = $this->httpRequest($uri, $uid, $method);
0494             if (false === $response) {
0495                 $this->messages[] = "Fail ";
0496 
0497                 return false;
0498             }
0499         } catch (Zend_Exception $e) {
0500             $this->messages[] = "Fail " . $e->getMessage();
0501 
0502             return false;
0503         }
0504 
0505         $this->messages[] = "Successful unblock user: {$member_data['username']}";
0506 
0507         $memberLog = new Default_Model_MemberDeactivationLog();
0508         $memberLog->deleteLog($member_data['member_id'], Default_Model_MemberDeactivationLog::OBJ_TYPE_GITLAB_USER,
0509             $user['id']);
0510 
0511         return true;
0512     }
0513 
0514     /**
0515      * @param int|array $member_data
0516      * @param string    $oldUsername
0517      *
0518      * @return array|bool|null
0519      * @throws Zend_Exception
0520      */
0521     public function updateUserFromArray($member_data, $oldUsername)
0522     {
0523         if (empty($member_data)) {
0524             return false;
0525         }
0526 
0527         $this->messages = array();
0528 
0529         $data = $this->mapUserData($member_data);
0530 
0531         $user = $this->getUser($data['extern_uid'], $oldUsername);
0532 
0533         if (false === $user) {
0534             $this->messages[] = "Fail";
0535 
0536             return false;
0537         }
0538         //        $data['skip_reconfirmation'] = 'true';
0539         //        unset($data['password']);
0540 
0541         try {
0542             foreach ($data as $datum) {
0543                 $datum['skip_reconfirmation'] = 'true';
0544                 unset($datum['password']);
0545 
0546                 $this->httpUserUpdate($data, $user['id']);
0547             }
0548         } catch (Zend_Exception $e) {
0549             $this->messages[] = "Fail " . $e->getMessage();
0550 
0551             return false;
0552         }
0553         $this->messages[] = "overwritten : " . json_encode($user);
0554 
0555         return $user;
0556     }
0557 
0558     /**
0559      * @param array $user
0560      *
0561      * @return array
0562      * @throws Zend_Exception
0563      */
0564     protected function mapUserData($user)
0565     {
0566         $paramEmail = '';
0567         if (isset($user['email_address'])) {
0568             $paramEmail = $user['email_address'];
0569         } else {
0570             if (isset($user['mail'])) {
0571                 $paramEmail = $user['mail'];
0572             }
0573         }
0574 
0575         if (strlen($user['biography']) > 254) {
0576             $helperTruncate = new Default_View_Helper_Truncate();
0577             $bio = $helperTruncate->truncate($user['biography'], 250);
0578         } else {
0579             $bio = empty($user['biography']) ? '' : $user['biography'];
0580         }
0581 
0582         $data = array(
0583             array(
0584                 'email'            => $paramEmail,
0585                 'username'         => mb_strtolower($user['username']),
0586                 //                'name'             => (false == empty($user['lastname'])) ? trim($user['firstname'] . ' ' . $user['lastname']) : $user['username'],
0587                 'name'             => $user['username'],
0588                 'password'         => $user['password'],
0589                 'provider'         => $this->config->provider_name,
0590                 'extern_uid'       => $user['external_id'],
0591                 'bio'              => $bio,
0592                 'admin'            => $user['roleId'] == 100 ? 'true' : 'false',
0593                 'can_create_group' => 'true'
0594             ),
0595             array(
0596                 'email'            => $paramEmail,
0597                 'username'         => mb_strtolower($user['username']),
0598                 //                'name'             => (false == empty($user['lastname'])) ? trim($user['firstname'] . ' ' . $user['lastname']) : $user['username'],
0599                 'name'             => $user['username'],
0600                 'password'         => $user['password'],
0601                 'provider'         => "ldapmain",
0602                 'extern_uid'       => $this->buildUserDn($user['username']),
0603                 'bio'              => $bio,
0604                 'admin'            => $user['roleId'] == 100 ? 'true' : 'false',
0605                 'can_create_group' => 'true'
0606             )
0607         );
0608 
0609         return $data;
0610     }
0611 
0612     /**
0613      * @param $data
0614      *
0615      * @param $id
0616      *
0617      * @return bool
0618      * @throws Zend_Exception
0619      * @throws Zend_Http_Client_Exception
0620      * @throws Zend_Http_Exception
0621      */
0622     private function httpUserUpdate($data, $id)
0623     {
0624         $uri = $this->config->host . '/api/v4/users/' . $id;
0625         $this->httpClient->resetParameters();
0626         $this->httpClient->setUri($uri);
0627         $this->httpClient->setHeaders('Private-Token', $this->config->private_token);
0628         $this->httpClient->setHeaders('Sudo', $this->config->user_sudo);
0629         $this->httpClient->setHeaders('User-Agent', $this->config->user_agent);
0630         $this->httpClient->setMethod(Zend_Http_Client::PUT);
0631         $this->httpClient->setParameterPost($data);
0632 
0633         $response = $this->httpClient->request();
0634         if ($response->getStatus() < 200 OR $response->getStatus() >= 300) {
0635             throw new Default_Model_Ocs_Exception('update user data failed. OCS OpenCode server send message: '
0636                                                   . $response->getRawBody());
0637         }
0638 
0639         $body = Zend_Json::decode($response->getRawBody());
0640         if (array_key_exists("message", $body)) {
0641             throw new Default_Model_Ocs_Exception($body["message"]);
0642         }
0643 
0644         Zend_Registry::get('logger')->debug(__METHOD__ . ' - request: ' . $uri);
0645         Zend_Registry::get('logger')->debug(__METHOD__ . ' - response: ' . $response->getRawBody());
0646 
0647         return $body;
0648     }
0649 
0650     /**
0651      * @param string $email
0652      *
0653      * @return array
0654      * @throws Default_Model_Ocs_Exception
0655      * @throws Zend_Exception
0656      * @throws Zend_Http_Client_Exception
0657      * @throws Zend_Json_Exception
0658      */
0659     public function getUserByEmail($email)
0660     {
0661         $uri = $this->config->host . "/api/v4/users?search={$email}";
0662         $this->httpClient->resetParameters();
0663         $this->httpClient->setUri($uri);
0664         $this->httpClient->setHeaders('Private-Token', $this->config->private_token);
0665         $this->httpClient->setHeaders('Sudo', $this->config->user_sudo);
0666         $this->httpClient->setHeaders('User-Agent', $this->config->user_agent);
0667         $this->httpClient->setMethod(Zend_Http_Client::GET);
0668 
0669         $response = $this->httpClient->request();
0670 
0671         $body = Zend_Json::decode($response->getRawBody());
0672 
0673         if (count($body) == 0) {
0674             return array();
0675         }
0676 
0677         if (array_key_exists("message", $body)) {
0678             $result_code = substr(trim($body["message"]), 0, 3);
0679             if ((int)$result_code >= 300) {
0680                 throw new Default_Model_Ocs_Exception($body["message"]);
0681             }
0682         }
0683 
0684         Zend_Registry::get('logger')->debug(__METHOD__ . " - body: " . $response->getRawBody());
0685 
0686         return $body;
0687     }
0688 
0689     /**
0690      * @param array $member
0691      * @param array $userSubsystem
0692      *
0693      * @return array
0694      * @throws Zend_Exception
0695      */
0696     public function validateUserData($member, $userSubsystem)
0697     {
0698         $userDn = $this->buildUserDn(strtolower($member['username']));
0699         $result = array();
0700 
0701         if (mb_strtolower($member['email_address']) != $userSubsystem['email']) {
0702             $result[] = 'email_address<=>email';
0703             $result[] = $member['email_address'] . '<=>' . $userSubsystem['email'];
0704         }
0705         if (mb_strtolower($member['username']) != $userSubsystem['username']) {
0706             $result[] = 'username<=>username';
0707             $result[] = mb_strtolower($member['username']) . '<=>' . $userSubsystem['username'];
0708         }
0709         if ($member['username'] != $userSubsystem['name']) {
0710             $result[] = 'username<=>name';
0711             $result[] = $member['username'] . '<=>' . $userSubsystem['name'];
0712         }
0713         if (($member['roleId'] == 100 ? true : false) != $userSubsystem['is_admin']) {
0714             $result[] = 'roleId<=>admin';
0715             $result[] = $member['roleId'] . '<=>' . $userSubsystem['admin'];
0716         }
0717         if ("active" != $userSubsystem['state']) {
0718             $result[] = 'is_active<=>state';
0719             $result[] = ($member['is_active'] ? 'active' : 'inactive') . '<=>' . $userSubsystem['state'];
0720         }
0721         if (false === array_search('oauth_opendesktop', array_column($userSubsystem['identities'], 'provider'))) {
0722             $result[] = 'oauth_opendesktop missing';
0723         }
0724         $provider = array_column($userSubsystem['identities'], 'extern_uid', 'provider');
0725         $providerOauth = isset($provider['oauth_opendesktop']) ? $provider['oauth_opendesktop'] : '';
0726         if ($member['external_id'] != $providerOauth) {
0727             $result[] = 'external_id<=>oauth_opendesktop->extern_uid';
0728             $result[] = $member['external_id'] . '<=>' . $providerOauth;
0729         }
0730         if (false === array_search('ldapmain', array_column($userSubsystem['identities'], 'provider'))) {
0731             $result[] = 'ldapmain missing';
0732         }
0733         $providerLdap = isset($provider['ldapmain']) ? $provider['ldapmain'] : '';
0734         if ($userDn != $providerLdap) {
0735             $result[] = 'userDn<=>ldapmain->extern_uid';
0736             $result[] = $userDn . '<=>' . $providerLdap;
0737         }
0738 
0739         return $result;
0740     }
0741 
0742     public function resetMessages()
0743     {
0744         $this->messages = array();
0745     }
0746 
0747     /**
0748      * @param array $member_data
0749      * @param bool  $force
0750      *
0751      * @return array|bool
0752      * @throws Zend_Exception
0753      */
0754     public function createUserFromArray($member_data, $force = false)
0755     {
0756         if (empty($member_data)) {
0757             return false;
0758         }
0759 
0760         $this->messages = array();
0761 
0762         $data = $this->mapUserData($member_data);
0763 
0764         $user = $this->getUser($member_data['external_id'], $member_data['username']);
0765 
0766         $updatedUser = null;
0767 
0768         if (false === $user) {
0769             try {
0770                 $data[0]['skip_confirmation'] = 'true';
0771                 $user = $this->httpUserCreate($data[0]);
0772                 $this->messages[] = "created : " . json_encode($user);
0773                 $data[1]['skip_reconfirmation'] = 'true';
0774                 $updatedUser = $this->httpUserUpdate($data[1], $user['id']);
0775                 $this->messages[] = "updated : " . json_encode($updatedUser);
0776             } catch (Zend_Exception $e) {
0777                 $this->messages[] = "Fail " . $e->getMessage();
0778 
0779                 return false;
0780             }
0781 
0782             return $updatedUser;
0783         }
0784 
0785         if ($force === true) {
0786             try {
0787                 foreach ($data as $datum) {
0788                     $datum['skip_reconfirmation'] = 'true';
0789                     unset($datum['password']);
0790                     $updatedUser = $this->httpUserUpdate($datum, $user['id']);
0791                 }
0792             } catch (Zend_Exception $e) {
0793                 $this->messages[] = "Fail " . $e->getMessage();
0794 
0795                 return false;
0796             }
0797             $this->messages[] = "overwritten : " . json_encode($updatedUser);
0798 
0799             return $updatedUser;
0800         }
0801 
0802         $this->messages[0] = 'user already exists.';
0803 
0804         return false;
0805     }
0806 
0807     /**
0808      * @param array $data
0809      *
0810      * @return bool
0811      * @throws Default_Model_Ocs_Exception
0812      * @throws Zend_Exception
0813      * @throws Zend_Http_Client_Exception
0814      * @throws Zend_Json_Exception
0815      */
0816     private function httpUserCreate($data)
0817     {
0818         $uri = $this->config->host . '/api/v4/users';
0819         $this->httpClient->resetParameters();
0820         $this->httpClient->setUri($uri);
0821         $this->httpClient->setHeaders('Private-Token', $this->config->private_token);
0822         $this->httpClient->setHeaders('Sudo', $this->config->user_sudo);
0823         $this->httpClient->setHeaders('User-Agent', $this->config->user_agent);
0824         $this->httpClient->setMethod(Zend_Http_Client::POST);
0825         $this->httpClient->setParameterPost($data);
0826 
0827         $response = $this->httpClient->request();
0828         if ($response->getStatus() < 200 OR $response->getStatus() >= 300) {
0829             throw new Default_Model_Ocs_Exception('push user data failed. OCS OpenCode server send message: '
0830                                                   . $response->getRawBody());
0831         }
0832 
0833         $body = Zend_Json::decode($response->getRawBody());
0834         if (array_key_exists("message", $body)) {
0835             throw new Default_Model_Ocs_Exception(Zend_Json::encode($body["message"]));
0836         }
0837 
0838         Zend_Registry::get('logger')->debug(__METHOD__ . ' - request: ' . $uri);
0839         Zend_Registry::get('logger')->debug(__METHOD__ . ' - response: ' . $response->getRawBody());
0840 
0841         return $body;
0842     }
0843 
0844     /**
0845      * @param int $member_id
0846      *
0847      * @return bool
0848      * @throws Default_Model_Ocs_Exception
0849      * @throws Zend_Exception
0850      * @throws Zend_Http_Client_Exception
0851      * @throws Zend_Http_Exception
0852      */
0853     public function deleteUser($member_id)
0854     {
0855         if (empty($member_id)) {
0856             return false;
0857         }
0858 
0859         $member_data = $this->getMemberData($member_id, false);
0860 
0861         $user = $this->getUser($member_data['external_id'], mb_strtolower($member_data['username']));
0862 
0863         if (false === $user) {
0864             $this->messages[0] = 'Not deleted. User not exists. ';
0865 
0866             return false;
0867         }
0868 
0869         return $this->httpUserDelete($user['id']);
0870     }
0871 
0872     /**
0873      * @param $id
0874      *
0875      * @return bool
0876      * @throws Zend_Exception
0877      * @throws Zend_Http_Client_Exception
0878      * @throws Zend_Http_Exception
0879      */
0880     private function httpUserDelete($id)
0881     {
0882         $uri = $this->config->host . '/api/v4/users/' . $id;
0883         $this->httpClient->resetParameters();
0884         $this->httpClient->setUri($uri);
0885         $this->httpClient->setHeaders('Private-Token', $this->config->private_token);
0886         $this->httpClient->setHeaders('Sudo', $this->config->user_sudo);
0887         $this->httpClient->setHeaders('User-Agent', $this->config->user_agent);
0888         $this->httpClient->setMethod(Zend_Http_Client::DELETE);
0889 
0890         $response = $this->httpClient->request();
0891 
0892         if (204 == $response->getStatus()) {
0893             $this->messages[0] = ' - response : ' . $response->getRawBody() . " - user id: {$id}";
0894 
0895             return true;
0896         }
0897 
0898         if ($response->getStatus() < 200 AND $response->getStatus() >= 300) {
0899             throw new Default_Model_Ocs_Exception('delete user failed. OCS OpenCode server send message: ' . $response->getRawBody()
0900                                                   . PHP_EOL . " - OpenCode user id: {$id}");
0901         }
0902 
0903         $body = Zend_Json::decode($response->getRawBody());
0904         if (array_key_exists("message", $body)) {
0905             throw new Default_Model_Ocs_Exception($body["message"]);
0906         }
0907 
0908         Zend_Registry::get('logger')->debug(__METHOD__ . ' - request: ' . $uri);
0909         Zend_Registry::get('logger')->debug(__METHOD__ . ' - response: ' . $response->getRawBody());
0910 
0911         $this->messages[0] = ' - response : ' . $response->getRawBody() . " - user id: {$id}";
0912 
0913         return true;
0914     }
0915 
0916     /**
0917      * @param string $username
0918      *
0919      * @return bool
0920      * @throws Zend_Exception
0921      * @throws Zend_Http_Client_Exception
0922      * @throws Zend_Json_Exception
0923      */
0924     public function userExists($username)
0925     {
0926         $uri = $this->config->host . '/api/v4/users?username=' . $username;
0927         $this->httpClient->resetParameters();
0928         $this->httpClient->setUri($uri);
0929         $this->httpClient->setHeaders('Private-Token', $this->config->private_token);
0930         $this->httpClient->setHeaders('Sudo', $this->config->user_sudo);
0931         $this->httpClient->setHeaders('User-Agent', $this->config->user_agent);
0932         $this->httpClient->setMethod(Zend_Http_Client::GET);
0933 
0934         $response = $this->httpClient->request();
0935 
0936         $body = Zend_Json::decode($response->getRawBody());
0937         if (array_key_exists("message", $body)) {
0938             throw new Default_Model_Ocs_Exception($body["message"]);
0939         }
0940 
0941         if (count($body) == 0) {
0942             return false;
0943         }
0944 
0945         Zend_Registry::get('logger')->debug(__METHOD__ . ' - request: ' . $uri);
0946         Zend_Registry::get('logger')->debug(__METHOD__ . ' - response: ' . $response->getBody());
0947 
0948         if ($response->getStatus() < 200 AND $response->getStatus() >= 300) {
0949             throw new Zend_Exception('exists user failed. OCS OpenCode server send message: ' . $response->getBody() . PHP_EOL
0950                                      . " - OpenCode user id: {$username}");
0951         }
0952 
0953         $this->messages[0] =
0954             ' - response for user exists request: ' . $response->getBody() . PHP_EOL . " - OpenCode user id: {$username}" . PHP_EOL;
0955 
0956         return $body[0]['id'];
0957     }
0958 
0959     /**
0960      * @return array|null
0961      */
0962     public function getMessages()
0963     {
0964         return $this->messages;
0965     }
0966 
0967     /**
0968      * @param int $member_id
0969      *
0970      * @return array|bool
0971      * @throws Default_Model_Ocs_Exception
0972      * @throws Zend_Exception
0973      */
0974     public function createUser($member_id)
0975     {
0976         if (empty($member_id)) {
0977             return false;
0978         }
0979 
0980         $member_data = $this->getMemberData($member_id);
0981         $data = $this->mapUserData($member_data);
0982 
0983         $userId = $this->getUser($data['extern_uid'], $data['username']);
0984 
0985         if (false === $userId) {
0986 
0987             try {
0988                 $data[0]['skip_confirmation'] = 'true';
0989                 $user = $this->httpUserCreate($data[0]);
0990                 $this->messages[] = "created : " . json_encode($user);
0991                 $data[1]['skip_reconfirmation'] = 'true';
0992                 $updatedUser = $this->httpUserUpdate($data[1], $user['id']);
0993                 $this->messages[] = "updated : " . json_encode($updatedUser);
0994             } catch (Zend_Exception $e) {
0995                 $this->messages[] = "Fail " . $e->getMessage();
0996 
0997                 return false;
0998             }
0999             $this->messages[] = "Success";
1000 
1001             return $data;
1002         }
1003 
1004         $this->messages[0] = 'user already exists.';
1005 
1006         return false;
1007     }
1008 
1009     /**
1010      * @param string $name
1011      *
1012      * @return bool
1013      * @throws Default_Model_Ocs_Exception
1014      * @throws Zend_Http_Client_Exception
1015      * @throws Zend_Uri_Exception
1016      */
1017     public function groupExists($name)
1018     {
1019         $uri = $this->config->host . '/api/v4/groups?search=' . $name;
1020         $this->httpClient->resetParameters();
1021         $this->httpClient->setUri($uri);
1022         $this->httpClient->setHeaders('Private-Token', $this->config->private_token);
1023         $this->httpClient->setHeaders('Sudo', $this->config->user_sudo);
1024         $this->httpClient->setHeaders('User-Agent', $this->config->user_agent);
1025         $this->httpClient->setMethod(Zend_Http_Client::GET);
1026 
1027         $response = $this->httpClient->request();
1028 
1029         try {
1030             $body = Zend_Json::decode($response->getRawBody());
1031         } catch (Zend_Json_Exception $e) {
1032             throw new Default_Model_Ocs_Exception($e, 0, $e);
1033         } catch (Zend_Http_Client_Exception $e) {
1034             // Gitlab send empty response when group not found, this cause an Exception in http client
1035             // we cannot distinguish between a real error and a successful empty response
1036             // so we catch this exception and log only
1037             // TODO: maybe use plain curl request
1038             error_log($e->getMessage());
1039         }
1040 
1041         if (count($body) > 0) {
1042             return true;
1043         }
1044 
1045         if (array_key_exists("message", $body)) {
1046             $result_code = substr(trim($body["message"]), 0, 3);
1047             if ((int)$result_code >= 300) {
1048                 throw new Default_Model_Ocs_Exception($body["message"]);
1049             }
1050         }
1051 
1052         if (array_key_exists("error_description", $body)) {
1053             throw new Default_Model_Ocs_Exception($body["error_description"]);
1054         }
1055 
1056         return false;
1057     }
1058 
1059     /**
1060      * @param $member_id
1061      *
1062      * @return bool
1063      * @throws Default_Model_Ocs_Exception
1064      * @throws Zend_Exception
1065      * @throws Zend_Http_Client_Exception
1066      * @throws Zend_Http_Exception
1067      */
1068     public function updateMail($member_id)
1069     {
1070         if (empty($member_id)) {
1071             throw new Default_Model_Ocs_Exception('given member_id is empty');
1072         }
1073 
1074         $member_data = $this->getMemberData($member_id, false);
1075         $entry = $this->getUser($member_data['external_id'], $member_data['username']);
1076 
1077         if (false === $entry) {
1078             $this->messages[] = "Failed. User not found;";
1079 
1080             return false;
1081         }
1082 
1083         $entry['skip_reconfirmation'] = 'true';
1084         $entry['email'] = $member_data['email_address'];
1085         unset($entry['password']);
1086         $this->httpUserUpdate($entry, $entry['id']);
1087         $this->messages[] = "Success";
1088 
1089         return true;
1090     }
1091 
1092     /**
1093      * @return array|mixed
1094      * @throws Default_Model_Ocs_Exception
1095      * @throws Zend_Http_Client_Exception
1096      * @throws Zend_Json_Exception
1097      * @throws Zend_Uri_Exception
1098      */
1099     public function getUsers()
1100     {
1101         $uri = $this->config->host . "/api/v4/users";
1102         $this->httpClient->resetParameters();
1103         $this->httpClient->setUri($uri);
1104         $this->httpClient->setHeaders('Private-Token', $this->config->private_token);
1105         $this->httpClient->setHeaders('Sudo', $this->config->user_sudo);
1106         $this->httpClient->setHeaders('User-Agent', $this->config->user_agent);
1107         $this->httpClient->setMethod(Zend_Http_Client::GET);
1108 
1109         $response = $this->httpClient->request();
1110 
1111         $body = Zend_Json::decode($response->getRawBody());
1112 
1113         if (count($body) == 0) {
1114             return array();
1115         }
1116 
1117         if (array_key_exists("message", $body)) {
1118             $result_code = substr(trim($body["message"]), 0, 3);
1119             if ((int)$result_code >= 300) {
1120                 throw new Default_Model_Ocs_Exception($body["message"]);
1121             }
1122         }
1123 
1124         return $body;
1125     }
1126 
1127     /**
1128      * @param int $id
1129      *
1130      * @return array|mixed
1131      * @throws Default_Model_Ocs_Exception
1132      * @throws Zend_Http_Client_Exception
1133      * @throws Zend_Json_Exception
1134      * @throws Zend_Uri_Exception
1135      */
1136     public function getUserWithId($id)
1137     {
1138         $uri = $this->config->host . "/api/v4/users/" . $id;
1139         $this->httpClient->resetParameters();
1140         $this->httpClient->setUri($uri);
1141         $this->httpClient->setHeaders('Private-Token', $this->config->private_token);
1142         $this->httpClient->setHeaders('Sudo', $this->config->user_sudo);
1143         $this->httpClient->setHeaders('User-Agent', $this->config->user_agent);
1144         $this->httpClient->setMethod(Zend_Http_Client::GET);
1145 
1146         $response = $this->httpClient->request();
1147 
1148         $body = Zend_Json::decode($response->getRawBody());
1149 
1150         if (count($body) == 0) {
1151             return array();
1152         }
1153 
1154         if (array_key_exists("message", $body)) {
1155             $result_code = substr(trim($body["message"]), 0, 3);
1156             if ((int)$result_code >= 300) {
1157                 throw new Default_Model_Ocs_Exception($body["message"]);
1158             }
1159         }
1160 
1161         return $body;
1162     }
1163 
1164     /**
1165      * @param int    $page
1166      * @param int    $limit
1167      * @param string $order_by
1168      * @param string $sort
1169      *
1170      * @return array|false|mixed
1171      * @throws Zend_Http_Client_Exception
1172      * @throws Zend_Uri_Exception
1173      */
1174     public function getProjects($page = 1, $limit = 5, $order_by = 'created_at', $sort = 'desc')
1175     {
1176         $cache = $this->cache;
1177         $cacheName = __FUNCTION__;
1178         if (!($body = $cache->load($cacheName))) {
1179             $this->httpClient->resetParameters();
1180             $uri =
1181                 $this->config->host . '/api/v4/projects?order_by=' . $order_by . '&sort=' . $sort . '&visibility=public&page=' . $page
1182                 . '&per_page=' . $limit;
1183             $this->httpClient->setUri($uri);
1184             $this->httpClient->setHeaders('Private-Token', $this->config->private_token);
1185             $this->httpClient->setHeaders('Sudo', $this->config->user_sudo);
1186             $this->httpClient->setHeaders('User-Agent', $this->config->user_agent);
1187             $this->httpClient->setMethod(Zend_Http_Client::GET);
1188 
1189             try {
1190                 $response = $this->httpClient->request();
1191 
1192                 $body = Zend_Json::decode($response->getRawBody());
1193 
1194                 if (count($body) == 0) {
1195                     return array();
1196                 }
1197 
1198                 if (array_key_exists("message", $body)) {
1199                     $result_code = substr(trim($body["message"]), 0, 3);
1200                     if ((int)$result_code >= 300) {
1201                         throw new Default_Model_Ocs_Exception($body["message"]);
1202                     }
1203                 }
1204 
1205                 //fetch also user data
1206                 $returnArray = array();
1207                 foreach ($body as $git_project) {
1208                     $gituser = $this->getUserWithName($git_project['namespace']['name']);
1209                     $git_project['namespace']['avatar_url'] = $gituser['avatar_url'];
1210                     $returnArray[] = $git_project;
1211                 }
1212                 $body = $returnArray;
1213             } catch (Exception $exc) {
1214                 return array();
1215             }
1216         }
1217 
1218         return $body;
1219     }
1220 
1221     /**
1222      * @param int $id
1223      *
1224      * @return mixed|null
1225      * @throws Default_Model_Ocs_Exception
1226      * @throws Zend_Http_Client_Exception
1227      * @throws Zend_Json_Exception
1228      * @throws Zend_Uri_Exception
1229      */
1230     public function getProject($id)
1231     {
1232         $uri = $this->config->host . "/api/v4/projects/" . $id . "/";
1233         $this->httpClient->resetParameters();
1234         $this->httpClient->setUri($uri);
1235         $this->httpClient->setHeaders('Private-Token', $this->config->private_token);
1236         $this->httpClient->setHeaders('Sudo', $this->config->user_sudo);
1237         $this->httpClient->setHeaders('User-Agent', $this->config->user_agent);
1238         $this->httpClient->setMethod(Zend_Http_Client::GET);
1239 
1240         $response = $this->httpClient->request();
1241 
1242         $body = Zend_Json::decode($response->getRawBody());
1243 
1244         if ($body['visibility'] <> 'public') {
1245             throw new Default_Model_Ocs_Exception('Project not found in gitlab');
1246         }
1247 
1248         if (count($body) == 0) {
1249             return null;
1250         }
1251 
1252         if (array_key_exists("message", $body)) {
1253             $result_code = substr(trim($body["message"]), 0, 3);
1254             if ((int)$result_code >= 300) {
1255                 throw new Default_Model_Ocs_Exception($body["message"]);
1256             }
1257         }
1258 
1259         return $body;
1260     }
1261 
1262     /**
1263      * @param int    $id
1264      * @param string $state
1265      * @param int    $page
1266      * @param int    $limit
1267      *
1268      * @return array|mixed
1269      * @throws Default_Model_Ocs_Exception
1270      * @throws Zend_Http_Client_Exception
1271      * @throws Zend_Json_Exception
1272      * @throws Zend_Uri_Exception
1273      */
1274     public function getProjectIssues($id, $state = 'opened', $page = 1, $limit = 5)
1275     {
1276         $uri = $this->config->host . '/api/v4/projects/' . $id . '/issues?state=' . $state . '&page=' . $page . '&per_page=' . $limit;
1277         $this->httpClient->resetParameters();
1278         $this->httpClient->setUri($uri);
1279         $this->httpClient->setHeaders('Private-Token', $this->config->private_token);
1280         $this->httpClient->setHeaders('Sudo', $this->config->user_sudo);
1281         $this->httpClient->setHeaders('User-Agent', $this->config->user_agent);
1282         $this->httpClient->setMethod(Zend_Http_Client::GET);
1283 
1284         $response = $this->httpClient->request();
1285 
1286         $body = Zend_Json::decode($response->getRawBody());
1287 
1288         if (count($body) == 0) {
1289             return array();
1290         }
1291 
1292         if (array_key_exists("message", $body)) {
1293             $result_code = substr(trim($body["message"]), 0, 3);
1294             if ((int)$result_code >= 300) {
1295                 throw new Default_Model_Ocs_Exception($body["message"]);
1296             }
1297         }
1298 
1299         return $body;
1300     }
1301 
1302     /**
1303      * @param int $user_id
1304      * @param int $page
1305      * @param int $limit
1306      *
1307      * @return array|mixed
1308      * @throws Default_Model_Ocs_Exception
1309      * @throws Zend_Http_Client_Exception
1310      * @throws Zend_Json_Exception
1311      * @throws Zend_Uri_Exception
1312      */
1313     public function getUserProjects($user_id, $page = 1, $limit = 50)
1314     {
1315         $uri = $this->config->host . '/api/v4/users/' . $user_id . '/projects?visibility=public&page=' . $page . '&per_page=' . $limit;
1316         $this->httpClient->resetParameters();
1317         $this->httpClient->setUri($uri);
1318         $this->httpClient->setHeaders('Private-Token', $this->config->private_token);
1319         $this->httpClient->setHeaders('Sudo', $this->config->user_sudo);
1320         $this->httpClient->setHeaders('User-Agent', $this->config->user_agent);
1321         $this->httpClient->setMethod(Zend_Http_Client::GET);
1322         $response = null;
1323         try {
1324             $response = $this->httpClient->request();
1325 
1326         } catch (Exception $ex) {
1327             $response = null;
1328         }
1329 
1330         if ($response && !empty($response)) {
1331 
1332             $body = Zend_Json::decode($response->getRawBody());
1333 
1334             if (count($body) == 0) {
1335                 return array();
1336             }
1337 
1338             if (array_key_exists("message", $body)) {
1339                 $result_code = substr(trim($body["message"]), 0, 3);
1340                 if ((int)$result_code >= 300) {
1341                     throw new Default_Model_Ocs_Exception($body["message"]);
1342                 }
1343             }
1344 
1345             return $body;
1346         }
1347 
1348         return null;
1349     }
1350 
1351 }