Passed
Push — master ( bd5724...8a312b )
by
unknown
01:47
created
src/User/Activity.php 1 patch
Indentation   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -14,60 +14,60 @@
 block discarded – undo
14 14
  */
15 15
 final class Activity
16 16
 {
17
-    /**
18
-     * activity id on the provider side, usually given as integer
19
-     *
20
-     * @var string
21
-     */
22
-    public $id = null;
17
+	/**
18
+	 * activity id on the provider side, usually given as integer
19
+	 *
20
+	 * @var string
21
+	 */
22
+	public $id = null;
23 23
 
24
-    /**
25
-     * activity date of creation
26
-     *
27
-     * @var string
28
-     */
29
-    public $date = null;
24
+	/**
25
+	 * activity date of creation
26
+	 *
27
+	 * @var string
28
+	 */
29
+	public $date = null;
30 30
 
31
-    /**
32
-     * activity content as a string
33
-     *
34
-     * @var string
35
-     */
36
-    public $text = null;
31
+	/**
32
+	 * activity content as a string
33
+	 *
34
+	 * @var string
35
+	 */
36
+	public $text = null;
37 37
 
38
-    /**
39
-     * user who created the activity
40
-     *
41
-     * @var object
42
-     */
43
-    public $user = null;
38
+	/**
39
+	 * user who created the activity
40
+	 *
41
+	 * @var object
42
+	 */
43
+	public $user = null;
44 44
 
45
-    /**
46
-     *
47
-     */
48
-    public function __construct()
49
-    {
50
-        $this->user = new \stdClass();
45
+	/**
46
+	 *
47
+	 */
48
+	public function __construct()
49
+	{
50
+		$this->user = new \stdClass();
51 51
 
52
-        // typically, we should have a few information about the user who created the event from social apis
53
-        $this->user->identifier = null;
54
-        $this->user->displayName = null;
55
-        $this->user->profileURL = null;
56
-        $this->user->photoURL = null;
57
-    }
52
+		// typically, we should have a few information about the user who created the event from social apis
53
+		$this->user->identifier = null;
54
+		$this->user->displayName = null;
55
+		$this->user->profileURL = null;
56
+		$this->user->photoURL = null;
57
+	}
58 58
 
59
-    /**
60
-     * Prevent the providers adapters from adding new fields.
61
-     *
62
-     * @throws UnexpectedValueException
63
-     * @var string $name
64
-     *
65
-     * @var mixed $value
66
-     *
67
-     */
68
-    public function __set($name, $value)
69
-    {
70
-        // phpcs:ignore
71
-        throw new UnexpectedValueException(sprintf('Adding new property "%s\' to %s is not allowed.', $name, __CLASS__));
72
-    }
59
+	/**
60
+	 * Prevent the providers adapters from adding new fields.
61
+	 *
62
+	 * @throws UnexpectedValueException
63
+	 * @var string $name
64
+	 *
65
+	 * @var mixed $value
66
+	 *
67
+	 */
68
+	public function __set($name, $value)
69
+	{
70
+		// phpcs:ignore
71
+		throw new UnexpectedValueException(sprintf('Adding new property "%s\' to %s is not allowed.', $name, __CLASS__));
72
+	}
73 73
 }
Please login to merge, or discard this patch.
src/User/Contact.php 1 patch
Indentation   +54 added lines, -54 removed lines patch added patch discarded remove patch
@@ -14,65 +14,65 @@
 block discarded – undo
14 14
  */
15 15
 final class Contact
16 16
 {
17
-    /**
18
-     * The Unique contact user ID
19
-     *
20
-     * @var string
21
-     */
22
-    public $identifier = null;
17
+	/**
18
+	 * The Unique contact user ID
19
+	 *
20
+	 * @var string
21
+	 */
22
+	public $identifier = null;
23 23
 
24
-    /**
25
-     * User website, blog, web page
26
-     *
27
-     * @var string
28
-     */
29
-    public $webSiteURL = null;
24
+	/**
25
+	 * User website, blog, web page
26
+	 *
27
+	 * @var string
28
+	 */
29
+	public $webSiteURL = null;
30 30
 
31
-    /**
32
-     * URL link to profile page on the IDp web site
33
-     *
34
-     * @var string
35
-     */
36
-    public $profileURL = null;
31
+	/**
32
+	 * URL link to profile page on the IDp web site
33
+	 *
34
+	 * @var string
35
+	 */
36
+	public $profileURL = null;
37 37
 
38
-    /**
39
-     * URL link to user photo or avatar
40
-     *
41
-     * @var string
42
-     */
43
-    public $photoURL = null;
38
+	/**
39
+	 * URL link to user photo or avatar
40
+	 *
41
+	 * @var string
42
+	 */
43
+	public $photoURL = null;
44 44
 
45
-    /**
46
-     * User displayName provided by the IDp or a concatenation of first and last name
47
-     *
48
-     * @var string
49
-     */
50
-    public $displayName = null;
45
+	/**
46
+	 * User displayName provided by the IDp or a concatenation of first and last name
47
+	 *
48
+	 * @var string
49
+	 */
50
+	public $displayName = null;
51 51
 
52
-    /**
53
-     * A short about_me
54
-     *
55
-     * @var string
56
-     */
57
-    public $description = null;
52
+	/**
53
+	 * A short about_me
54
+	 *
55
+	 * @var string
56
+	 */
57
+	public $description = null;
58 58
 
59
-    /**
60
-     * User email. Not all of IDp grant access to the user email
61
-     *
62
-     * @var string
63
-     */
64
-    public $email = null;
59
+	/**
60
+	 * User email. Not all of IDp grant access to the user email
61
+	 *
62
+	 * @var string
63
+	 */
64
+	public $email = null;
65 65
 
66
-    /**
67
-     * Prevent the providers adapters from adding new fields.
68
-     *
69
-     * @param string $name
70
-     * @param mixed $value
71
-     *
72
-     * @throws UnexpectedValueException
73
-     */
74
-    public function __set($name, $value)
75
-    {
76
-        throw new UnexpectedValueException(sprintf('Adding new property "%s" to %s is not allowed.', $name, __CLASS__));
77
-    }
66
+	/**
67
+	 * Prevent the providers adapters from adding new fields.
68
+	 *
69
+	 * @param string $name
70
+	 * @param mixed $value
71
+	 *
72
+	 * @throws UnexpectedValueException
73
+	 */
74
+	public function __set($name, $value)
75
+	{
76
+		throw new UnexpectedValueException(sprintf('Adding new property "%s" to %s is not allowed.', $name, __CLASS__));
77
+	}
78 78
 }
Please login to merge, or discard this patch.
src/Storage/Session.php 1 patch
Indentation   +113 added lines, -113 removed lines patch added patch discarded remove patch
@@ -14,117 +14,117 @@
 block discarded – undo
14 14
  */
15 15
 class Session implements StorageInterface
16 16
 {
17
-    /**
18
-     * Namespace
19
-     *
20
-     * @var string
21
-     */
22
-    protected $storeNamespace = 'HYBRIDAUTH::STORAGE';
23
-
24
-    /**
25
-     * Key prefix
26
-     *
27
-     * @var string
28
-     */
29
-    protected $keyPrefix = '';
30
-
31
-    /**
32
-     * Initiate a new session
33
-     *
34
-     * @throws RuntimeException
35
-     */
36
-    public function __construct()
37
-    {
38
-        if (session_id()) {
39
-            return;
40
-        }
41
-
42
-        if (headers_sent()) {
43
-            // phpcs:ignore
44
-            throw new RuntimeException('HTTP headers already sent to browser and Hybridauth won\'t be able to start/resume PHP session. To resolve this, session_start() must be called before outputing any data.');
45
-        }
46
-
47
-        if (!session_start()) {
48
-            throw new RuntimeException('PHP session failed to start.');
49
-        }
50
-    }
51
-
52
-    /**
53
-     * {@inheritdoc}
54
-     */
55
-    public function get($key)
56
-    {
57
-        $key = $this->keyPrefix . strtolower($key);
58
-
59
-        if (isset($_SESSION[$this->storeNamespace], $_SESSION[$this->storeNamespace][$key])) {
60
-            $value = $_SESSION[$this->storeNamespace][$key];
61
-
62
-            if (is_array($value) && array_key_exists('lateObject', $value)) {
63
-                $value = unserialize($value['lateObject']);
64
-            }
65
-
66
-            return $value;
67
-        }
68
-
69
-        return null;
70
-    }
71
-
72
-    /**
73
-     * {@inheritdoc}
74
-     */
75
-    public function set($key, $value)
76
-    {
77
-        $key = $this->keyPrefix . strtolower($key);
78
-
79
-        if (is_object($value)) {
80
-            // We encapsulate as our classes may be defined after session is initialized.
81
-            $value = ['lateObject' => serialize($value)];
82
-        }
83
-
84
-        $_SESSION[$this->storeNamespace][$key] = $value;
85
-    }
86
-
87
-    /**
88
-     * {@inheritdoc}
89
-     */
90
-    public function clear()
91
-    {
92
-        $_SESSION[$this->storeNamespace] = [];
93
-    }
94
-
95
-    /**
96
-     * {@inheritdoc}
97
-     */
98
-    public function delete($key)
99
-    {
100
-        $key = $this->keyPrefix . strtolower($key);
101
-
102
-        if (isset($_SESSION[$this->storeNamespace], $_SESSION[$this->storeNamespace][$key])) {
103
-            $tmp = $_SESSION[$this->storeNamespace];
104
-
105
-            unset($tmp[$key]);
106
-
107
-            $_SESSION[$this->storeNamespace] = $tmp;
108
-        }
109
-    }
110
-
111
-    /**
112
-     * {@inheritdoc}
113
-     */
114
-    public function deleteMatch($key)
115
-    {
116
-        $key = $this->keyPrefix . strtolower($key);
117
-
118
-        if (isset($_SESSION[$this->storeNamespace]) && count($_SESSION[$this->storeNamespace])) {
119
-            $tmp = $_SESSION[$this->storeNamespace];
120
-
121
-            foreach ($tmp as $k => $v) {
122
-                if (strstr($k, $key)) {
123
-                    unset($tmp[$k]);
124
-                }
125
-            }
126
-
127
-            $_SESSION[$this->storeNamespace] = $tmp;
128
-        }
129
-    }
17
+	/**
18
+	 * Namespace
19
+	 *
20
+	 * @var string
21
+	 */
22
+	protected $storeNamespace = 'HYBRIDAUTH::STORAGE';
23
+
24
+	/**
25
+	 * Key prefix
26
+	 *
27
+	 * @var string
28
+	 */
29
+	protected $keyPrefix = '';
30
+
31
+	/**
32
+	 * Initiate a new session
33
+	 *
34
+	 * @throws RuntimeException
35
+	 */
36
+	public function __construct()
37
+	{
38
+		if (session_id()) {
39
+			return;
40
+		}
41
+
42
+		if (headers_sent()) {
43
+			// phpcs:ignore
44
+			throw new RuntimeException('HTTP headers already sent to browser and Hybridauth won\'t be able to start/resume PHP session. To resolve this, session_start() must be called before outputing any data.');
45
+		}
46
+
47
+		if (!session_start()) {
48
+			throw new RuntimeException('PHP session failed to start.');
49
+		}
50
+	}
51
+
52
+	/**
53
+	 * {@inheritdoc}
54
+	 */
55
+	public function get($key)
56
+	{
57
+		$key = $this->keyPrefix . strtolower($key);
58
+
59
+		if (isset($_SESSION[$this->storeNamespace], $_SESSION[$this->storeNamespace][$key])) {
60
+			$value = $_SESSION[$this->storeNamespace][$key];
61
+
62
+			if (is_array($value) && array_key_exists('lateObject', $value)) {
63
+				$value = unserialize($value['lateObject']);
64
+			}
65
+
66
+			return $value;
67
+		}
68
+
69
+		return null;
70
+	}
71
+
72
+	/**
73
+	 * {@inheritdoc}
74
+	 */
75
+	public function set($key, $value)
76
+	{
77
+		$key = $this->keyPrefix . strtolower($key);
78
+
79
+		if (is_object($value)) {
80
+			// We encapsulate as our classes may be defined after session is initialized.
81
+			$value = ['lateObject' => serialize($value)];
82
+		}
83
+
84
+		$_SESSION[$this->storeNamespace][$key] = $value;
85
+	}
86
+
87
+	/**
88
+	 * {@inheritdoc}
89
+	 */
90
+	public function clear()
91
+	{
92
+		$_SESSION[$this->storeNamespace] = [];
93
+	}
94
+
95
+	/**
96
+	 * {@inheritdoc}
97
+	 */
98
+	public function delete($key)
99
+	{
100
+		$key = $this->keyPrefix . strtolower($key);
101
+
102
+		if (isset($_SESSION[$this->storeNamespace], $_SESSION[$this->storeNamespace][$key])) {
103
+			$tmp = $_SESSION[$this->storeNamespace];
104
+
105
+			unset($tmp[$key]);
106
+
107
+			$_SESSION[$this->storeNamespace] = $tmp;
108
+		}
109
+	}
110
+
111
+	/**
112
+	 * {@inheritdoc}
113
+	 */
114
+	public function deleteMatch($key)
115
+	{
116
+		$key = $this->keyPrefix . strtolower($key);
117
+
118
+		if (isset($_SESSION[$this->storeNamespace]) && count($_SESSION[$this->storeNamespace])) {
119
+			$tmp = $_SESSION[$this->storeNamespace];
120
+
121
+			foreach ($tmp as $k => $v) {
122
+				if (strstr($k, $key)) {
123
+					unset($tmp[$k]);
124
+				}
125
+			}
126
+
127
+			$_SESSION[$this->storeNamespace] = $tmp;
128
+		}
129
+	}
130 130
 }
Please login to merge, or discard this patch.
src/Provider/Medium.php 1 patch
Indentation   +56 added lines, -56 removed lines patch added patch discarded remove patch
@@ -17,72 +17,72 @@
 block discarded – undo
17 17
  */
18 18
 class Medium extends OAuth2
