From e9749ff172e6fab7ff9845e375cffd9ef913db38 Mon Sep 17 00:00:00 2001 From: Oleg Kosarev Date: Thu, 17 Aug 2023 18:27:40 -0700 Subject: [PATCH 1/3] Fix Auth Bitrix24 * Fix Inccorect Login or Password + Add Bitrix24AuthorizationReturn Return all Error User. Remove All Exception return ['error' => true|false "message" => "error description"] --- src/bitrix24Authorization.php | 28 ++- src/bitrix24AuthorizationReturn.php | 323 ++++++++++++++++++++++++++++ 2 files changed, 341 insertions(+), 10 deletions(-) create mode 100644 src/bitrix24AuthorizationReturn.php diff --git a/src/bitrix24Authorization.php b/src/bitrix24Authorization.php index 5fa1599..0a6e4c2 100644 --- a/src/bitrix24Authorization.php +++ b/src/bitrix24Authorization.php @@ -1,5 +1,6 @@ exec(); $b24_login_check_data = json_decode($b24_auth_response['content'], true); if (!is_array($b24_login_check_data) || !array_key_exists('status', $b24_login_check_data) || $b24_login_check_data['status'] != 'success') { - throw new \Exception('Login and Password check fails at Bitrix24 portal!'); + throw new \Exception('Login check fails at Bitrix24 portal!'); } // Авторизуемся на портале Bitrix24 по проверенным данным... @@ -62,6 +63,12 @@ private function authorize() ->setCookies($b24_auth_cookies) ->exec(); + if ( + !array_key_exists('X-User-Id', $b24_auth_response) + ) { + throw new \Exception('Password check fails at Bitrix24 portal!'); + } + // Dыдергиваем js-redirect из body, который редиректит нас на портал компании $b24_js_domain_backurl = $this->getRespondUrlFromCurl($b24_auth_response['content']); @@ -109,7 +116,7 @@ private function authorize() */ private function getRespondUrlFromCurl($curl_response) { - if(!preg_match('~window\.location(\.href)?[\s\=]{1,3}\'(.+?)\'~m', $curl_response, $result)) { + if (!preg_match('~window\.location(\.href)?[\s\=]{1,3}\'(.+?)\'~m', $curl_response, $result)) { throw new \Exception("THERE IS NO ~bitrix24 chain URL~ IN CURL ANSWER...
\r\nINPUT CURL BODY:
\r\n{$curl_response}"); } @@ -123,7 +130,7 @@ private function getRespondUrlFromCurl($curl_response) */ public function is_authorize() { - if(!empty($this->bitrix24_access) && $this->bitrix24_access['expires'] > time()) + if (!empty($this->bitrix24_access) && $this->bitrix24_access['expires'] > time()) return true; return false; @@ -134,7 +141,7 @@ public function is_authorize() * @return bool * @throws \Exception */ - private function checkAuthorizationVars () + private function checkAuthorizationVars() { $error = ''; $error .= empty($this->app_scope) ? "\r\napp_scope with 'setApplicationScope' method
" : ''; @@ -144,7 +151,8 @@ private function checkAuthorizationVars () $error .= empty($this->bitrix24_login) ? "\r\nbitrix24_login with 'setBitrix24Login' method
" : ''; $error .= empty($this->bitrix24_password) ? "\r\nbitrix24_password with 'setBitrix24Password' method
" : ''; - if(!empty($error)) throw new \Exception('You need to set this variables to get authorization data:
' . $error); + if (!empty($error)) + throw new \Exception('You need to set this variables to get authorization data:
' . $error); return true; } @@ -162,14 +170,14 @@ public function initialize(\Bitrix24\Bitrix24 $B24App = null) } - if(!$this->is_authorize()) + if (!$this->is_authorize()) try { $this->authorize(); } catch (\Exception $error) { die($error->getMessage()); } - if(is_object($B24App)) { + if (is_object($B24App)) { $B24App->setApplicationScope(array($this->app_scope)); $B24App->setApplicationId($this->app_id); $B24App->setApplicationSecret($this->app_secret); @@ -242,7 +250,7 @@ public function setBitrix24Password($bitrix24_user_password) */ public function __get($name) { - if(isset($this->{$name})) + if (isset($this->{$name})) return $this->{$name}; } @@ -254,7 +262,7 @@ public function __get($name) */ private function getBitrixSessionIdFromCurl($curl_response) { - if(!preg_match('~\'bitrix_sessid\':\'([\d\w]+)\'~', $curl_response, $result)) { + if (!preg_match('~\'bitrix_sessid\':\'([\d\w]+)\'~', $curl_response, $result)) { throw new \Exception("THERE IS NO ~bitrix_sessid~ IN CURL ANSWER...
\r\nINPUT CURL BODY:
\r\n{$curl_response}"); } @@ -270,7 +278,7 @@ private function getBitrixSessionIdFromCurl($curl_response) */ private function getBitrixAuthCodeFromCurl($curl_response) { - if(!preg_match('~code=([^\&]+)~', $curl_response, $b24_auth_code)) + if (!preg_match('~code=([^\&]+)~', $curl_response, $b24_auth_code)) throw new \Exception("NO PARAMETER ~CODE~ IN BITRIX24 ANSWER: ...
\r\nINPUT CURL BODY:
\r\n{$curl_response}"); $b24_auth_code = $b24_auth_code[1]; diff --git a/src/bitrix24AuthorizationReturn.php b/src/bitrix24AuthorizationReturn.php new file mode 100644 index 0000000..be3f3f5 --- /dev/null +++ b/src/bitrix24AuthorizationReturn.php @@ -0,0 +1,323 @@ +bitrix24_domain . '/oauth/authorize/') + ->follow(false) + ->setGetFields([ + 'client_id' => $this->app_id + ]) + ->exec(); + $b24_domain_cookies = $b24_auth_response['cookies']; + $b24_location_target = $b24_auth_response['headers']['Location']; + + $b24_auth_response = CurlHelper::factory($b24_location_target) + ->exec(); + $b24_auth_sessid = $this->getBitrixSessionIdFromCurl($b24_auth_response['content']); + $b24_auth_cookies = $b24_auth_response['cookies']; + + // Имитируем проверку логина и пароля + $b24_login_post_data = [ + 'SITE_ID' => 's1', + 'sessid' => $b24_auth_sessid['bitrix_session_id'], + 'login' => $this->bitrix24_login, + 'password' => $this->bitrix24_password, + 'remember' => '1' + ]; + + + $b24_auth_response = CurlHelper::factory('https://auth2.bitrix24.net/bitrix/services/main/ajax.php?action=b24network.authorize.checkLogin') + ->setPostFields($b24_login_post_data) + ->setCookies($b24_auth_cookies) + ->exec(); + + $b24_login_check_data = json_decode($b24_auth_response['content'], true); + + if (!is_array($b24_login_check_data) || !array_key_exists('status', $b24_login_check_data) || $b24_login_check_data['status'] != 'success') { + throw new \Exception('Login check fails at Bitrix24 portal!'); + } + + // Авторизуемся на портале Bitrix24 по проверенным данным... + $b24_auth_response = CurlHelper::factory('https://auth2.bitrix24.net/bitrix/services/main/ajax.php?action=b24network.authorize.check') + ->setPostFields($b24_login_post_data) + ->setCookies($b24_auth_cookies) + ->exec(); + + $b24_auth_cookies = array_merge($b24_auth_cookies, $b24_auth_response['cookies']); + + // Переходим по ссылке авторизации с новыми cookies + $b24_auth_response = CurlHelper::factory($b24_location_target) + ->setCookies($b24_auth_cookies) + ->exec(); + + if ( + !array_key_exists('X-User-Id', $b24_auth_response) + ) { + return [ + 'error' => true, + 'error_message' => 'Password check fails at Bitrix24 portal!', + ]; + } + + // Dыдергиваем js-redirect из body, который редиректит нас на портал компании + $b24_js_domain_backurl = $this->getRespondUrlFromCurl($b24_auth_response['content']); + if ($b24_js_domain_backurl["error"] == true) { + return $b24_js_domain_backurl; + } + // Переходим на свой портал компании и получаем ссылку-редирект для авторизации на портале компании + $b24_auth_response = CurlHelper::factory($b24_js_domain_backurl['bitrix_respond_url']) + ->setCookies($b24_domain_cookies) + ->exec(); + $b24_domain_cookies = array_merge($b24_domain_cookies, $b24_auth_response['cookies']); + + // Собираем ссылку аторизации на своём портале компании + $b24_domain_backurl_uri = $this->getRespondUrlFromCurl($b24_auth_response['content']); + $b24_js_domain_backurl = 'https://' . $this->bitrix24_domain . $b24_domain_backurl_uri['bitrix_respond_url']; + + // Переходим по ссылке своего портала для получения параметра CODE + $b24_auth_response = CurlHelper::factory($b24_js_domain_backurl) + ->setCookies($b24_domain_cookies) + ->follow(false) + ->exec(); + $b24_auth_code = $this->getBitrixAuthCodeFromCurl($b24_auth_response['headers']['Location']); + if ($b24_auth_code["error"] == true) { + return $b24_auth_code; + + } + // По полученному CODE формируем запрос для получения ACCESS TOKEN`а + $get = [ + 'grant_type' => 'authorization_code', + 'client_id' => $this->app_id, + 'client_secret' => $this->app_secret, + 'code' => $b24_auth_code['code'], + 'scope' => $this->app_scope + ]; + + $b24_auth_response = CurlHelper::factory('https://' . $this->bitrix24_domain . '/oauth/token/') + ->setGetFields($get) + ->setCookies($b24_auth_cookies) + ->exec(); + + $this->bitrix24_access = $b24_auth_response['data']; + $this->bitrix24_access['error'] = false; + + return $this->bitrix24_access; + + } + + /** + * Method which returns bitrix24 chain URL from cURL response + * @param $curl_response + * @return array + * @throws \Exception + */ + private function getRespondUrlFromCurl($curl_response) + { + if (!preg_match('~window\.location(\.href)?[\s\=]{1,3}\'(.+?)\'~m', $curl_response, $result)) { + return [ + 'error' => true, + 'error_message' => 'No ~bitrix24 chain URL~ in CURL ANSWER...' + ]; + } + + $bitrix_respond_url = trim($result[2]); + return [ + 'error' => false, + 'bitrix_respond_url' => $bitrix_respond_url + ]; + } + + /** + * Method which checks, is bitrix24 access token still valid + * @return bool + */ + public function is_authorize() + { + if (!empty($this->bitrix24_access) && $this->bitrix24_access['expires'] > time()) { + return true; + } + + return false; + } + + /** + * Method which checks, is required variables has been defined for further valid script work + * @return bool + * @throws \Exception + */ + private function checkAuthorizationVars() + { + $error = ''; + $error .= empty($this->app_scope) ? "\r\napp_scope with 'setApplicationScope' method
" : ''; + $error .= empty($this->app_id) ? "\r\napp_id with 'setApplicationId' method
" : ''; + $error .= empty($this->app_secret) ? "\r\napp_secret with 'setApplicationSecret' method
" : ''; + $error .= empty($this->bitrix24_domain) ? "\r\nbitrix24_domain with 'setBitrix24Domain' method
" : ''; + $error .= empty($this->bitrix24_login) ? "\r\nbitrix24_login with 'setBitrix24Login' method
" : ''; + $error .= empty($this->bitrix24_password) ? "\r\nbitrix24_password with 'setBitrix24Password' method
" : ''; + + if (!empty($error)) + throw new \Exception('You need to set this variables to get authorization data:
' . $error); + return true; + } + + /** + * Method which returns bitrix24 authorization data or authorized Bitrix24 object if using mesilov/bitrix24-php-sdk + * @param Bitrix24|null $B24App + * @return Bitrix24|object|array + */ + public function initialize(\Bitrix24\Bitrix24 $B24App = null) + { + try { + $this->checkAuthorizationVars(); + } catch (\Exception $error) { + die($error->getMessage()); + } + + + if (!$this->is_authorize()) { + $authorize = $this->authorize(); + } + if ($authorize["error"] == true) { + + return $authorize; + } + if (is_object($B24App) && $authorize["error"] == false) { + $B24App->setApplicationScope(array($this->app_scope)); + $B24App->setApplicationId($this->app_id); + $B24App->setApplicationSecret($this->app_secret); + $B24App->setDomain($this->bitrix24_domain); + $B24App->setMemberId($this->bitrix24_access['member_id']); + $B24App->setAccessToken($this->bitrix24_access['access_token']); + $B24App->setRefreshToken($this->bitrix24_access['refresh_token']); + + return $B24App; + } + + return $this->bitrix24_access; + } + + /** + * @param $application_scope + */ + public function setApplicationScope($application_scope) + { + $application_scope = str_replace(' ', '', $application_scope); + $this->app_scope = $application_scope; + } + + /** + * @param $application_id + */ + public function setApplicationId($application_id) + { + $this->app_id = $application_id; + } + + /** + * @param $application_secret + */ + public function setApplicationSecret($application_secret) + { + $this->app_secret = $application_secret; + } + + /** + * @param $bitrix24_domain + */ + public function setBitrix24Domain($bitrix24_domain) + { + $bitrix24_domain = preg_replace('~https?:\/\/([w]{3})?~', '', $bitrix24_domain); + + $this->bitrix24_domain = $bitrix24_domain; + } + + /** + * @param $bitrix24_user_login + */ + public function setBitrix24Login($bitrix24_user_login) + { + $this->bitrix24_login = $bitrix24_user_login; + } + + /** + * @param $bitrix24_user_password + */ + public function setBitrix24Password($bitrix24_user_password) + { + $this->bitrix24_password = $bitrix24_user_password; + } + + /** + * Method which returns private properties if user wants to use them directly + * @param $name + * @return mixed + */ + public function __get($name) + { + if (isset($this->{$name})) + return $this->{$name}; + } + + /** + * Method which returns bitrix24 SessionId from cURL response + * @param $curl_response + * @return array + * @throws \Exception + */ + private function getBitrixSessionIdFromCurl($curl_response) + { + if (!preg_match('~\'bitrix_sessid\':\'([\d\w]+)\'~', $curl_response, $result)) { + return [ + "error" => true, + "error_message" => "NO ~bitrix_sessid~ IN CURL ANSWER" + ]; + // throw new \Exception("THERE IS NO ~bitrix_sessid~ IN CURL ANSWER...
\r\nINPUT CURL BODY:
\r\n{$curl_response}"); + } + + $bitrix_session_id = trim($result[1]); + return [ + "error" => false, + "bitrix_session_id" => $bitrix_session_id + ]; + } + + /** + * Method which returns bitrix24 CODE parameter from cURL response + * @param $curl_response + * @return array + * @throws \Exception + */ + private function getBitrixAuthCodeFromCurl($curl_response) + { + if (!preg_match('~code=([^\&]+)~', $curl_response, $b24_auth_code)) { + return [ + "error" => true, + "error_message" => "NO PARAMETER ~CODE~ IN CURL ANSWER" + ]; + } + + $b24_auth_code = $b24_auth_code[1]; + return [ + "error" => false, + "code" => $b24_auth_code + ]; + } +} \ No newline at end of file From e5f3b1c1b7010b166f750394c8f4f70053edd5d5 Mon Sep 17 00:00:00 2001 From: Oleg Kosarev Date: Thu, 17 Aug 2023 18:29:10 -0700 Subject: [PATCH 2/3] Update composer.json --- composer.json | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 86df00f..324de93 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,12 @@ { "name": "ujy/bitrix24_api_authorization", "description": "Authorization class to easy get Bitrix24 Access Tokens for use in API", - "keywords": ["Bitrix24", "Access", "API", "Token"], + "keywords": [ + "Bitrix24", + "Access", + "API", + "Token" + ], "type": "library", "homepage": "https://github.com/xUJYx/bitrix24_api_authorization", "license": "MIT", @@ -15,12 +20,19 @@ "name": "Oleg Pravdin", "email": "opravdin@gmail.com", "role": "Developer" + }, + { + "name": "Oleg Kosarev", + "email": "dev.olegkosarev@outlook.com", + "role": "Developer" } ], "autoload": { - "classmap": ["src/"] + "classmap": [ + "src/" + ] }, "require": { - "mervick/curl-helper": "^1.1" + "mervick/curl-helper": "^1.2" } -} +} \ No newline at end of file From 86ce1522d44a1c56eab00abaf0f73593dca5bd65 Mon Sep 17 00:00:00 2001 From: Oleg Kosarev <109492069+DevOlegKosarev@users.noreply.github.com> Date: Thu, 17 Aug 2023 18:49:07 -0700 Subject: [PATCH 3/3] Update composer.json --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 324de93..6a7d041 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,7 @@ { "name": "ujy/bitrix24_api_authorization", "description": "Authorization class to easy get Bitrix24 Access Tokens for use in API", + "version": "0.1.2", "keywords": [ "Bitrix24", "Access", @@ -35,4 +36,4 @@ "require": { "mervick/curl-helper": "^1.2" } -} \ No newline at end of file +}