Test Failed
Push — master ( d9b525...db8114 )
by Mike
02:47
created

AbstractClient::getCredentials()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 3
ccs 0
cts 0
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
3
namespace SugarAPI\SDK\Client\Abstracts;
4
5
use SugarAPI\SDK\Client\Interfaces\ClientInterface;
6
use SugarAPI\SDK\Exception\EntryPoint\EntryPointException;
7
use SugarAPI\SDK\Helpers\Helpers;
8
use SugarAPI\SDK\EntryPoint\POST\OAuth2Logout;
9
use SugarAPI\SDK\EntryPoint\POST\OAuth2Token;
10
use SugarAPI\SDK\EntryPoint\POST\RefreshToken;
11
use SugarAPI\SDK\Exception\Authentication\AuthenticationException;
12
13
abstract class AbstractClient implements ClientInterface {
14
15
    /**
16
     * Array of Statically Bound Tokens for SDK Clients
17
     * - Allows for reinstating objects in multiple areas, without needing to Sign-in
18
     * - Allows for multiple client_id's to be used between SDK Clients
19
     *
20
     * @var array = array(
21
     *      $client_id => $token
22
     * )
23
     */
24
    protected static $_STORED_TOKENS = array();
25
26
27
    /**
28
     * The configured server domain name/url on the SDK Client
29
     * @var string
30
     */
31
    protected $server = '';
32
33
    /**
34
     * The API Url configured on the SDK Client
35
     * @var string
36
     */
37
    protected $apiURL = '';
38
39
    /**
40
     * The full token object returned by the Login method
41
     * @var \stdClass
42
     */
43
    protected $token;
44
45
    /**
46
     * Array of OAuth Creds to be used by SDK Client
47
     * @var array
48
     */
49
    protected $credentials = array();
50
51
    /**
52
     * Token expiration time
53
     * @var
54
     */
55
    protected $expiration;
56
57
    /**
58
     * The list of registered EntryPoints
59
     * @var array
60
     */
61
    protected $entryPoints = array();
62
63
    public function __construct($server = '',array $credentials = array()){
64
        $server = (empty($server)?$this->server:$server);
65
        if (!empty($server)) {
66
            $this->setServer($server);
67
        }
68
        $credentials = (empty($credentials)?$this->credentials:$credentials);
69
        if (!empty($credentials)){
70
            $this->setCredentials($credentials);
71
        }
72
        $this->registerSDKEntryPoints();
73
    }
74
75
    /**
76
     * @inheritdoc
77
     * @param string $server
78
     */
79
    public function setServer($server) {
80
        $this->server = $server;
81
        $this->apiURL = Helpers::configureAPIURL($this->server);
82
        return $this;
83
    }
84
85
    /**
86
     * @inheritdoc
87
     */
88
    public function getAPIUrl() {
89
        return $this->apiURL;
90
    }
91
92
    /**
93
     * @inheritdoc
94
     * Retrieves stored token based on passed in Credentials
95
     */
96
    public function setCredentials(array $credentials){
97
        $this->credentials = $credentials;
98
        $token = static::getStoredToken($this->credentials['client_id']);
99
        if (!empty($token)){
100
            $this->setToken($token);
101
        }
102
        return $this;
103
    }
104
105
    /**
106
     * @inheritdoc
107
     */
108
    public function setToken(\stdClass $token){
109
        $this->token = $token;
110
        $this->expiration = time()+$token->expires_in;
111
        return $this;
112
    }
113
114
    /**
115
     * @inheritdoc
116
     */
117
    public function getToken(){
118
        return $this->token;
119
    }
120
121
    /**
122
     * @inheritdoc
123
     */
124
    public function getCredentials(){
125
        return $this->credentials;
126
    }
127
128
    /**
129
     * @inheritdoc
130
     */
131
    public function getServer() {
132
        return $this->server;
133
    }
134
135
    /**
136
     * @inheritdoc
137
     */
138
    public function authenticated(){
139
        return time() < $this->expiration;
140
    }
141
142
    /**
143
     * Register the defined EntryPoints in SDK, located in src/EntryPoint/registry.php file
144
     * @throws EntryPointException
145
     */
146
    protected function registerSDKEntryPoints(){
147
        $entryPoints = Helpers::getSDKEntryPointRegistry();
148
        foreach ($entryPoints as $funcName => $className){
149
            $this->registerEntryPoint($funcName, $className);
150
        }
151
    }
152
153
    /**
154
     * @param $funcName
155
     * @param $className
156
     * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be AbstractClient?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
157
     * @throws EntryPointException
158
     */
159
    public function registerEntryPoint($funcName, $className){
160
        $implements = class_implements($className);
161
        if (is_array($implements) && in_array('SugarAPI\SDK\EntryPoint\Interfaces\EPInterface',$implements)){
162
            $this->entryPoints[$funcName] = $className;
163
        }else{
164
            throw new EntryPointException($className,'Class must extend SugarAPI\SDK\EntryPoint\Interfaces\EPInterface');
165
        }
166
        return $this;
167
    }
168
169
    /**
170
     * Generates the EntryPoint objects based on a Method name that was called
171
     * @param $name
172
     * @param $params
173
     * @return mixed
174
     * @throws EntryPointException
175
     */
176
    public function __call($name, $params){
177
        if (array_key_exists($name, $this->entryPoints)){
178
            $Class = $this->entryPoints[$name];
179
            $EntryPoint = new $Class($this->apiURL, $params);
180
181
            if ($EntryPoint->authRequired()){
182
                if (isset($this->token) && $this->authenticated()) {
183
                    $EntryPoint->setAuth($this->getToken()->access_token);
184
                }
185
            }
186
            return $EntryPoint;
187
        }else{
188
            throw new EntryPointException($name,'Unregistered EntryPoint');
189
        }
190
    }
191
192
    /**
193
     * @inheritdoc
194
     * @throws AuthenticationException - When Login request fails
195
     */
196 View Code Duplication
    public function login() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
197
        $EP = new OAuth2Token($this->apiURL);
198
        $response = $EP->execute($this->credentials)->getResponse();
199
        if ($response->getStatus()=='200'){
200
            $this->setToken($response->getBody(FALSE));
0 ignored issues
show
Unused Code introduced by
The call to ResponseInterface::getBody() has too many arguments starting with FALSE.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Documentation introduced by
$response->getBody(FALSE) is of type string, but the function expects a object<stdClass>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
201
            static::storeToken($this->token,$this->credentials['client_id']);
202
        } else {
203
            $error = $response->getBody();
204
            throw new AuthenticationException("Login Response [".$error['error']."] ".$error['error_message']);
205
        }
206
        return $this;
207
    }