19 19
 {
20
-    /**
21
-     * {@inheritdoc}
22
-     */
23
-    protected $scope = 'basicProfile';
20
+	/**
21
+	 * {@inheritdoc}
22
+	 */
23
+	protected $scope = 'basicProfile';
24 24
 
25
-    /**
26
-     * {@inheritdoc}
27
-     */
28
-    protected $apiBaseUrl = 'https://api.medium.com/v1/';
25
+	/**
26
+	 * {@inheritdoc}
27
+	 */
28
+	protected $apiBaseUrl = 'https://api.medium.com/v1/';
29 29
 
30
-    /**
31
-     * {@inheritdoc}
32
-     */
33
-    protected $authorizeUrl = 'https://medium.com/m/oauth/authorize';
30
+	/**
31
+	 * {@inheritdoc}
32
+	 */
33
+	protected $authorizeUrl = 'https://medium.com/m/oauth/authorize';
34 34
 
35
-    /**
36
-     * {@inheritdoc}
37
-     */
38
-    protected $accessTokenUrl = 'https://api.medium.com/v1/tokens';
35
+	/**
36
+	 * {@inheritdoc}
37
+	 */
38
+	protected $accessTokenUrl = 'https://api.medium.com/v1/tokens';
39 39
 
40
-    /**
41
-     * {@inheritdoc}
42
-     */
43
-    protected $apiDocumentation = 'https://github.com/Medium/medium-api-docs';
40
+	/**
41
+	 * {@inheritdoc}
42
+	 */
43
+	protected $apiDocumentation = 'https://github.com/Medium/medium-api-docs';
44 44
 
45
-    /**
46
-     * {@inheritdoc}
47
-     */
48
-    protected function initialize()
49
-    {
50
-        parent::initialize();
45
+	/**
46
+	 * {@inheritdoc}
47
+	 */
48
+	protected function initialize()
49
+	{
50
+		parent::initialize();
51 51
 
52
-        if ($this->isRefreshTokenAvailable()) {
53
-            $this->tokenRefreshParameters += [
54
-                'client_id' => $this->clientId,
55
-                'client_secret' => $this->clientSecret,
56
-            ];
57
-        }
58
-    }
52
+		if ($this->isRefreshTokenAvailable()) {
53
+			$this->tokenRefreshParameters += [
54
+				'client_id' => $this->clientId,
55
+				'client_secret' => $this->clientSecret,
56
+			];
57
+		}
58
+	}
59 59
 
60
-    /**
61
-     * {@inheritdoc}
62
-     *
63
-     * See: https://github.com/Medium/medium-api-docs#getting-the-authenticated-users-details
64
-     */
65
-    public function getUserProfile()
66
-    {
67
-        $response = $this->apiRequest('me');
60
+	/**
61
+	 * {@inheritdoc}
62
+	 *
63
+	 * See: https://github.com/Medium/medium-api-docs#getting-the-authenticated-users-details
64
+	 */
65
+	public function getUserProfile()
66
+	{
67
+		$response = $this->apiRequest('me');
68 68
 
69
-        $data = new Data\Collection($response);
69
+		$data = new Data\Collection($response);
70 70
 
71
-        $userProfile = new User\Profile();
72
-        $data = $data->filter('data');
71
+		$userProfile = new User\Profile();
72
+		$data = $data->filter('data');
73 73
 
74
-        $full_name = explode(' ', $data->get('name'));
75
-        if (count($full_name) < 2) {
76
-            $full_name[1] = '';
77
-        }
74
+		$full_name = explode(' ', $data->get('name'));
75
+		if (count($full_name) < 2) {
76
+			$full_name[1] = '';
77
+		}
78 78
 
79
-        $userProfile->identifier = $data->get('id');
80
-        $userProfile->displayName = $data->get('username');
81
-        $userProfile->profileURL = $data->get('imageUrl');
82
-        $userProfile->firstName = $full_name[0];
83
-        $userProfile->lastName = $full_name[1];
84
-        $userProfile->profileURL = $data->get('url');
79
+		$userProfile->identifier = $data->get('id');
80
+		$userProfile->displayName = $data->get('username');
81
+		$userProfile->profileURL = $data->get('imageUrl');
82
+		$userProfile->firstName = $full_name[0];
83
+		$userProfile->lastName = $full_name[1];
84
+		$userProfile->profileURL = $data->get('url');
85 85
 
86
-        return $userProfile;
87
-    }
86
+		return $userProfile;
87
+	}
88 88
 }
Please login to merge, or discard this patch.
src/Adapter/AdapterInterface.php 1 patch
Indentation   +136 added lines, -136 removed lines patch added patch discarded remove patch
@@ -16,140 +16,140 @@
 block discarded – undo
16 16
  */
17 17
 interface AdapterInterface
18 18
 {
19
-    /**
20
-     * Initiate the appropriate protocol and process/automate the authentication or authorization flow.
21
-     *
22
-     * @return bool|null
23
-     */
24
-    public function authenticate();
25
-
26
-    /**
27
-     * Returns TRUE if the user is connected
28
-     *
29
-     * @return bool
30
-     */
31
-    public function isConnected();
32
-
33
-    /**
34
-     * Clear all access token in storage
35
-     */
36
-    public function disconnect();
37
-
38
-    /**
39
-     * Retrieve the connected user profile
40
-     *
41
-     * @return \Hybridauth\User\Profile
42
-     */
43
-    public function getUserProfile();
44
-
45
-    /**
46
-     * Retrieve the connected user contacts list
47
-     *
48
-     * @return \Hybridauth\User\Contact[]
49
-     */
50
-    public function getUserContacts();
51
-
52
-    /**
53
-     * Retrieve the connected user pages|companies|groups list
54
-     *
55
-     * @return array
56
-     */
57
-    public function getUserPages();
58
-
59
-    /**
60
-     * Retrieve the user activity stream
61
-     *
62
-     * @param string $stream
63
-     *
64
-     * @return \Hybridauth\User\Activity[]
65
-     */
66
-    public function getUserActivity($stream);
67
-
68
-    /**
69
-     * Post a status on user wall|timeline|blog|website|etc.
70
-     *
71
-     * @param string|array $status
72
-     *
73
-     * @return mixed API response
74
-     */
75
-    public function setUserStatus($status);
76
-
77
-    /**
78
-     * Post a status on page|company|group wall.
79
-     *
80
-     * @param string|array $status
81
-     * @param string $pageId
82
-     *
83
-     * @return mixed API response
84
-     */
85
-    public function setPageStatus($status, $pageId);
86
-
87
-    /**
88
-     * Send a signed request to provider API
89
-     *
90
-     * @param string $url
91
-     * @param string $method
92
-     * @param array $parameters
93
-     * @param array $headers
94
-     * @param bool $multipart
95
-     *
96
-     * @return mixed
97
-     */
98
-    public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false);
99
-
100
-    /**
101
-     * Do whatever may be necessary to make sure tokens do not expire.
102
-     * Intended to be be called frequently, e.g. via Cron.
103
-     */
104
-    public function maintainToken();
105
-
106
-    /**
107
-     * Return oauth access tokens.
108
-     *
109
-     * @return array
110
-     */
111
-    public function getAccessToken();
112
-
113
-    /**
114
-     * Set oauth access tokens.
115
-     *
116
-     * @param array $tokens
117
-     */
118
-    public function setAccessToken($tokens = []);
119
-
120
-    /**
121
-     * Set http client instance.
122
-     *
123
-     * @param HttpClientInterface $httpClient
124
-     */
125
-    public function setHttpClient(HttpClientInterface $httpClient = null);
126
-
127
-    /**
128
-     * Return http client instance.
129
-     */
130
-    public function getHttpClient();
131
-
132
-    /**
133
-     * Set storage instance.
134
-     *
135
-     * @param StorageInterface $storage
136
-     */
137
-    public function setStorage(StorageInterface $storage = null);
138
-
139
-    /**
140
-     * Return storage instance.
141
-     */
142
-    public function getStorage();
143
-
144
-    /**
145
-     * Set Logger instance.
146
-     *
147
-     * @param LoggerInterface $logger
148
-     */
149
-    public function setLogger(LoggerInterface $logger = null);
150
-
151
-    /**
152
-     * Return logger instance.
153
-     */
154
-    public function getLogger();
19
+	/**
20
+	 * Initiate the appropriate protocol and process/automate the authentication or authorization flow.
21
+	 *
22
+	 * @return bool|null
23
+	 */
24
+	public function authenticate();
25
+
26
+	/**
27
+	 * Returns TRUE if the user is connected
28
+	 *
29
+	 * @return bool
30
+	 */
31
+	public function isConnected();
32
+
33
+	/**
34
+	 * Clear all access token in storage
35
+	 */
36
+	public function disconnect();
37
+
38
+	/**
39
+	 * Retrieve the connected user profile
40
+	 *
41
+	 * @return \Hybridauth\User\Profile
42
+	 */
43
+	public function getUserProfile();
44
+
45
+	/**
46
+	 * Retrieve the connected user contacts list
47
+	 *
48
+	 * @return \Hybridauth\User\Contact[]
49
+	 */
50
+	public function getUserContacts();
51
+
52
+	/**
53
+	 * Retrieve the connected user pages|companies|groups list
54
+	 *
55
+	 * @return array
56
+	 */
57
+	public function getUserPages();
58
+
59
+	/**
60
+	 * Retrieve the user activity stream
61
+	 *
62
+	 * @param string $stream
63
+	 *
64
+	 * @return \Hybridauth\User\Activity[]
65
+	 */
66
+	public function getUserActivity($stream);
67
+
68
+	/**
69
+	 * Post a status on user wall|timeline|blog|website|etc.
70
+	 *
71
+	 * @param string|array $status
72
+	 *
73
+	 * @return mixed API response
74
+	 */
75
+	public function setUserStatus($status);
76
+
77
+	/**
78
+	 * Post a status on page|company|group wall.
79
+	 *
80
+	 * @param string|array $status
81
+	 * @param string $pageId
82
+	 *
83
+	 * @return mixed API response
84
+	 */
85
+	public function setPageStatus($status, $pageId);
86
+
87
+	/**
88
+	 * Send a signed request to provider API
89
+	 *
90
+	 * @param string $url
91
+	 * @param string $method
92
+	 * @param array $parameters
93
+	 * @param array $headers
94
+	 * @param bool $multipart
95
+	 *
96
+	 * @return mixed
97
+	 */
98
+	public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false);
99
+
100
+	/**
101
+	 * Do whatever may be necessary to make sure tokens do not expire.
102
+	 * Intended to be be called frequently, e.g. via Cron.
103
+	 */
104
+	public function maintainToken();
105
+
106
+	/**
107
+	 * Return oauth access tokens.
108
+	 *
109
+	 * @return array
110
+	 */
111
+	public function getAccessToken();
112
+
113
+	/**
114
+	 * Set oauth access tokens.
115
+	 *
116
+	 * @param array $tokens
117
+	 */
118
+	public function setAccessToken($tokens = []);
119
+
120
+	/**
121
+	 * Set http client instance.
122
+	 *
123
+	 * @param HttpClientInterface $httpClient
124
+	 */
125
+	public function setHttpClient(HttpClientInterface $httpClient = null);
126
+
127
+	/**
128
+	 * Return http client instance.
129
+	 */
130
+	public function getHttpClient();
131
+
132
+	/**
133
+	 * Set storage instance.
134
+	 *
135
+	 * @param StorageInterface $storage
136
+	 */
137
+	public function setStorage(StorageInterface $storage = null);
138
+
139
+	/**
140
+	 * Return storage instance.
141
+	 */
142
+	public function getStorage();
143
+
144
+	/**
145
+	 * Set Logger instance.
146
+	 *
147
+	 * @param LoggerInterface $logger
148
+	 */
149
+	public function setLogger(LoggerInterface $logger = null);
150
+
151
+	/**
152
+	 * Return logger instance.
153
+	 */
154
+	public function getLogger();
155 155
 }
Please login to merge, or discard this patch.
src/Adapter/AbstractAdapter.php 1 patch
Indentation   +345 added lines, -345 removed lines patch added patch discarded remove patch
@@ -24,349 +24,349 @@
 block discarded – undo
24 24
  */
25 25
 abstract class AbstractAdapter implements AdapterInterface