208
209
    /**
210
     * @inheritdoc
211
     * @throws AuthenticationException - When Refresh Request fails
212
     */
213
    public function refreshToken(){
214
        $refreshOptions = array(
215
            'client_id' => $this->credentials->client_id,
216
            'client_secret' => $this->credentials->client_secret,
217
            'refresh_token' => $this->credentials->refresh_token
218
        );
219
        $EP = new RefreshToken($this->apiURL);
220
        $response = $EP->execute($refreshOptions)->getResponse();
221
        if ($response->getStatus()=='200'){
222
            $this->setToken($response->getBody(FALSE));
0 ignored issues
show
Unused Code introduced by
The call to ResponseInterface::getBody() has too many arguments starting with FALSE.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Documentation introduced by
$response->getBody(FALSE) is of type string, but the function expects a object<stdClass>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
223
            static::storeToken($this->token,$this->credentials['client_id']);
224
        }else{
225
            $error = $response->getBody();
226
            throw new AuthenticationException("Refresh Response [".$error['error']."] ".$error['error_message']);
227
        }
228
        return $this;
229
    }
230
231
    /**
232
     * @inheritdoc
233
     * @throws AuthenticationException - When logout request fails
234
     */
235 View Code Duplication
    public function logout(){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
236
        if ($this->authenticated()){
237
            $EP = new OAuth2Logout($this->apiURL);
238
            $response = $EP->execute()->getResponse();
239
            if ($response->getStatus()=='200'){
240
                unset($this->token);
241
                static::removeStoredToken($this->credentials['client_id']);
242
            }else{
243
                $error = $response->getBody();
244
                throw new AuthenticationException("Logout Response [".$error['error']."] ".$error['message']);
245
            }
246
        }
247
        return $this;
248
    }
249
250
    /**
251
     * @inheritdoc
252
     * @param \stdClass $token
253
     */
254
    public static function storeToken($token, $client_id) {
255
        static::$_STORED_TOKENS[$client_id] = $token;
256
        return TRUE;
257
    }
258
259
    /**
260
     * @inheritdoc
261
     */
262
    public static function getStoredToken($client_id) {
263
        return (isset(static::$_STORED_TOKENS[$client_id])?static::$_STORED_TOKENS[$client_id]:NULL);
264
    }
265
266
    /**
267
     * @inheritdoc
268
     */
269
    public static function removeStoredToken($client_id) {
270
        unset(static::$_STORED_TOKENS[$client_id]);
271
        return TRUE;
272
    }
273
274
}