26 26
 {
27
-    use DataStoreTrait;
28
-
29
-    /**
30
-     * Provider ID (unique name).
31
-     *
32
-     * @var string
33
-     */
34
-    protected $providerId = '';
35
-
36
-    /**
37
-     * Specific Provider config.
38
-     *
39
-     * @var mixed
40
-     */
41
-    protected $config = [];
42
-
43
-    /**
44
-     * Extra Provider parameters.
45
-     *
46
-     * @var array
47
-     */
48
-    protected $params;
49
-
50
-    /**
51
-     * Callback url
52
-     *
53
-     * @var string
54
-     */
55
-    protected $callback = '';
56
-
57
-    /**
58
-     * Storage.
59
-     *
60
-     * @var StorageInterface
61
-     */
62
-    public $storage;
63
-
64
-    /**
65
-     * HttpClient.
66
-     *
67
-     * @var HttpClientInterface
68
-     */
69
-    public $httpClient;
70
-
71
-    /**
72
-     * Logger.
73
-     *
74
-     * @var LoggerInterface
75
-     */
76
-    public $logger;
77
-
78
-    /**
79
-     * Whether to validate API status codes of http responses
80
-     *
81
-     * @var bool
82
-     */
83
-    protected $validateApiResponseHttpCode = true;
84
-
85
-    /**
86
-     * Common adapters constructor.
87
-     *
88
-     * @param array $config
89
-     * @param HttpClientInterface $httpClient
90
-     * @param StorageInterface $storage
91
-     * @param LoggerInterface $logger
92
-     */
93
-    public function __construct(
94
-        $config = [],
95
-        HttpClientInterface $httpClient = null,
96
-        StorageInterface $storage = null,
97
-        LoggerInterface $logger = null
98
-    ) {
99
-        $this->providerId = (new \ReflectionClass($this))->getShortName();
100
-
101
-        $this->config = new Data\Collection($config);
102
-
103
-        $this->setHttpClient($httpClient);
104
-
105
-        $this->setStorage($storage);
106
-
107
-        $this->setLogger($logger);
108
-
109
-        $this->configure();
110
-
111
-        $this->logger->debug(sprintf('Initialize %s, config: ', get_class($this)), $config);
112
-
113
-        $this->initialize();
114
-    }
115
-
116
-    /**
117
-     * Load adapter's configuration
118
-     */
119
-    abstract protected function configure();
120
-
121
-    /**
122
-     * Adapter initializer
123
-     */
124
-    abstract protected function initialize();
125
-
126
-    /**
127
-     * {@inheritdoc}
128
-     */
129
-    abstract public function isConnected();
130
-
131
-    /**
132
-     * {@inheritdoc}
133
-     */
134
-    public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
135
-    {
136
-        throw new NotImplementedException('Provider does not support this feature.');
137
-    }
138
-
139
-    /**
140
-     * {@inheritdoc}
141
-     */
142
-    public function maintainToken()
143
-    {
144
-        // Nothing needed for most providers
145
-    }
146
-
147
-    /**
148
-     * {@inheritdoc}
149
-     */
150
-    public function getUserProfile()
151
-    {
152
-        throw new NotImplementedException('Provider does not support this feature.');
153
-    }
154
-
155
-    /**
156
-     * {@inheritdoc}
157
-     */
158
-    public function getUserContacts()
159
-    {
160
-        throw new NotImplementedException('Provider does not support this feature.');
161
-    }
162
-
163
-    /**
164
-     * {@inheritdoc}
165
-     */
166
-    public function getUserPages()
167
-    {
168
-        throw new NotImplementedException('Provider does not support this feature.');
169
-    }
170
-
171
-    /**
172
-     * {@inheritdoc}
173
-     */
174
-    public function getUserActivity($stream)
175
-    {
176
-        throw new NotImplementedException('Provider does not support this feature.');
177
-    }
178
-
179
-    /**
180
-     * {@inheritdoc}
181
-     */
182
-    public function setUserStatus($status)
183
-    {
184
-        throw new NotImplementedException('Provider does not support this feature.');
185
-    }
186
-
187
-    /**
188
-     * {@inheritdoc}
189
-     */
190
-    public function setPageStatus($status, $pageId)
191
-    {
192
-        throw new NotImplementedException('Provider does not support this feature.');
193
-    }
194
-
195
-    /**
196
-     * {@inheritdoc}
197
-     */
198
-    public function disconnect()
199
-    {
200
-        $this->clearStoredData();
201
-    }
202
-
203
-    /**
204
-     * {@inheritdoc}
205
-     */
206
-    public function getAccessToken()
207
-    {
208
-        $tokenNames = [
209
-            'access_token',
210
-            'access_token_secret',
211
-            'token_type',
212
-            'refresh_token',
213
-            'expires_in',
214
-            'expires_at',
215
-        ];
216
-
217
-        $tokens = [];
218
-
219
-        foreach ($tokenNames as $name) {
220
-            if ($this->getStoredData($name)) {
221
-                $tokens[$name] = $this->getStoredData($name);
222
-            }
223
-        }
224
-
225
-        return $tokens;
226
-    }
227
-
228
-    /**
229
-     * {@inheritdoc}
230
-     */
231
-    public function setAccessToken($tokens = [])
232
-    {
233
-        $this->clearStoredData();
234
-
235
-        foreach ($tokens as $token => $value) {
236
-            $this->storeData($token, $value);
237
-        }
238
-
239
-        // Re-initialize token parameters.
240
-        $this->initialize();
241
-    }
242
-
243
-    /**
244
-     * {@inheritdoc}
245
-     */
246
-    public function setHttpClient(HttpClientInterface $httpClient = null)
247
-    {
248
-        $this->httpClient = $httpClient ?: new HttpClient();
249
-
250
-        if ($this->config->exists('curl_options') && method_exists($this->httpClient, 'setCurlOptions')) {
251
-            $this->httpClient->setCurlOptions($this->config->get('curl_options'));
252
-        }
253
-    }
254
-
255
-    /**
256
-     * {@inheritdoc}
257
-     */
258
-    public function getHttpClient()
259
-    {
260
-        return $this->httpClient;
261
-    }
262
-
263
-    /**
264
-     * {@inheritdoc}
265
-     */
266
-    public function setStorage(StorageInterface $storage = null)
267
-    {
268
-        $this->storage = $storage ?: new Session();
269
-    }
270
-
271
-    /**
272
-     * {@inheritdoc}
273
-     */
274
-    public function getStorage()
275
-    {
276
-        return $this->storage;
277
-    }
278
-
279
-    /**
280
-     * {@inheritdoc}
281
-     */
282
-    public function setLogger(LoggerInterface $logger = null)
283
-    {
284
-        $this->logger = $logger ?: new Logger(
285
-            $this->config->get('debug_mode'),
286
-            $this->config->get('debug_file')
287
-        );
288
-
289
-        if (method_exists($this->httpClient, 'setLogger')) {
290
-            $this->httpClient->setLogger($this->logger);
291
-        }
292
-    }
293
-
294
-    /**
295
-     * {@inheritdoc}
296
-     */
297
-    public function getLogger()
298
-    {
299
-        return $this->logger;
300
-    }
301
-
302
-    /**
303
-     * Set Adapter's API callback url
304
-     *
305
-     * @param string $callback
306
-     *
307
-     * @throws InvalidArgumentException
308
-     */
309
-    protected function setCallback($callback)
310
-    {
311
-        if (!filter_var($callback, FILTER_VALIDATE_URL)) {
312
-            throw new InvalidArgumentException('A valid callback url is required.');
313
-        }
314
-
315
-        $this->callback = $callback;
316
-    }
317
-
318
-    /**
319
-     * Overwrite Adapter's API endpoints
320
-     *
321
-     * @param array|Data\Collection $endpoints
322
-     */
323
-    protected function setApiEndpoints($endpoints = null)
324
-    {
325
-        if (empty($endpoints)) {
326
-            return;
327
-        }
328
-
329
-        $collection = is_array($endpoints) ? new Data\Collection($endpoints) : $endpoints;
330
-
331
-        $this->apiBaseUrl = $collection->get('api_base_url') ?: $this->apiBaseUrl;
332
-        $this->authorizeUrl = $collection->get('authorize_url') ?: $this->authorizeUrl;
333
-        $this->accessTokenUrl = $collection->get('access_token_url') ?: $this->accessTokenUrl;
334
-    }
335
-
336
-
337
-    /**
338
-     * Validate signed API responses Http status code.
339
-     *
340
-     * Since the specifics of error responses is beyond the scope of RFC6749 and OAuth Core specifications,
341
-     * Hybridauth will consider any HTTP status code that is different than '200 OK' as an ERROR.
342
-     *
343
-     * @param string $error String to pre append to message thrown in exception
344
-     *
345
-     * @throws HttpClientFailureException
346
-     * @throws HttpRequestFailedException
347
-     */
348
-    protected function validateApiResponse($error = '')
349
-    {
350
-        $error .= !empty($error) ? '. ' : '';
351
-
352
-        if ($this->httpClient->getResponseClientError()) {
353
-            throw new HttpClientFailureException(
354
-                $error . 'HTTP client error: ' . $this->httpClient->getResponseClientError() . '.'
355
-            );
356
-        }
357
-
358
-        // if validateApiResponseHttpCode is set to false, we by pass verification of http status code
359
-        if (!$this->validateApiResponseHttpCode) {
360
-            return;
361
-        }
362
-
363
-        $status = $this->httpClient->getResponseHttpCode();
364
-
365
-        if ($status < 200 || $status > 299) {
366
-            throw new HttpRequestFailedException(
367
-                $error . 'HTTP error ' . $this->httpClient->getResponseHttpCode() .
368
-                '. Raw Provider API response: ' . $this->httpClient->getResponseBody() . '.'
369
-            );
370
-        }
371
-    }
27
+	use DataStoreTrait;
28
+
29
+	/**
30
+	 * Provider ID (unique name).
31
+	 *
32
+	 * @var string
33
+	 */
34
+	protected $providerId = '';
35
+
36
+	/**
37
+	 * Specific Provider config.
38
+	 *
39
+	 * @var mixed
40
+	 */
41
+	protected $config = [];
42
+
43
+	/**
44
+	 * Extra Provider parameters.
45
+	 *
46
+	 * @var array
47
+	 */
48
+	protected $params;
49
+
50
+	/**
51
+	 * Callback url
52
+	 *
53
+	 * @var string
54
+	 */
55
+	protected $callback = '';
56
+
57
+	/**
58
+	 * Storage.
59
+	 *
60
+	 * @var StorageInterface
61
+	 */
62
+	public $storage;
63
+
64
+	/**
65
+	 * HttpClient.
66
+	 *
67
+	 * @var HttpClientInterface
68
+	 */
69
+	public $httpClient;
70
+
71
+	/**
72
+	 * Logger.
73
+	 *
74
+	 * @var LoggerInterface
75
+	 */
76
+	public $logger;
77
+
78
+	/**
79
+	 * Whether to validate API status codes of http responses
80
+	 *
81
+	 * @var bool
82
+	 */
83
+	protected $validateApiResponseHttpCode = true;
84
+
85
+	/**
86
+	 * Common adapters constructor.
87
+	 *
88
+	 * @param array $config
89
+	 * @param HttpClientInterface $httpClient
90
+	 * @param StorageInterface $storage
91
+	 * @param LoggerInterface $logger
92
+	 */
93
+	public function __construct(
94
+		$config = [],
95
+		HttpClientInterface $httpClient = null,
96
+		StorageInterface $storage = null,
97
+		LoggerInterface $logger = null
98
+	) {
99
+		$this->providerId = (new \ReflectionClass($this))->getShortName();
100
+
101
+		$this->config = new Data\Collection($config);
102
+
103
+		$this->setHttpClient($httpClient);
104
+
105
+		$this->setStorage($storage);
106
+
107
+		$this->setLogger($logger);
108
+
109
+		$this->configure();
110
+
111
+		$this->logger->debug(sprintf('Initialize %s, config: ', get_class($this)), $config);
112
+
113
+		$this->initialize();
114
+	}
115
+
116
+	/**
117
+	 * Load adapter's configuration
118
+	 */
119
+	abstract protected function configure();
120
+
121
+	/**
122
+	 * Adapter initializer
123
+	 */
124
+	abstract protected function initialize();
125
+
126
+	/**
127
+	 * {@inheritdoc}
128
+	 */
129
+	abstract public function isConnected();
130
+
131
+	/**
132
+	 * {@inheritdoc}
133
+	 */
134
+	public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
135
+	{
136
+		throw new NotImplementedException('Provider does not support this feature.');
137
+	}
138
+
139
+	/**
140
+	 * {@inheritdoc}
141
+	 */
142
+	public function maintainToken()
143
+	{
144
+		// Nothing needed for most providers
145
+	}
146
+
147
+	/**
148
+	 * {@inheritdoc}
149
+	 */
150
+	public function getUserProfile()
151
+	{
152
+		throw new NotImplementedException('Provider does not support this feature.');
153
+	}
154
+
155
+	/**
156
+	 * {@inheritdoc}
157
+	 */
158
+	public function getUserContacts()
159
+	{
160
+		throw new NotImplementedException('Provider does not support this feature.');
161
+	}
162
+
163
+	/**
164
+	 * {@inheritdoc}
165
+	 */
166
+	public function getUserPages()
167
+	{
168
+		throw new NotImplementedException('Provider does not support this feature.');
169
+	}
170
+
171
+	/**
172
+	 * {@inheritdoc}
173
+	 */
174
+	public function getUserActivity($stream)
175
+	{
176
+		throw new NotImplementedException('Provider does not support this feature.');
177
+	}
178
+
179
+	/**
180
+	 * {@inheritdoc}
181
+	 */
182
+	public function setUserStatus($status)
183
+	{
184
+		throw new NotImplementedException('Provider does not support this feature.');
185
+	}
186
+
187
+	/**
188
+	 * {@inheritdoc}
189
+	 */
190
+	public function setPageStatus($status, $pageId)
191
+	{
192
+		throw new NotImplementedException('Provider does not support this feature.');
193
+	}
194
+
195
+	/**
196
+	 * {@inheritdoc}
197
+	 */
198
+	public function disconnect()
199
+	{
200
+		$this->clearStoredData();
201
+	}
202
+
203
+	/**
204
+	 * {@inheritdoc}
205
+	 */
206
+	public function getAccessToken()
207
+	{
208
+		$tokenNames = [
209
+			'access_token',
210
+			'access_token_secret',
211
+			'token_type',
212
+			'refresh_token',
213
+			'expires_in',
214
+			'expires_at',
215
+		];
216
+
217
+		$tokens = [];
218
+
219
+		foreach ($tokenNames as $name) {
220
+			if ($this->getStoredData($name)) {
221
+				$tokens[$name] = $this->getStoredData($name);
222
+			}
223
+		}
224
+
225
+		return $tokens;
226
+	}
227
+
228
+	/**
229
+	 * {@inheritdoc}
230
+	 */
231
+	public function setAccessToken($tokens = [])
232
+	{
233
+		$this->clearStoredData();
234
+
235
+		foreach ($tokens as $token => $value) {
236
+			$this->storeData($token, $value);
237
+		}
238
+
239
+		// Re-initialize token parameters.
240
+		$this->initialize();
241
+	}
242
+
243
+	/**
244
+	 * {@inheritdoc}
245
+	 */
246
+	public function setHttpClient(HttpClientInterface $httpClient = null)
247
+	{
248
+		$this->httpClient = $httpClient ?: new HttpClient();
249
+
250
+		if ($this->config->exists('curl_options') && method_exists($this->httpClient, 'setCurlOptions')) {
251
+			$this->httpClient->setCurlOptions($this->config->get('curl_options'));
252
+		}
253
+	}
254
+
255
+	/**
256
+	 * {@inheritdoc}
257
+	 */
258
+	public function getHttpClient()
259
+	{
260
+		return $this->httpClient;
261
+	}
262
+
263
+	/**
264
+	 * {@inheritdoc}
265
+	 */
266
+	public function setStorage(StorageInterface $storage = null)
267
+	{
268
+		$this->storage = $storage ?: new Session();
269
+	}
270
+
271
+	/**
272
+	 * {@inheritdoc}
273
+	 */
274
+	public function getStorage()
275
+	{
276
+		return $this->storage;
277
+	}
278
+
279
+	/**
280
+	 * {@inheritdoc}
281
+	 */
282
+	public function setLogger(LoggerInterface $logger = null)
283
+	{
284
+		$this->logger = $logger ?: new Logger(
285
+			$this->config->get('debug_mode'),
286
+			$this->config->get('debug_file')
287
+		);
288
+
289
+		if (method_exists($this->httpClient, 'setLogger')) {
290
+			$this->httpClient->setLogger($this->logger);
291
+		}
292
+	}
293
+
294
+	/**
295
+	 * {@inheritdoc}
296
+	 */
297
+	public function getLogger()
298
+	{
299
+		return $this->logger;
300
+	}
301
+
302
+	/**
303
+	 * Set Adapter's API callback url
304
+	 *
305
+	 * @param string $callback
306
+	 *
307
+	 * @throws InvalidArgumentException
308
+	 */
309
+	protected function setCallback($callback)
310
+	{
311
+		if (!filter_var($callback, FILTER_VALIDATE_URL)) {
312
+			throw new InvalidArgumentException('A valid callback url is required.');
313
+		}
314
+
315
+		$this->callback = $callback;
316
+	}
317
+
318
+	/**
319
+	 * Overwrite Adapter's API endpoints
320
+	 *
321
+	 * @param array|Data\Collection $endpoints
322
+	 */
323
+	protected function setApiEndpoints($endpoints = null)
324
+	{
325
+		if (empty($endpoints)) {
326
+			return;
327
+		}
328
+
329
+		$collection = is_array($endpoints) ? new Data\Collection($endpoints) : $endpoints;
330
+
331
+		$this->apiBaseUrl = $collection->get('api_base_url') ?: $this->apiBaseUrl;
332
+		$this->authorizeUrl = $collection->get('authorize_url') ?: $this->authorizeUrl;
333
+		$this->accessTokenUrl = $collection->get('access_token_url') ?: $this->accessTokenUrl;
334
+	}
335
+
336
+
337
+	/**
338
+	 * Validate signed API responses Http status code.
339
+	 *
340
+	 * Since the specifics of error responses is beyond the scope of RFC6749 and OAuth Core specifications,
341
+	 * Hybridauth will consider any HTTP status code that is different than '200 OK' as an ERROR.
342
+	 *
343
+	 * @param string $error String to pre append to message thrown in exception
344
+	 *
345
+	 * @throws HttpClientFailureException
346
+	 * @throws HttpRequestFailedException
347
+	 */
348
+	protected function validateApiResponse($error = '')
349
+	{
350
+		$error .= !empty($error) ? '. ' : '';
351
+
352
+		if ($this->httpClient->getResponseClientError()) {
353
+			throw new HttpClientFailureException(
354
+				$error . 'HTTP client error: ' . $this->httpClient->getResponseClientError() . '.'
355
+			);
356
+		}
357
+
358
+		// if validateApiResponseHttpCode is set to false, we by pass verification of http status code
359
+		if (!$this->validateApiResponseHttpCode) {
360
+			return;
361
+		}
362
+
363
+		$status = $this->httpClient->getResponseHttpCode();
364
+
365
+		if ($status < 200 || $status > 299) {
366
+			throw new HttpRequestFailedException(
367
+				$error . 'HTTP error ' . $this->httpClient->getResponseHttpCode() .
368
+				'. Raw Provider API response: ' . $this->httpClient->getResponseBody() . '.'
369
+			);
370
+		}
371
+	}
372 372
 }
Please login to merge, or discard this patch.
src/Provider/Telegram.php 1 patch
Indentation   +164 added lines, -164 removed lines patch added patch discarded remove patch
@@ -44,143 +44,143 @@  discard block
 block discarded – undo
44 44
  */
45 45
 class Telegram extends AbstractAdapter implements AdapterInterface
46 46
 {
47
-    protected $botId = '';
48
-
49
-    protected $botSecret = '';
50
-
51
-    protected $callbackUrl = '';
52
-
53
-    /**
54
-     * IPD API Documentation
55
-     *
56
-     * OPTIONAL.
57
-     *
58
-     * @var string
59
-     */
60
-    protected $apiDocumentation = 'https://core.telegram.org/bots';
61
-
62
-    /**
63
-     * {@inheritdoc}
64
-     */
65
-    protected function configure()
66
-    {
67
-        $this->botId = $this->config->filter('keys')->get('id');
68
-        $this->botSecret = $this->config->filter('keys')->get('secret');
69
-        $this->callbackUrl = $this->config->get('callback');
70
-
71
-        if (!$this->botId || !$this->botSecret) {
72
-            throw new InvalidApplicationCredentialsException(
73
-                'Your application id is required in order to connect to ' . $this->providerId
74
-            );
75
-        }
76
-    }
77
-
78
-    /**
79
-     * {@inheritdoc}
80
-     */
81
-    protected function initialize()
82
-    {
83
-    }
84
-
85
-    /**
86
-     * {@inheritdoc}
87
-     */
88
-    public function authenticate()
89
-    {
90
-        $this->logger->info(sprintf('%s::authenticate()', get_class($this)));
91
-        if (!filter_input(INPUT_GET, 'hash')) {
92
-            $this->authenticateBegin();
93
-        } else {
94
-            $this->authenticateCheckError();
95
-            $this->authenticateFinish();
96
-        }
97
-        return null;
98
-    }
99
-
100
-    /**
101
-     * {@inheritdoc}
102
-     */
103
-    public function isConnected()
104
-    {
105
-        $authData = $this->getStoredData('auth_data');
106
-        return !empty($authData);
107
-    }
108
-
109
-    /**
110
-     * {@inheritdoc}
111
-     */
112
-    public function getUserProfile()
113
-    {
114
-        $data = new Collection($this->getStoredData('auth_data'));
115
-
116
-        if (!$data->exists('id')) {
117
-            throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
118
-        }
119
-
120
-        $userProfile = new Profile();
121
-
122
-        $userProfile->identifier = $data->get('id');
123
-        $userProfile->firstName = $data->get('first_name');
124
-        $userProfile->lastName = $data->get('last_name');
125
-        $userProfile->displayName = $data->get('username');
126
-        $userProfile->photoURL = $data->get('photo_url');
127
-        $username = $data->get('username');
128
-        if (!empty($username)) {
129
-            // Only some accounts have usernames.
130
-            $userProfile->profileURL = "https://t.me/{$username}";
131
-        }
132
-
133
-        return $userProfile;
134
-    }
135
-
136
-    /**
137
-     * See: https://telegram.im/widget-login.php
138
-     * See: https://gist.github.com/anonymous/6516521b1fb3b464534fbc30ea3573c2
139
-     */
140
-    protected function authenticateCheckError()
141
-    {
142
-        $auth_data = $this->parseAuthData();
143
-
144
-        $check_hash = $auth_data['hash'];
145
-        unset($auth_data['hash']);
146
-        $data_check_arr = [];
147
-
148
-        foreach ($auth_data as $key => $value) {
149
-            if (!empty($value)) {
150
-                $data_check_arr[] = $key . '=' . $value;
151
-            }
152
-        }
153
-        sort($data_check_arr);
154
-
155
-        $data_check_string = implode("\n", $data_check_arr);
156
-        $secret_key = hash('sha256', $this->botSecret, true);
157
-        $hash = hash_hmac('sha256', $data_check_string, $secret_key);
158
-
159
-        if (strcmp($hash, $check_hash) !== 0) {
160
-            throw new InvalidAuthorizationCodeException(
161
-                sprintf('Provider returned an error: %s', 'Data is NOT from Telegram')
162
-            );
163
-        }
164
-
165
-        if ((time() - $auth_data['auth_date']) > 86400) {
166
-            throw new InvalidAuthorizationCodeException(
167
-                sprintf('Provider returned an error: %s', 'Data is outdated')
168
-            );
169
-        }
170
-    }
171
-
172
-    /**
173
-     * See: https://telegram.im/widget-login.php
174
-     */
175
-    protected function authenticateBegin()
176
-    {
177
-        $this->logger->debug(sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)));
178
-
179
-        $nonce = $this->config->get('nonce');
180
-        $nonce_code = empty($nonce) ? '' : "nonce=\"{$nonce}\"";
181
-
182
-        exit(
183
-            <<<HTML
47
+	protected $botId = '';
48
+
49
+	protected $botSecret = '';
50
+
51
+	protected $callbackUrl = '';
52
+
53
+	/**
54
+	 * IPD API Documentation
55
+	 *
56
+	 * OPTIONAL.
57
+	 *
58
+	 * @var string
59
+	 */
60
+	protected $apiDocumentation = 'https://core.telegram.org/bots';
61
+
62
+	/**
63
+	 * {@inheritdoc}
64
+	 */
65
+	protected function configure()
66
+	{
67
+		$this->botId = $this->config->filter('keys')->get('id');
68
+		$this->botSecret = $this->config->filter('keys')->get('secret');
69
+		$this->callbackUrl = $this->config->get('callback');
70
+
71
+		if (!$this->botId || !$this->botSecret) {
72
+			throw new InvalidApplicationCredentialsException(
73
+				'Your application id is required in order to connect to ' . $this->providerId
74
+			);
75
+		}
76
+	}
77
+
78
+	/**
79
+	 * {@inheritdoc}
80
+	 */
81
+	protected function initialize()
82
+	{
83
+	}
84
+
85
+	/**
86
+	 * {@inheritdoc}
87
+	 */
88
+	public function authenticate()
89
+	{
90
+		$this->logger->info(sprintf('%s::authenticate()', get_class($this)));
91
+		if (!filter_input(INPUT_GET, 'hash')) {
92
+			$this->authenticateBegin();
93
+		} else {
94
+			$this->authenticateCheckError();
95
+			$this->authenticateFinish();
96
+		}
97
+		return null;
98
+	}
99
+
100
+	/**
101
+	 * {@inheritdoc}
102
+	 */
103
+	public function isConnected()
104
+	{
105
+		$authData = $this->getStoredData('auth_data');
106
+		return !empty($authData);
107
+	}
108
+
109
+	/**
110
+	 * {@inheritdoc}
111
+	 */
112
+	public function getUserProfile()
113
+	{
114
+		$data = new Collection($this->getStoredData('auth_data'));
115
+
116
+		if (!$data->exists('id')) {
117
+			throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
118
+		}
119
+
120
+		$userProfile = new Profile();
121
+
122
+		$userProfile->identifier = $data->get('id');
123
+		$userProfile->firstName = $data->get('first_name');
124
+		$userProfile->lastName = $data->get('last_name');
125
+		$userProfile->displayName = $data->get('username');
126
+		$userProfile->photoURL = $data->get('photo_url');
127
+		$username = $data->get('username');
128
+		if (!empty($username)) {
129
+			// Only some accounts have usernames.
130
+			$userProfile->profileURL = "https://t.me/{$username}";
131
+		}
132
+
133
+		return $userProfile;
134
+	}
135
+
136
+	/**
137
+	 * See: https://telegram.im/widget-login.php
138
+	 * See: https://gist.github.com/anonymous/6516521b1fb3b464534fbc30ea3573c2
139
+	 */
140
+	protected function authenticateCheckError()
141
+	{
142
+		$auth_data = $this->parseAuthData();
143
+
144
+		$check_hash = $auth_data['hash'];
145
+		unset($auth_data['hash']);
146
+		$data_check_arr = [];
147
+
148
+		foreach ($auth_data as $key => $value) {
149
+			if (!empty($value)) {
150
+				$data_check_arr[] = $key . '=' . $value;
151
+			}
152
+		}
153
+		sort($data_check_arr);
154
+
155
+		$data_check_string = implode("\n", $data_check_arr);
156
+		$secret_key = hash('sha256', $this->botSecret, true);
157
+		$hash = hash_hmac('sha256', $data_check_string, $secret_key);
158
+
159
+		if (strcmp($hash, $check_hash) !== 0) {
160
+			throw new InvalidAuthorizationCodeException(
161
+				sprintf('Provider returned an error: %s', 'Data is NOT from Telegram')
162
+			);
163
+		}
164
+
165
+		if ((time() - $auth_data['auth_date']) > 86400) {
166
+			throw new InvalidAuthorizationCodeException(
167
+				sprintf('Provider returned an error: %s', 'Data is outdated')
168
+			);
169
+		}
170
+	}
171
+
172
+	/**
173
+	 * See: https://telegram.im/widget-login.php
174
+	 */
175
+	protected function authenticateBegin()
176
+	{
177
+		$this->logger->debug(sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)));
178
+
179
+		$nonce = $this->config->get('nonce');
180
+		$nonce_code = empty($nonce) ? '' : "nonce=\"{$nonce}\"";
181
+
182
+		exit(
183
+			<<<HTML
184 184
 <center>
185 185
     <script async src="https://telegram.org/js/telegram-widget.js?7"
186 186
             {$nonce_code}
@@ -191,31 +191,31 @@  discard block
 block discarded – undo
191 191
     </script>
192 192
 </center>
193 193
 HTML
194
-        );
195
-    }
196
-
197
-    protected function authenticateFinish()
198
-    {
199
-        $this->logger->debug(
200
-            sprintf('%s::authenticateFinish(), callback url:', get_class($this)),
201
-            [Util::getCurrentUrl(true)]
202
-        );
203
-
204
-        $this->storeData('auth_data', $this->parseAuthData());
205
-
206
-        $this->initialize();
207
-    }
208
-
209
-    protected function parseAuthData()
210
-    {
211
-        return [
212
-            'id' => filter_input(INPUT_GET, 'id'),
213
-            'first_name' => filter_input(INPUT_GET, 'first_name'),
214
-            'last_name' => filter_input(INPUT_GET, 'last_name'),
215
-            'username' => filter_input(INPUT_GET, 'username'),
216
-            'photo_url' => filter_input(INPUT_GET, 'photo_url'),
217
-            'auth_date' => filter_input(INPUT_GET, 'auth_date'),
218
-            'hash' => filter_input(INPUT_GET, 'hash'),
219
-        ];
220
-    }
194
+		);
195
+	}
196
+
197
+	protected function authenticateFinish()
198
+	{
199
+		$this->logger->debug(
200
+			sprintf('%s::authenticateFinish(), callback url:', get_class($this)),
201
+			[Util::getCurrentUrl(true)]
202
+		);
203
+
204
+		$this->storeData('auth_data', $this->parseAuthData());
205
+
206
+		$this->initialize();
207
+	}
208
+
209
+	protected function parseAuthData()
210
+	{
211
+		return [
212
+			'id' => filter_input(INPUT_GET, 'id'),
213
+			'first_name' => filter_input(INPUT_GET, 'first_name'),
214
+			'last_name' => filter_input(INPUT_GET, 'last_name'),
215
+			'username' => filter_input(INPUT_GET, 'username'),
216
+			'photo_url' => filter_input(INPUT_GET, 'photo_url'),
217
+			'auth_date' => filter_input(INPUT_GET, 'auth_date'),
218
+			'hash' => filter_input(INPUT_GET, 'hash'),
219
+		];
220
+	}
221 221
 }
Please login to merge, or discard this patch.
src/HttpClient/Curl.php 1 patch
Indentation   +301 added lines, -301 removed lines patch added patch discarded remove patch
@@ -12,305 +12,305 @@
 block discarded – undo
12 12
  */
13 13
 class Curl implements HttpClientInterface
14 14
 {
15
-    /**
16
-     * Default curl options
17
-     *
18
-     * These defaults options can be overwritten when sending requests.
19
-     *
20
-     * See setCurlOptions()
21
-     *
22
-     * @var array
23
-     */
24
-    protected $curlOptions = [
25
-        CURLOPT_TIMEOUT => 30,
26
-        CURLOPT_CONNECTTIMEOUT => 30,
27
-        CURLOPT_SSL_VERIFYPEER => false,
28
-        CURLOPT_SSL_VERIFYHOST => false,
29
-        CURLOPT_RETURNTRANSFER => true,
30
-        CURLOPT_FOLLOWLOCATION => true,
31
-        CURLOPT_MAXREDIRS => 5,
32
-        CURLINFO_HEADER_OUT => true,
33
-        CURLOPT_ENCODING => 'identity',
34
-        // phpcs:ignore
35
-        CURLOPT_USERAGENT => 'Hybridauth, PHP Social Authentication Library (https://github.com/hybridauth/hybridauth)',
36
-    ];
37
-
38
-    /**
39
-     * Method request() arguments
40
-     *
41
-     * This is used for debugging.
42
-     *
43
-     * @var array
44
-     */
45
-    protected $requestArguments = [];
46
-
47
-    /**
48
-     * Default request headers
49
-     *
50
-     * @var array
51
-     */
52
-    protected $requestHeader = [
53
-        'Accept' => '*/*',
54
-        'Cache-Control' => 'max-age=0',
55
-        'Connection' => 'keep-alive',
56
-        'Expect' => '',
57
-        'Pragma' => '',
58
-    ];
59
-
60
-    /**
61
-     * Raw response returned by server
62
-     *
63
-     * @var string
64
-     */
65
-    protected $responseBody = '';
66
-
67
-    /**
68
-     * Headers returned in the response
69
-     *
70
-     * @var array
71
-     */
72
-    protected $responseHeader = [];
73
-
74
-    /**
75
-     * Response HTTP status code
76
-     *
77
-     * @var int
78
-     */
79
-    protected $responseHttpCode = 0;
80
-
81
-    /**
82
-     * Last curl error number
83
-     *
84
-     * @var mixed
85
-     */
86
-    protected $responseClientError = null;
87
-
88
-    /**
89
-     * Information about the last transfer
90
-     *
91
-     * @var mixed
92
-     */
93
-    protected $responseClientInfo = [];
94
-
95
-    /**
96
-     * Hybridauth logger instance
97
-     *
98
-     * @var object
99
-     */
100
-    protected $logger = null;
101
-
102
-    /**
103
-     * {@inheritdoc}
104
-     */
105
-    public function request($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
106
-    {
107
-        $this->requestHeader = array_replace($this->requestHeader, (array)$headers);
108
-
109
-        $this->requestArguments = [
110
-            'uri' => $uri,
111
-            'method' => $method,
112
-            'parameters' => $parameters,
113
-            'headers' => $this->requestHeader,
114
-        ];
115
-
116
-        $curl = curl_init();
117
-
118
-        switch ($method) {
119
-            case 'GET':
120
-            case 'DELETE':
121
-                unset($this->curlOptions[CURLOPT_POST]);
122
-                unset($this->curlOptions[CURLOPT_POSTFIELDS]);
123
-
124
-                $uri = $uri . (strpos($uri, '?') ? '&' : '?') . http_build_query($parameters);
125
-                if ($method === 'DELETE') {
126
-                    $this->curlOptions[CURLOPT_CUSTOMREQUEST] = 'DELETE';
127
-                }
128
-                break;
129
-            case 'PUT':
130
-            case 'POST':
131
-            case 'PATCH':
132
-                $body_content = $multipart ? $parameters : http_build_query($parameters);
133
-                if (isset($this->requestHeader['Content-Type'])
134
-                    && $this->requestHeader['Content-Type'] == 'application/json'
135
-                ) {
136
-                    $body_content = json_encode($parameters);
137
-                }
138
-
139
-                if ($method === 'POST') {
140
-                    $this->curlOptions[CURLOPT_POST] = true;
141
-                } else {
142
-                    $this->curlOptions[CURLOPT_CUSTOMREQUEST] = $method;
143
-                }
144
-                $this->curlOptions[CURLOPT_POSTFIELDS] = $body_content;
145
-                break;
146
-        }
147
-
148
-        $this->curlOptions[CURLOPT_URL] = $uri;
149
-        $this->curlOptions[CURLOPT_HTTPHEADER] = $this->prepareRequestHeaders();
150
-        $this->curlOptions[CURLOPT_HEADERFUNCTION] = [$this, 'fetchResponseHeader'];
151
-
152
-        foreach ($this->curlOptions as $opt => $value) {
153
-            curl_setopt($curl, $opt, $value);
154
-        }
155
-
156
-        $response = curl_exec($curl);
157
-
158
-        $this->responseBody = $response;
159
-        $this->responseHttpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
160
-        $this->responseClientError = curl_error($curl);
161
-        $this->responseClientInfo = curl_getinfo($curl);
162
-
163
-        if ($this->logger) {
164
-            // phpcs:ignore
165
-            $this->logger->debug(sprintf('%s::request( %s, %s ), response:', get_class($this), $uri, $method), $this->getResponse());
166
-
167
-            if (false === $response) {
168
-                // phpcs:ignore
169
-                $this->logger->error(sprintf('%s::request( %s, %s ), error:', get_class($this), $uri, $method), [$this->responseClientError]);
170
-            }
171
-        }
172
-
173
-        curl_close($curl);
174
-
175
-        return $this->responseBody;
176
-    }
177
-
178
-    /**
179
-     * Get response details
180
-     *
181
-     * @return array Map structure of details
182
-     */
183
-    public function getResponse()
184
-    {
185
-        $curlOptions = $this->curlOptions;
186
-
187
-        $curlOptions[CURLOPT_HEADERFUNCTION] = '*omitted';
188
-
189
-        return [
190
-            'request' => $this->getRequestArguments(),
191
-            'response' => [
192
-                'code' => $this->getResponseHttpCode(),
193
-                'headers' => $this->getResponseHeader(),
194
-                'body' => $this->getResponseBody(),
195
-            ],
196
-            'client' => [
197
-                'error' => $this->getResponseClientError(),
198
-                'info' => $this->getResponseClientInfo(),
199
-                'opts' => $curlOptions,
200
-            ],
201
-        ];
202
-    }
203
-
204
-    /**
205
-     * Reset curl options
206
-     *
207
-     * @param array $curlOptions
208
-     */
209
-    public function setCurlOptions($curlOptions)
210
-    {
211
-        foreach ($curlOptions as $opt => $value) {
212
-            $this->curlOptions[$opt] = $value;
213
-        }
214
-    }
215
-
216
-    /**
217
-     * Set logger instance
218
-     *
219
-     * @param object $logger
220
-     */
221
-    public function setLogger($logger)
222
-    {
223
-        $this->logger = $logger;
224
-    }
225
-
226
-    /**
227
-     * {@inheritdoc}
228
-     */
229
-    public function getResponseBody()
230
-    {
231
-        return $this->responseBody;
232
-    }
233
-
234
-    /**
235
-     * {@inheritdoc}
236
-     */
237
-    public function getResponseHeader()
238
-    {
239
-        return $this->responseHeader;
240
-    }
241
-
242
-    /**
243
-     * {@inheritdoc}
244
-     */
245
-    public function getResponseHttpCode()
246
-    {
247
-        return $this->responseHttpCode;
248
-    }
249
-
250
-    /**
251
-     * {@inheritdoc}
252
-     */
253
-    public function getResponseClientError()
254
-    {
255
-        return $this->responseClientError;
256
-    }
257
-
258
-    /**
259
-     * @return array
260
-     */
261
-    protected function getResponseClientInfo()
262
-    {
263
-        return $this->responseClientInfo;
264
-    }
265
-
266
-    /**
267
-     * Returns method request() arguments
268
-     *
269
-     * This is used for debugging.
270
-     *
271
-     * @return array
272
-     */
273
-    protected function getRequestArguments()
274
-    {
275
-        return $this->requestArguments;
276
-    }
277
-
278
-    /**
279
-     * Fetch server response headers
280
-     *
281
-     * @param mixed $curl
282
-     * @param string $header
283
-     *
284
-     * @return int
285
-     */
286
-    protected function fetchResponseHeader($curl, $header)
287
-    {
288
-        $pos = strpos($header, ':');
289
-
290
-        if (!empty($pos)) {
291
-            $key = str_replace('-', '_', strtolower(substr($header, 0, $pos)));
292
-
293
-            $value = trim(substr($header, $pos + 2));
294
-
295
-            $this->responseHeader[$key] = $value;
296
-        }
297
-
298
-        return strlen($header);
299
-    }
300
-
301
-    /**
302
-     * Convert request headers to the expect curl format
303
-     *
304
-     * @return array
305
-     */
306
-    protected function prepareRequestHeaders()
307
-    {
308
-        $headers = [];
309
-
310
-        foreach ($this->requestHeader as $header => $value) {
311
-            $headers[] = trim($header) . ': ' . trim($value);
312
-        }
313
-
314
-        return $headers;
315
-    }
15
+	/**
16
+	 * Default curl options
17
+	 *
18
+	 * These defaults options can be overwritten when sending requests.
19
+	 *
20
+	 * See setCurlOptions()
21
+	 *
22
+	 * @var array
23
+	 */
24
+	protected $curlOptions = [
25
+		CURLOPT_TIMEOUT => 30,
26
+		CURLOPT_CONNECTTIMEOUT => 30,
27
+		CURLOPT_SSL_VERIFYPEER => false,
28
+		CURLOPT_SSL_VERIFYHOST => false,
29
+		CURLOPT_RETURNTRANSFER => true,
30
+		CURLOPT_FOLLOWLOCATION => true,
31
+		CURLOPT_MAXREDIRS => 5,
32
+		CURLINFO_HEADER_OUT => true,
33
+		CURLOPT_ENCODING => 'identity',
34
+		// phpcs:ignore
35
+		CURLOPT_USERAGENT => 'Hybridauth, PHP Social Authentication Library (https://github.com/hybridauth/hybridauth)',
36
+	];
37
+
38
+	/**
39
+	 * Method request() arguments
40
+	 *
41
+	 * This is used for debugging.
42
+	 *
43
+	 * @var array
44
+	 */
45
+	protected $requestArguments = [];
46
+
47
+	/**
48
+	 * Default request headers
49
+	 *
50
+	 * @var array
51
+	 */
52
+	protected $requestHeader = [
53
+		'Accept' => '*/*',
54
+		'Cache-Control' => 'max-age=0',
55
+		'Connection' => 'keep-alive',
56
+		'Expect' => '',
57
+		'Pragma' => '',
58
+	];
59
+
60
+	/**
61
+	 * Raw response returned by server
62
+	 *
63
+	 * @var string
64
+	 */
65
+	protected $responseBody = '';
66
+
67
+	/**
68
+	 * Headers returned in the response
69
+	 *
70
+	 * @var array
71
+	 */
72
+	protected $responseHeader = [];
73
+
74
+	/**
75
+	 * Response HTTP status code
76
+	 *
77
+	 * @var int
78
+	 */
79
+	protected $responseHttpCode = 0;
80
+
81
+	/**
82
+	 * Last curl error number
83
+	 *
84
+	 * @var mixed
85
+	 */
86
+	protected $responseClientError = null;
87
+
88
+	/**
89
+	 * Information about the last transfer
90
+	 *
91
+	 * @var mixed
92
+	 */
93
+	protected $responseClientInfo = [];
94
+
95
+	/**
96
+	 * Hybridauth logger instance
97
+	 *
98
+	 * @var object
99
+	 */
100
+	protected $logger = null;
101
+
102
+	/**
103
+	 * {@inheritdoc}
104
+	 */
105
+	public function request($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
106
+	{
107
+		$this->requestHeader = array_replace($this->requestHeader, (array)$headers);
108
+
109
+		$this->requestArguments = [
110
+			'uri' => $uri,
111
+			'method' => $method,
112
+			'parameters' => $parameters,
113
+			'headers' => $this->requestHeader,
114
+		];
115
+
116
+		$curl = curl_init();
117
+
118
+		switch ($method) {
119
+			case 'GET':
120
+			case 'DELETE':
121
+				unset($this->curlOptions[CURLOPT_POST]);
122
+				unset($this->curlOptions[CURLOPT_POSTFIELDS]);
123
+
124
+				$uri = $uri . (strpos($uri, '?') ? '&' : '?') . http_build_query($parameters);
125
+				if ($method === 'DELETE') {
126
+					$this->curlOptions[CURLOPT_CUSTOMREQUEST] = 'DELETE';
127
+				}
128
+				break;
129
+			case 'PUT':
130
+			case 'POST':
131
+			case 'PATCH':
132
+				$body_content = $multipart ? $parameters : http_build_query($parameters);
133
+				if (isset($this->requestHeader['Content-Type'])
134
+					&& $this->requestHeader['Content-Type'] == 'application/json'
135
+				) {
136
+					$body_content = json_encode($parameters);
137
+				}
138
+
139
+				if ($method === 'POST') {
140
+					$this->curlOptions[CURLOPT_POST] = true;
141
+				} else {
142
+					$this->curlOptions[CURLOPT_CUSTOMREQUEST] = $method;
143
+				}
144
+				$this->curlOptions[CURLOPT_POSTFIELDS] = $body_content;
145
+				break;
146
+		}
147
+
148
+		$this->curlOptions[CURLOPT_URL] = $uri;
149
+		$this->curlOptions[CURLOPT_HTTPHEADER] = $this->prepareRequestHeaders();
150
+		$this->curlOptions[CURLOPT_HEADERFUNCTION] = [$this, 'fetchResponseHeader'];
151
+
152
+		foreach ($this->curlOptions as $opt => $value) {
153
+			curl_setopt($curl, $opt, $value);
154
+		}
155
+
156
+		$response = curl_exec($curl);
157
+
158
+		$this->responseBody = $response;
159
+		$this->responseHttpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
160
+		$this->responseClientError = curl_error($curl);
161
+		$this->responseClientInfo = curl_getinfo($curl);
162
+
163
+		if ($this->logger) {
164
+			// phpcs:ignore
165
+			$this->logger->debug(sprintf('%s::request( %s, %s ), response:', get_class($this), $uri, $method), $this->getResponse());
166
+
167
+			if (false === $response) {
168
+				// phpcs:ignore
169
+				$this->logger->error(sprintf('%s::request( %s, %s ), error:', get_class($this), $uri, $method), [$this->responseClientError]);
170
+			}
171
+		}
172
+
173
+		curl_close($curl);
174
+
175
+		return $this->responseBody;
176
+	}
177
+
178
+	/**
179
+	 * Get response details
180
+	 *
181
+	 * @return array Map structure of details
182
+	 */
183
+	public function getResponse()
184
+	{
185
+		$curlOptions = $this->curlOptions;
186
+
187
+		$curlOptions[CURLOPT_HEADERFUNCTION] = '*omitted';
188
+
189
+		return [
190
+			'request' => $this->getRequestArguments(),
191
+			'response' => [
192
+				'code' => $this->getResponseHttpCode(),
193
+				'headers' => $this->getResponseHeader(),
194
+				'body' => $this->getResponseBody(),
195
+			],
196
+			'client' => [
197
+				'error' => $this->getResponseClientError(),
198
+				'info' => $this->getResponseClientInfo(),
199
+				'opts' => $curlOptions,
200
+			],
201
+		];
202
+	}
203
+
204
+	/**
205
+	 * Reset curl options
206
+	 *
207
+	 * @param array $curlOptions
208
+	 */
209
+	public function setCurlOptions($curlOptions)
210
+	{
211
+		foreach ($curlOptions as $opt => $value) {
212
+			$this->curlOptions[$opt] = $value;
213
+		}
214
+	}
215
+
216
+	/**
217
+	 * Set logger instance
218
+	 *
219
+	 * @param object $logger
220
+	 */
221
+	public function setLogger($logger)
222
+	{
223
+		$this->logger = $logger;
224
+	}
225
+
226
+	/**
227
+	 * {@inheritdoc}
228
+	 */
229
+	public function getResponseBody()
230
+	{
231
+		return $this->responseBody;
232
+	}
233
+
234
+	/**
235
+	 * {@inheritdoc}
236
+	 */
237
+	public function getResponseHeader()
238
+	{
239
+		return $this->responseHeader;
240
+	}
241
+
242
+	/**
243
+	 * {@inheritdoc}
244
+	 */
245
+	public function getResponseHttpCode()
246
+	{
247
+		return $this->responseHttpCode;
248
+	}
249
+
250
+	/**
251
+	 * {@inheritdoc}
252
+	 */
253
+	public function getResponseClientError()
254
+	{
255
+		return $this->responseClientError;
256
+	}
257
+
258
+	/**
259
+	 * @return array
260
+	 */
261
+	protected function getResponseClientInfo()
262
+	{
263
+		return $this->responseClientInfo;
264
+	}
265
+
266
+	/**
267
+	 * Returns method request() arguments
268
+	 *
269
+	 * This is used for debugging.
270
+	 *
271
+	 * @return array
272
+	 */
273
+	protected function getRequestArguments()
274
+	{
275
+		return $this->requestArguments;
276
+	}
277
+
278
+	/**
279
+	 * Fetch server response headers
280
+	 *
281
+	 * @param mixed $curl
282
+	 * @param string $header
283
+	 *
284
+	 * @return int
285
+	 */
286
+	protected function fetchResponseHeader($curl, $header)
287
+	{
288
+		$pos = strpos($header, ':');
289
+
290
+		if (!empty($pos)) {
291
+			$key = str_replace('-', '_', strtolower(substr($header, 0, $pos)));
292
+
293
+			$value = trim(substr($header, $pos + 2));
294
+
295
+			$this->responseHeader[$key] = $value;
296
+		}
297
+
298
+		return strlen($header);
299
+	}
300
+
301
+	/**
302
+	 * Convert request headers to the expect curl format
303
+	 *
304
+	 * @return array
305
+	 */
306
+	protected function prepareRequestHeaders()
307
+	{
308
+		$headers = [];
309
+
310
+		foreach ($this->requestHeader as $header => $value) {
311
+			$headers[] = trim($header) . ': ' . trim($value);
312
+		}
313
+
314
+		return $headers;
315
+	}
316 316
 }
Please login to merge, or discard this patch.
src/Adapter/OAuth1.php 1 patch
Indentation   +586 added lines, -586 removed lines patch added patch discarded remove patch
@@ -27,590 +27,590 @@
 block discarded – undo
27 27
  */
28 28
 abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
29 29
 {
30
-    /**
31
-     * Base URL to provider API
32
-     *
33
-     * This var will be used to build urls when sending signed requests
34
-     *
35
-     * @var string
36
-     */
37
-    protected $apiBaseUrl = '';
38
-
39
-    /**
40
-     * @var string
41
-     */
42
-    protected $authorizeUrl = '';
43
-
44
-    /**
45
-     * @var string
46
-     */
47
-    protected $requestTokenUrl = '';
48
-
49
-    /**
50
-     * @var string
51
-     */
52
-    protected $accessTokenUrl = '';
53
-
54
-    /**
55
-     * IPD API Documentation
56
-     *
57
-     * OPTIONAL.
58
-     *
59
-     * @var string
60
-     */
61
-    protected $apiDocumentation = '';
62
-
63
-    /**
64
-     * OAuth Version
65
-     *
66
-     *  '1.0' OAuth Core 1.0
67
-     * '1.0a' OAuth Core 1.0 Revision A
68
-     *
69
-     * @var string
70
-     */
71
-    protected $oauth1Version = '1.0a';
72
-
73
-    /**
74
-     * @var string
75
-     */
76
-    protected $consumerKey = null;
77
-
78
-    /**
79
-     * @var string
80
-     */
81
-    protected $consumerSecret = null;
82
-
83
-    /**
84
-     * @var object
85
-     */
86
-    protected $OAuthConsumer = null;
87
-
88
-    /**
89
-     * @var object
90
-     */
91
-    protected $sha1Method = null;
92
-
93
-    /**
94
-     * @var object
95
-     */
96
-    protected $consumerToken = null;
97
-
98
-    /**
99
-     * Authorization Url Parameters
100
-     *
101
-     * @var bool
102
-     */
103
-    protected $AuthorizeUrlParameters = [];
104
-
105
-    /**
106
-     * @var string
107
-     */
108
-    protected $requestTokenMethod = 'POST';
109
-
110
-    /**
111
-     * @var array
112
-     */
113
-    protected $requestTokenParameters = [];
114
-
115
-    /**
116
-     * @var array
117
-     */
118
-    protected $requestTokenHeaders = [];
119
-
120
-    /**
121
-     * @var string
122
-     */
123
-    protected $tokenExchangeMethod = 'POST';
124
-
125
-    /**
126
-     * @var array
127
-     */
128
-    protected $tokenExchangeParameters = [];
129
-
130
-    /**
131
-     * @var array
132
-     */
133
-    protected $tokenExchangeHeaders = [];
134
-
135
-    /**
136
-     * @var array
137
-     */
138
-    protected $apiRequestParameters = [];
139
-
140
-    /**
141
-     * @var array
142
-     */
143
-    protected $apiRequestHeaders = [];
144
-
145
-    /**
146
-     * {@inheritdoc}
147
-     */
148
-    protected function configure()
149
-    {
150
-        $this->consumerKey = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
151
-        $this->consumerSecret = $this->config->filter('keys')->get('secret');
152
-
153
-        if (!$this->consumerKey || !$this->consumerSecret) {
154
-            throw new InvalidApplicationCredentialsException(
155
-                'Your application id is required in order to connect to ' . $this->providerId
156
-            );
157
-        }
158
-
159
-        if ($this->config->exists('tokens')) {
160
-            $this->setAccessToken($this->config->get('tokens'));
161
-        }
162
-
163
-        $this->setCallback($this->config->get('callback'));
164
-        $this->setApiEndpoints($this->config->get('endpoints'));
165
-    }
166
-
167
-    /**
168
-     * {@inheritdoc}
169
-     */
170
-    protected function initialize()
171
-    {
172
-        /**
173
-         * Set up OAuth Signature and Consumer
174
-         *
175
-         * OAuth Core: All Token requests and Protected Resources requests MUST be signed
176
-         * by the Consumer and verified by the Service Provider.
177
-         *
178
-         * The protocol defines three signature methods: HMAC-SHA1, RSA-SHA1, and PLAINTEXT..
179
-         *
180
-         * The Consumer declares a signature method in the oauth_signature_method parameter..
181
-         *
182
-         * http://oauth.net/core/1.0a/#signing_process
183
-         */
184
-        $this->sha1Method = new OAuthSignatureMethodHMACSHA1();
185
-
186
-        $this->OAuthConsumer = new OAuthConsumer(
187
-            $this->consumerKey,
188
-            $this->consumerSecret
189
-        );
190
-
191
-        if ($this->getStoredData('request_token')) {
192
-            $this->consumerToken = new OAuthConsumer(
193
-                $this->getStoredData('request_token'),
194
-                $this->getStoredData('request_token_secret')
195
-            );
196
-        }
197
-
198
-        if ($this->getStoredData('access_token')) {
199
-            $this->consumerToken = new OAuthConsumer(
200
-                $this->getStoredData('access_token'),
201
-                $this->getStoredData('access_token_secret')
202
-            );
203
-        }
204
-    }
205
-
206
-    /**
207
-     * {@inheritdoc}
208
-     */
209
-    public function authenticate()
210
-    {
211
-        $this->logger->info(sprintf('%s::authenticate()', get_class($this)));
212
-
213
-        if ($this->isConnected()) {
214
-            return true;
215
-        }
216
-
217
-        try {
218
-            if (!$this->getStoredData('request_token')) {
219
-                // Start a new flow.
220
-                $this->authenticateBegin();
221
-            } elseif (empty($_GET['oauth_token']) && empty($_GET['denied'])) {
222
-                // A previous authentication was not finished, and this request is not finishing it.
223
-                $this->authenticateBegin();
224
-            } else {
225
-                // Finish a flow.
226
-                $this->authenticateFinish();
227
-            }
228
-        } catch (Exception $exception) {
229
-            $this->clearStoredData();
230
-
231
-            throw $exception;
232
-        }
233
-
234
-        return null;
235
-    }
236
-
237
-    /**
238
-     * {@inheritdoc}
239
-     */
240
-    public function isConnected()
241
-    {
242
-        return (bool)$this->getStoredData('access_token');
243
-    }
244
-
245
-    /**
246
-     * Initiate the authorization protocol
247
-     *
248
-     * 1. Obtaining an Unauthorized Request Token
249
-     * 2. Build Authorization URL for Authorization Request and redirect the user-agent to the
250
-     *    Authorization Server.
251
-     */
252
-    protected function authenticateBegin()
253
-    {
254
-        $response = $this->requestAuthToken();
255
-
256
-        $this->validateAuthTokenRequest($response);
257
-
258
-        $authUrl = $this->getAuthorizeUrl();
259
-
260
-        $this->logger->debug(sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)), [$authUrl]);
261
-
262
-        HttpClient\Util::redirect($authUrl);
263
-    }
264
-
265
-    /**
266
-     * Finalize the authorization process
267
-     *
268
-     * @throws AuthorizationDeniedException
269
-     * @throws \Hybridauth\Exception\HttpClientFailureException
270
-     * @throws \Hybridauth\Exception\HttpRequestFailedException
271
-     * @throws InvalidAccessTokenException
272
-     * @throws InvalidOauthTokenException
273
-     */
274
-    protected function authenticateFinish()
275
-    {
276
-        $this->logger->debug(
277
-            sprintf('%s::authenticateFinish(), callback url:', get_class($this)),
278
-            [HttpClient\Util::getCurrentUrl(true)]
279
-        );
280
-
281
-        $denied = filter_input(INPUT_GET, 'denied');
282
-        $oauth_problem = filter_input(INPUT_GET, 'oauth_problem');
283
-        $oauth_token = filter_input(INPUT_GET, 'oauth_token');
284
-        $oauth_verifier = filter_input(INPUT_GET, 'oauth_verifier');
285
-
286
-        if ($denied) {
287
-            throw new AuthorizationDeniedException(
288
-                'User denied access request. Provider returned a denied token: ' . htmlentities($denied)
289
-            );
290
-        }
291
-
292
-        if ($oauth_problem) {
293
-            throw new InvalidOauthTokenException(
294
-                'Provider returned an error. oauth_problem: ' . htmlentities($oauth_problem)
295
-            );
296
-        }
297
-
298
-        if (!$oauth_token) {
299
-            throw new InvalidOauthTokenException(
300
-                'Expecting a non-null oauth_token to continue the authorization flow.'
301
-            );
302
-        }
303
-
304
-        $response = $this->exchangeAuthTokenForAccessToken($oauth_token, $oauth_verifier);
305
-
306
-        $this->validateAccessTokenExchange($response);
307
-
308
-        $this->initialize();
309
-    }
310
-
311
-    /**
312
-     * Build Authorization URL for Authorization Request
313
-     *
314
-     * @param array $parameters
315
-     *
316
-     * @return string
317
-     */
318
-    protected function getAuthorizeUrl($parameters = [])
319
-    {
320
-        $this->AuthorizeUrlParameters = !empty($parameters)
321
-            ? $parameters
322
-            : array_replace(
323
-                (array)$this->AuthorizeUrlParameters,
324
-                (array)$this->config->get('authorize_url_parameters')
325
-            );
326
-
327
-        $this->AuthorizeUrlParameters['oauth_token'] = $this->getStoredData('request_token');
328
-
329
-        return $this->authorizeUrl . '?' . http_build_query($this->AuthorizeUrlParameters, '', '&');
330
-    }
331
-
332
-    /**
333
-     * Unauthorized Request Token
334
-     *
335
-     * OAuth Core: The Consumer obtains an unauthorized Request Token by asking the Service Provider
336
-     * to issue a Token. The Request Token's sole purpose is to receive User approval and can only
337
-     * be used to obtain an Access Token.
338
-     *
339
-     * http://oauth.net/core/1.0/#auth_step1
340
-     * 6.1.1. Consumer Obtains a Request Token
341
-     *
342
-     * @return string Raw Provider API response
343
-     * @throws \Hybridauth\Exception\HttpClientFailureException
344
-     * @throws \Hybridauth\Exception\HttpRequestFailedException
345
-     */
346
-    protected function requestAuthToken()
347
-    {
348
-        /**
349
-         * OAuth Core 1.0 Revision A: oauth_callback: An absolute URL to which the Service Provider will redirect
350
-         * the User back when the Obtaining User Authorization step is completed.
351
-         *
352
-         * http://oauth.net/core/1.0a/#auth_step1
353
-         */
354
-        if ('1.0a' == $this->oauth1Version) {
355
-            $this->requestTokenParameters['oauth_callback'] = $this->callback;
356
-        }
357
-
358
-        $response = $this->oauthRequest(
359
-            $this->requestTokenUrl,
360
-            $this->requestTokenMethod,
361
-            $this->requestTokenParameters,
362
-            $this->requestTokenHeaders
363
-        );
364
-
365
-        return $response;
366
-    }
367
-
368
-    /**
369
-     * Validate Unauthorized Request Token Response
370
-     *
371
-     * OAuth Core: The Service Provider verifies the signature and Consumer Key. If successful,
372
-     * it generates a Request Token and Token Secret and returns them to the Consumer in the HTTP
373
-     * response body.
374
-     *
375
-     * http://oauth.net/core/1.0/#auth_step1
376
-     * 6.1.2. Service Provider Issues an Unauthorized Request Token
377
-     *
378
-     * @param string $response
379
-     *
380
-     * @return \Hybridauth\Data\Collection
381
-     * @throws InvalidOauthTokenException
382
-     */
383
-    protected function validateAuthTokenRequest($response)
384
-    {
385
-        /**
386
-         * The response contains the following parameters:
387
-         *
388
-         *    - oauth_token               The Request Token.
389
-         *    - oauth_token_secret        The Token Secret.
390
-         *    - oauth_callback_confirmed  MUST be present and set to true.
391
-         *
392
-         * http://oauth.net/core/1.0/#auth_step1
393
-         * 6.1.2. Service Provider Issues an Unauthorized Request Token
394
-         *
395
-         * Example of a successful response:
396
-         *
397
-         *  HTTP/1.1 200 OK
398
-         *  Content-Type: text/html; charset=utf-8
399
-         *  Cache-Control: no-store
400
-         *  Pragma: no-cache
401
-         *
402
-         *  oauth_token=80359084-clg1DEtxQF3wstTcyUdHF3wsdHM&oauth_token_secret=OIF07hPmJB:P
403
-         *  6qiHTi1znz6qiH3tTcyUdHnz6qiH3tTcyUdH3xW3wsDvV08e&example_parameter=example_value
404
-         *
405
-         * OAuthUtil::parse_parameters will attempt to decode the raw response into an array.
406
-         */
407
-        $tokens = OAuthUtil::parse_parameters($response);
408
-
409
-        $collection = new Data\Collection($tokens);
410
-
411
-        if (!$collection->exists('oauth_token')) {
412
-            throw new InvalidOauthTokenException(
413
-                'Provider returned no oauth_token: ' . htmlentities($response)
414
-            );
415
-        }
416
-
417
-        $this->consumerToken = new OAuthConsumer(
418
-            $tokens['oauth_token'],
419
-            $tokens['oauth_token_secret']
420
-        );
421
-
422
-        $this->storeData('request_token', $tokens['oauth_token']);
423
-        $this->storeData('request_token_secret', $tokens['oauth_token_secret']);
424
-
425
-        return $collection;
426
-    }
427
-
428
-    /**
429
-     * Requests an Access Token
430
-     *
431
-     * OAuth Core: The Request Token and Token Secret MUST be exchanged for an Access Token and Token Secret.
432
-     *
433
-     * http://oauth.net/core/1.0a/#auth_step3
434
-     * 6.3.1. Consumer Requests an Access Token
435
-     *
436
-     * @param string $oauth_token
437
-     * @param string $oauth_verifier
438
-     *
439
-     * @return string Raw Provider API response
440
-     * @throws \Hybridauth\Exception\HttpClientFailureException
441
-     * @throws \Hybridauth\Exception\HttpRequestFailedException
442
-     */
443
-    protected function exchangeAuthTokenForAccessToken($oauth_token, $oauth_verifier = '')
444
-    {
445
-        $this->tokenExchangeParameters['oauth_token'] = $oauth_token;
446
-
447
-        /**
448
-         * OAuth Core 1.0 Revision A: oauth_verifier: The verification code received from the Service Provider
449
-         * in the "Service Provider Directs the User Back to the Consumer" step.
450
-         *
451
-         * http://oauth.net/core/1.0a/#auth_step3
452
-         */
453
-        if ('1.0a' == $this->oauth1Version) {
454
-            $this->tokenExchangeParameters['oauth_verifier'] = $oauth_verifier;
455
-        }
456
-
457
-        $response = $this->oauthRequest(
458
-            $this->accessTokenUrl,
459
-            $this->tokenExchangeMethod,
460
-            $this->tokenExchangeParameters,
461
-            $this->tokenExchangeHeaders
462
-        );
463
-
464
-        return $response;
465
-    }
466
-
467
-    /**
468
-     * Validate Access Token Response
469
-     *
470
-     * OAuth Core: If successful, the Service Provider generates an Access Token and Token Secret and returns
471
-     * them in the HTTP response body.
472
-     *
473
-     * The Access Token and Token Secret are stored by the Consumer and used when signing Protected Resources requests.
474
-     *
475
-     * http://oauth.net/core/1.0a/#auth_step3
476
-     * 6.3.2. Service Provider Grants an Access Token
477
-     *
478
-     * @param string $response
479
-     *
480
-     * @return \Hybridauth\Data\Collection
481
-     * @throws InvalidAccessTokenException
482
-     */
483
-    protected function validateAccessTokenExchange($response)
484
-    {
485
-        /**
486
-         * The response contains the following parameters:
487
-         *
488
-         *    - oauth_token         The Access Token.
489
-         *    - oauth_token_secret  The Token Secret.
490
-         *
491
-         * http://oauth.net/core/1.0/#auth_step3
492
-         * 6.3.2. Service Provider Grants an Access Token
493
-         *
494
-         * Example of a successful response:
495
-         *
496
-         *  HTTP/1.1 200 OK
497
-         *  Content-Type: text/html; charset=utf-8
498
-         *  Cache-Control: no-store
499
-         *  Pragma: no-cache
500
-         *
501
-         *  oauth_token=sHeLU7Far428zj8PzlWR75&oauth_token_secret=fXb30rzoG&oauth_callback_confirmed=true
502
-         *
503
-         * OAuthUtil::parse_parameters will attempt to decode the raw response into an array.
504
-         */
505
-        $tokens = OAuthUtil::parse_parameters($response);
506
-
507
-        $collection = new Data\Collection($tokens);
508
-
509
-        if (!$collection->exists('oauth_token')) {
510
-            throw new InvalidAccessTokenException(
511
-                'Provider returned no access_token: ' . htmlentities($response)
512
-            );
513
-        }
514
-
515
-        $this->consumerToken = new OAuthConsumer(
516
-            $collection->get('oauth_token'),
517
-            $collection->get('oauth_token_secret')
518
-        );
519
-
520
-        $this->storeData('access_token', $collection->get('oauth_token'));
521
-        $this->storeData('access_token_secret', $collection->get('oauth_token_secret'));
522
-
523
-        $this->deleteStoredData('request_token');
524
-        $this->deleteStoredData('request_token_secret');
525
-
526
-        return $collection;
527
-    }
528
-
529
-    /**
530
-     * Send a signed request to provider API
531
-     *
532
-     * Note: Since the specifics of error responses is beyond the scope of RFC6749 and OAuth specifications,
533
-     * Hybridauth will consider any HTTP status code that is different than '200 OK' as an ERROR.
534
-     *
535
-     * @param string $url
536
-     * @param string $method
537
-     * @param array $parameters
538
-     * @param array $headers
539
-     * @param bool $multipart
540
-     *
541
-     * @return mixed
542
-     * @throws \Hybridauth\Exception\HttpClientFailureException
543
-     * @throws \Hybridauth\Exception\HttpRequestFailedException
544
-     */
545
-    public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
546
-    {
547
-        // refresh tokens if needed
548
-        $this->maintainToken();
549
-
550
-        if (strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0) {
551
-            $url = rtrim($this->apiBaseUrl, '/') . '/' . ltrim($url, '/');
552
-        }
553
-
554
-        $parameters = array_replace($this->apiRequestParameters, (array)$parameters);
555
-
556
-        $headers = array_replace($this->apiRequestHeaders, (array)$headers);
557
-
558
-        $response = $this->oauthRequest($url, $method, $parameters, $headers, $multipart);
559
-
560
-        $response = (new Data\Parser())->parse($response);
561
-
562
-        return $response;
563
-    }
564
-
565
-    /**
566
-     * Setup and Send a Signed Oauth Request
567
-     *
568
-     * This method uses OAuth Library.
569
-     *
570
-     * @param string $uri
571
-     * @param string $method
572
-     * @param array $parameters
573
-     * @param array $headers
574
-     * @param bool $multipart
575
-     *
576
-     * @return string Raw Provider API response
577
-     * @throws \Hybridauth\Exception\HttpClientFailureException
578
-     * @throws \Hybridauth\Exception\HttpRequestFailedException
579
-     */
580
-    protected function oauthRequest($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
581
-    {
582
-        $signing_parameters = $parameters;
583
-        if ($multipart) {
584
-            $signing_parameters = [];
585
-        }
586
-
587
-        $request = OAuthRequest::from_consumer_and_token(
588
-            $this->OAuthConsumer,
589
-            $this->consumerToken,
590
-            $method,
591
-            $uri,
592
-            $signing_parameters
593
-        );
594
-
595
-        $request->sign_request(
596
-            $this->sha1Method,
597
-            $this->OAuthConsumer,
598
-            $this->consumerToken
599
-        );
600
-
601
-        $uri = $request->get_normalized_http_url();
602
-        $headers = array_replace($request->to_header(), (array)$headers);
603
-
604
-        $response = $this->httpClient->request(
605
-            $uri,
606
-            $method,
607
-            $parameters,
608
-            $headers,
609
-            $multipart
610
-        );
611
-
612
-        $this->validateApiResponse('Signed API request to ' . $uri . ' has returned an error');
613
-
614
-        return $response;
615
-    }
30
+	/**
31
+	 * Base URL to provider API
32
+	 *
33
+	 * This var will be used to build urls when sending signed requests
34
+	 *
35
+	 * @var string
36
+	 */
37
+	protected $apiBaseUrl = '';
38
+
39
+	/**
40
+	 * @var string
41
+	 */
42
+	protected $authorizeUrl = '';
43
+
44
+	/**
45
+	 * @var string
46
+	 */
47
+	protected $requestTokenUrl = '';
48
+
49
+	/**
50
+	 * @var string
51
+	 */
52
+	protected $accessTokenUrl = '';
53
+
54
+	/**
55
+	 * IPD API Documentation
56
+	 *
57
+	 * OPTIONAL.
58
+	 *
59
+	 * @var string
60
+	 */
61
+	protected $apiDocumentation = '';
62
+
63
+	/**
64
+	 * OAuth Version
65
+	 *
66
+	 *  '1.0' OAuth Core 1.0
67
+	 * '1.0a' OAuth Core 1.0 Revision A
68
+	 *
69
+	 * @var string
70
+	 */
71
+	protected $oauth1Version = '1.0a';
72
+
73
+	/**
74
+	 * @var string
75
+	 */
76
+	protected $consumerKey = null;
77
+
78
+	/**
79
+	 * @var string
80
+	 */
81
+	protected $consumerSecret = null;
82
+
83
+	/**
84
+	 * @var object
85
+	 */
86
+	protected $OAuthConsumer = null;
87
+
88
+	/**
89
+	 * @var object
90
+	 */
91
+	protected $sha1Method = null;
92
+
93
+	/**
94
+	 * @var object
95
+	 */
96
+	protected $consumerToken = null;
97
+
98
+	/**
99
+	 * Authorization Url Parameters
100
+	 *
101
+	 * @var bool
102
+	 */
103
+	protected $AuthorizeUrlParameters = [];
104
+
105
+	/**
106
+	 * @var string
107
+	 */
108
+	protected $requestTokenMethod = 'POST';
109
+
110
+	/**
111
+	 * @var array
112
+	 */
113
+	protected $requestTokenParameters = [];
114
+
115
+	/**
116
+	 * @var array
117
+	 */
118
+	protected $requestTokenHeaders = [];
119
+
120
+	/**
121
+	 * @var string
122
+	 */
123
+	protected $tokenExchangeMethod = 'POST';
124
+
125
+	/**
126
+	 * @var array
127
+	 */
128
+	protected $tokenExchangeParameters = [];
129
+
130
+	/**
131
+	 * @var array
132
+	 */
133
+	protected $tokenExchangeHeaders = [];
134
+
135
+	/**
136
+	 * @var array
137
+	 */
138
+	protected $apiRequestParameters = [];
139
+
140
+	/**
141
+	 * @var array
142
+	 */
143
+	protected $apiRequestHeaders = [];
144
+
145
+	/**
146
+	 * {@inheritdoc}
147
+	 */
148
+	protected function configure()
149
+	{
150
+		$this->consumerKey = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
151
+		$this->consumerSecret = $this->config->filter('keys')->get('secret');
152
+
153
+		if (!$this->consumerKey || !$this->consumerSecret) {
154
+			throw new InvalidApplicationCredentialsException(
155
+				'Your application id is required in order to connect to ' . $this->providerId
156
+			);
157
+		}
158
+
159
+		if ($this->config->exists('tokens')) {
160
+			$this->setAccessToken($this->config->get('tokens'));
161
+		}
162
+
163
+		$this->setCallback($this->config->get('callback'));
164
+		$this->setApiEndpoints($this->config->get('endpoints'));
165
+	}
166
+
167
+	/**
168
+	 * {@inheritdoc}
169
+	 */
170
+	protected function initialize()
171
+	{
172
+		/**
173
+		 * Set up OAuth Signature and Consumer
174
+		 *
175
+		 * OAuth Core: All Token requests and Protected Resources requests MUST be signed
176
+		 * by the Consumer and verified by the Service Provider.
177
+		 *
178
+		 * The protocol defines three signature methods: HMAC-SHA1, RSA-SHA1, and PLAINTEXT..
179
+		 *
180
+		 * The Consumer declares a signature method in the oauth_signature_method parameter..
181
+		 *
182
+		 * http://oauth.net/core/1.0a/#signing_process
183
+		 */
184
+		$this->sha1Method = new OAuthSignatureMethodHMACSHA1();
185
+
186
+		$this->OAuthConsumer = new OAuthConsumer(
187
+			$this->consumerKey,
188
+			$this->consumerSecret
189
+		);
190
+
191
+		if ($this->getStoredData('request_token')) {
192
+			$this->consumerToken = new OAuthConsumer(
193
+				$this->getStoredData('request_token'),
194
+				$this->getStoredData('request_token_secret')
195
+			);
196
+		}
197
+
198
+		if ($this->getStoredData('access_token')) {
199
+			$this->consumerToken = new OAuthConsumer(
200
+				$this->getStoredData('access_token'),
201
+				$this->getStoredData('access_token_secret')
202
+			);
203
+		}
204
+	}
205
+
206
+	/**
207
+	 * {@inheritdoc}
208
+	 */
209
+	public function authenticate()
210
+	{
211
+		$this->logger->info(sprintf('%s::authenticate()', get_class($this)));
212
+
213
+		if ($this->isConnected()) {
214
+			return true;
215
+		}
216
+
217
+		try {
218
+			if (!$this->getStoredData('request_token')) {
219
+				// Start a new flow.
220
+				$this->authenticateBegin();
221
+			} elseif (empty($_GET['oauth_token']) && empty($_GET['denied'])) {
222
+				// A previous authentication was not finished, and this request is not finishing it.
223
+				$this->authenticateBegin();
224
+			} else {
225
+				// Finish a flow.
226
+				$this->authenticateFinish();
227
+			}
228
+		} catch (Exception $exception) {
229
+			$this->clearStoredData();
230
+
231
+			throw $exception;
232
+		}
233
+
234
+		return null;
235
+	}
236
+
237
+	/**
238
+	 * {@inheritdoc}
239
+	 */
240
+	public function isConnected()
241
+	{
242
+		return (bool)$this->getStoredData('access_token');
243
+	}
244
+
245
+	/**
246
+	 * Initiate the authorization protocol
247
+	 *
248
+	 * 1. Obtaining an Unauthorized Request Token
249
+	 * 2. Build Authorization URL for Authorization Request and redirect the user-agent to the
250
+	 *    Authorization Server.
251
+	 */
252
+	protected function authenticateBegin()
253
+	{
254
+		$response = $this->requestAuthToken();
255
+
256
+		$this->validateAuthTokenRequest($response);
257
+
258
+		$authUrl = $this->getAuthorizeUrl();
259
+
260
+		$this->logger->debug(sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)), [$authUrl]);
261
+
262
+		HttpClient\Util::redirect($authUrl);
263
+	}
264
+
265
+	/**
266
+	 * Finalize the authorization process
267
+	 *
268
+	 * @throws AuthorizationDeniedException
269
+	 * @throws \Hybridauth\Exception\HttpClientFailureException
270
+	 * @throws \Hybridauth\Exception\HttpRequestFailedException
271
+	 * @throws InvalidAccessTokenException
272
+	 * @throws InvalidOauthTokenException
273
+	 */
274
+	protected function authenticateFinish()
275
+	{
276
+		$this->logger->debug(
277
+			sprintf('%s::authenticateFinish(), callback url:', get_class($this)),
278
+			[HttpClient\Util::getCurrentUrl(true)]
279
+		);
280
+
281
+		$denied = filter_input(INPUT_GET, 'denied');
282
+		$oauth_problem = filter_input(INPUT_GET, 'oauth_problem');
283
+		$oauth_token = filter_input(INPUT_GET, 'oauth_token');
284
+		$oauth_verifier = filter_input(INPUT_GET, 'oauth_verifier');
285
+
286
+		if ($denied) {
287
+			throw new AuthorizationDeniedException(
288
+				'User denied access request. Provider returned a denied token: ' . htmlentities($denied)
289
+			);
290
+		}
291
+
292
+		if ($oauth_problem) {
293
+			throw new InvalidOauthTokenException(
294
+				'Provider returned an error. oauth_problem: ' . htmlentities($oauth_problem)
295
+			);
296
+		}
297
+
298
+		if (!$oauth_token) {
299
+			throw new InvalidOauthTokenException(
300
+				'Expecting a non-null oauth_token to continue the authorization flow.'
301
+			);
302
+		}
303
+
304
+		$response = $this->exchangeAuthTokenForAccessToken($oauth_token, $oauth_verifier);
305
+
306
+		$this->validateAccessTokenExchange($response);
307
+
308
+		$this->initialize();
309
+	}
310
+
311
+	/**
312
+	 * Build Authorization URL for Authorization Request
313
+	 *
314
+	 * @param array $parameters
315
+	 *
316
+	 * @return string
317
+	 */
318
+	protected function getAuthorizeUrl($parameters = [])
319
+	{
320
+		$this->AuthorizeUrlParameters = !empty($parameters)
321
+			? $parameters
322
+			: array_replace(
323
+				(array)$this->AuthorizeUrlParameters,
324
+				(array)$this->config->get('authorize_url_parameters')
325
+			);
326
+
327
+		$this->AuthorizeUrlParameters['oauth_token'] = $this->getStoredData('request_token');
328
+
329
+		return $this->authorizeUrl . '?' . http_build_query($this->AuthorizeUrlParameters, '', '&');
330
+	}
331
+
332
+	/**
333
+	 * Unauthorized Request Token
334
+	 *
335
+	 * OAuth Core: The Consumer obtains an unauthorized Request Token by asking the Service Provider
336
+	 * to issue a Token. The Request Token's sole purpose is to receive User approval and can only
337
+	 * be used to obtain an Access Token.
338
+	 *
339
+	 * http://oauth.net/core/1.0/#auth_step1
340
+	 * 6.1.1. Consumer Obtains a Request Token
341
+	 *
342
+	 * @return string Raw Provider API response
343
+	 * @throws \Hybridauth\Exception\HttpClientFailureException
344
+	 * @throws \Hybridauth\Exception\HttpRequestFailedException
345
+	 */
346
+	protected function requestAuthToken()
347
+	{
348
+		/**
349
+		 * OAuth Core 1.0 Revision A: oauth_callback: An absolute URL to which the Service Provider will redirect
350
+		 * the User back when the Obtaining User Authorization step is completed.
351
+		 *
352
+		 * http://oauth.net/core/1.0a/#auth_step1
353
+		 */
354
+		if ('1.0a' == $this->oauth1Version) {
355
+			$this->requestTokenParameters['oauth_callback'] = $this->callback;
356
+		}
357
+
358
+		$response = $this->oauthRequest(
359
+			$this->requestTokenUrl,
360
+			$this->requestTokenMethod,
361
+			$this->requestTokenParameters,
362
+			$this->requestTokenHeaders
363
+		);
364
+
365
+		return $response;
366
+	}
367
+
368
+	/**
369
+	 * Validate Unauthorized Request Token Response
370
+	 *
371
+	 * OAuth Core: The Service Provider verifies the signature and Consumer Key. If successful,
372
+	 * it generates a Request Token and Token Secret and returns them to the Consumer in the HTTP
373
+	 * response body.
374
+	 *
375
+	 * http://oauth.net/core/1.0/#auth_step1
376
+	 * 6.1.2. Service Provider Issues an Unauthorized Request Token
377
+	 *
378
+	 * @param string $response
379
+	 *
380
+	 * @return \Hybridauth\Data\Collection
381
+	 * @throws InvalidOauthTokenException
382
+	 */
383
+	protected function validateAuthTokenRequest($response)
384
+	{
385
+		/**
386
+		 * The response contains the following parameters:
387
+		 *
388
+		 *    - oauth_token               The Request Token.
389
+		 *    - oauth_token_secret        The Token Secret.
390
+		 *    - oauth_callback_confirmed  MUST be present and set to true.
391
+		 *
392
+		 * http://oauth.net/core/1.0/#auth_step1
393
+		 * 6.1.2. Service Provider Issues an Unauthorized Request Token
394
+		 *
395
+		 * Example of a successful response:
396
+		 *
397
+		 *  HTTP/1.1 200 OK
398
+		 *  Content-Type: text/html; charset=utf-8
399
+		 *  Cache-Control: no-store
400
+		 *  Pragma: no-cache
401
+		 *
402
+		 *  oauth_token=80359084-clg1DEtxQF3wstTcyUdHF3wsdHM&oauth_token_secret=OIF07hPmJB:P
403
+		 *  6qiHTi1znz6qiH3tTcyUdHnz6qiH3tTcyUdH3xW3wsDvV08e&example_parameter=example_value
404
+		 *
405
+		 * OAuthUtil::parse_parameters will attempt to decode the raw response into an array.
406
+		 */
407
+		$tokens = OAuthUtil::parse_parameters($response);
408
+
409
+		$collection = new Data\Collection($tokens);
410
+
411
+		if (!$collection->exists('oauth_token')) {
412
+			throw new InvalidOauthTokenException(
413
+				'Provider returned no oauth_token: ' . htmlentities($response)
414
+			);
415
+		}
416
+
417
+		$this->consumerToken = new OAuthConsumer(
418
+			$tokens['oauth_token'],
419
+			$tokens['oauth_token_secret']
420
+		);
421
+
422
+		$this->storeData('request_token', $tokens['oauth_token']);
423
+		$this->storeData('request_token_secret', $tokens['oauth_token_secret']);
424
+
425
+		return $collection;
426
+	}
427
+
428
+	/**
429
+	 * Requests an Access Token
430
+	 *
431
+	 * OAuth Core: The Request Token and Token Secret MUST be exchanged for an Access Token and Token Secret.
432
+	 *
433
+	 * http://oauth.net/core/1.0a/#auth_step3
434
+	 * 6.3.1. Consumer Requests an Access Token
435
+	 *
436
+	 * @param string $oauth_token
437
+	 * @param string $oauth_verifier
438
+	 *
439
+	 * @return string Raw Provider API response
440
+	 * @throws \Hybridauth\Exception\HttpClientFailureException
441
+	 * @throws \Hybridauth\Exception\HttpRequestFailedException
442
+	 */
443
+	protected function exchangeAuthTokenForAccessToken($oauth_token, $oauth_verifier = '')
444
+	{
445
+		$this->tokenExchangeParameters['oauth_token'] = $oauth_token;
446
+
447
+		/**
448
+		 * OAuth Core 1.0 Revision A: oauth_verifier: The verification code received from the Service Provider
449
+		 * in the "Service Provider Directs the User Back to the Consumer" step.
450
+		 *
451
+		 * http://oauth.net/core/1.0a/#auth_step3
452
+		 */
453
+		if ('1.0a' == $this->oauth1Version) {
454
+			$this->tokenExchangeParameters['oauth_verifier'] = $oauth_verifier;
455
+		}
456
+
457
+		$response = $this->oauthRequest(
458
+			$this->accessTokenUrl,
459
+			$this->tokenExchangeMethod,
460
+			$this->tokenExchangeParameters,
461
+			$this->tokenExchangeHeaders
462
+		);
463
+
464
+		return $response;
465
+	}
466
+
467
+	/**
468
+	 * Validate Access Token Response
469
+	 *
470
+	 * OAuth Core: If successful, the Service Provider generates an Access Token and Token Secret and returns
471
+	 * them in the HTTP response body.
472
+	 *
473
+	 * The Access Token and Token Secret are stored by the Consumer and used when signing Protected Resources requests.
474
+	 *
475
+	 * http://oauth.net/core/1.0a/#auth_step3
476
+	 * 6.3.2. Service Provider Grants an Access Token
477
+	 *
478
+	 * @param string $response
479
+	 *
480
+	 * @return \Hybridauth\Data\Collection
481
+	 * @throws InvalidAccessTokenException
482
+	 */
483
+	protected function validateAccessTokenExchange($response)
484
+	{
485
+		/**
486
+		 * The response contains the following parameters:
487
+		 *
488
+		 *    - oauth_token         The Access Token.
489
+		 *    - oauth_token_secret  The Token Secret.
490
+		 *
491
+		 * http://oauth.net/core/1.0/#auth_step3
492
+		 * 6.3.2. Service Provider Grants an Access Token
493
+		 *
494
+		 * Example of a successful response:
495
+		 *
496
+		 *  HTTP/1.1 200 OK
497
+		 *  Content-Type: text/html; charset=utf-8
498
+		 *  Cache-Control: no-store
499
+		 *  Pragma: no-cache
500
+		 *
501
+		 *  oauth_token=sHeLU7Far428zj8PzlWR75&oauth_token_secret=fXb30rzoG&oauth_callback_confirmed=true
502
+		 *
503
+		 * OAuthUtil::parse_parameters will attempt to decode the raw response into an array.
504
+		 */
505
+		$tokens = OAuthUtil::parse_parameters($response);
506
+
507
+		$collection = new Data\Collection($tokens);
508
+
509
+		if (!$collection->exists('oauth_token')) {
510
+			throw new InvalidAccessTokenException(
511
+				'Provider returned no access_token: ' . htmlentities($response)
512
+			);
513
+		}
514
+
515
+		$this->consumerToken = new OAuthConsumer(
516
+			$collection->get('oauth_token'),
517
+			$collection->get('oauth_token_secret')
518
+		);
519
+
520
+		$this->storeData('access_token', $collection->get('oauth_token'));
521
+		$this->storeData('access_token_secret', $collection->get('oauth_token_secret'));
522
+
523
+		$this->deleteStoredData('request_token');
524
+		$this->deleteStoredData('request_token_secret');
525
+
526
+		return $collection;
527
+	}
528
+
529
+	/**
530
+	 * Send a signed request to provider API
531
+	 *
532
+	 * Note: Since the specifics of error responses is beyond the scope of RFC6749 and OAuth specifications,
533
+	 * Hybridauth will consider any HTTP status code that is different than '200 OK' as an ERROR.
534
+	 *
535
+	 * @param string $url
536
+	 * @param string $method
537
+	 * @param array $parameters
538
+	 * @param array $headers
539
+	 * @param bool $multipart
540
+	 *
541
+	 * @return mixed
542
+	 * @throws \Hybridauth\Exception\HttpClientFailureException
543
+	 * @throws \Hybridauth\Exception\HttpRequestFailedException
544
+	 */
545
+	public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
546
+	{
547
+		// refresh tokens if needed
548
+		$this->maintainToken();
549
+
550
+		if (strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0) {
551
+			$url = rtrim($this->apiBaseUrl, '/') . '/' . ltrim($url, '/');
552
+		}
553
+
554
+		$parameters = array_replace($this->apiRequestParameters, (array)$parameters);
555
+
556
+		$headers = array_replace($this->apiRequestHeaders, (array)$headers);
557
+
558
+		$response = $this->oauthRequest($url, $method, $parameters, $headers, $multipart);
559
+
560
+		$response = (new Data\Parser())->parse($response);
561
+
562
+		return $response;
563
+	}
564
+
565
+	/**
566
+	 * Setup and Send a Signed Oauth Request
567
+	 *
568
+	 * This method uses OAuth Library.
569
+	 *
570
+	 * @param string $uri
571
+	 * @param string $method
572
+	 * @param array $parameters
573
+	 * @param array $headers
574
+	 * @param bool $multipart
575
+	 *
576
+	 * @return string Raw Provider API response
577
+	 * @throws \Hybridauth\Exception\HttpClientFailureException
578
+	 * @throws \Hybridauth\Exception\HttpRequestFailedException
579
+	 */
580
+	protected function oauthRequest($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
581
+	{
582
+		$signing_parameters = $parameters;
583
+		if ($multipart) {
584
+			$signing_parameters = [];
585
+		}
586
+
587
+		$request = OAuthRequest::from_consumer_and_token(
588
+			$this->OAuthConsumer,
589
+			$this->consumerToken,
590
+			$method,
591
+			$uri,
592
+			$signing_parameters
593
+		);
594
+
595
+		$request->sign_request(
596
+			$this->sha1Method,
597
+			$this->OAuthConsumer,
598
+			$this->consumerToken
599
+		);
600
+
601
+		$uri = $request->get_normalized_http_url();
602
+		$headers = array_replace($request->to_header(), (array)$headers);
603
+
604
+		$response = $this->httpClient->request(
605
+			$uri,
606
+			$method,
607
+			$parameters,
608
+			$headers,
609
+			$multipart
610
+		);
611
+
612
+		$this->validateApiResponse('Signed API request to ' . $uri . ' has returned an error');
613
+
614
+		return $response;
615
+	}
616 616
 }
Please login to merge, or discard this patch.