Skip to content
This repository was archived by the owner on Jul 28, 2022. It is now read-only.

Commit b60eb8a

Browse files
committed
Adds Authentication support
Support for both Basic HTTP and OAuth added. Tests updates
1 parent b209c74 commit b60eb8a

File tree

13 files changed

+317
-148
lines changed

13 files changed

+317
-148
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ around the GitHub API v3. This is achieved using a number of methods:
1919

2020
// Setup the user, and authenticate
2121
$user = new User();
22-
$user->setCredentials('username', 'password');
22+
$user->setCredentials(new Authentication\Basic('username', 'password'));
2323
$user->login();
2424

2525
// Get the user details
@@ -96,7 +96,7 @@ Authentication can be achieved as follows.
9696
use GitHub\API\User\User;
9797

9898
$user = new User();
99-
$user->setCredentials('username', 'password');
99+
$user->setCredentials(new Authentication\Basic('username', 'password'));
100100
$user->login();
101101

102102
// Perform operations that require authentication ...

examples/user.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
$loader->register();
2121

2222

23+
use GitHub\API\Authentication;
2324
use GitHub\API\User\User;
2425
use GitHub\API\AuthenticationException;
2526

@@ -40,7 +41,7 @@
4041
* Perform operations that require authentication
4142
*/
4243
// Set user credentials and login
43-
$user->setCredentials('username', 'password');
44+
$user->setCredentials(new Authentication\Basic('username', 'password'));
4445
$user->login();
4546

4647
try

lib/GitHub/API/Api.php

+39-64
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,6 @@ class Api
4747
*/
4848
const DEFAULT_PAGE_SIZE = 30;
4949

50-
/**
51-
* Constants for authentication methods. AUTH_TYPE_OAUTH is currently not
52-
* implemented
53-
*
54-
* @link http://developer.github.com/v3/#authentication
55-
*/
56-
const AUTH_TYPE_BASIC = 'basic';
57-
const AUTH_TYPE_OAUTH = 'oauth';
58-
5950
/**
6051
* Transport layer
6152
*
@@ -72,18 +63,11 @@ class Api
7263
protected $authenticated = false;
7364

7465
/**
75-
* Authenticaton username
66+
* Authenticator to use (Basic|OAuth)
7667
*
77-
* @var string
68+
* @var AuthenticationInterface
7869
*/
79-
protected $authUsername = null;
80-
81-
/**
82-
* Authentication password
83-
*
84-
* @var string
85-
*/
86-
protected $authPassword = null;
70+
protected $authenticator = null;
8771

8872
/**
8973
* Constructor
@@ -97,20 +81,18 @@ public function __construct(Browser $transport = null)
9781
else
9882
$this->transport = $transport;
9983
}
100-
84+
10185
/**
102-
* Sets user credentials. Setting credentials does not log the user in.
103-
* A call to login() must be made aswell
86+
* Sets user credentials via an AuthenticationInterface. Setting credentials
87+
* does not log the user in. A call to login() must be made aswell
10488
*
105-
* @param string $username Username
106-
* @param string $password Password
89+
* @param AuthenticationInterface $authenticator Authenticator
10790
*/
108-
public function setCredentials($username, $password)
91+
public function setCredentials(Authentication\AuthenticationInterface $authenticator)
10992
{
110-
$this->authUsername = $username;
111-
$this->authPassword = $password;
93+
$this->authenticator = $authenticator;
11294
}
113-
95+
11496
/**
11597
* Clears credentials. Clearing credentials does not logout the user. A call
11698
* to logout() must be made first
@@ -119,8 +101,7 @@ public function clearCredentials()
119101
{
120102
if (false === $this->isAuthenticated())
121103
{
122-
$this->authUsername = '';
123-
$this->authPassword = '';
104+
$this->authenticator = null;
124105
}
125106
else
126107
throw new ApiException('You must logout before clearing credentials. Use logout() first');
@@ -132,7 +113,7 @@ public function clearCredentials()
132113
*/
133114
public function login()
134115
{
135-
if ((!strlen($this->authUsername)) || !strlen($this->authPassword))
116+
if (null === $this->authenticator)
136117
throw new ApiException('Cannot login. You must specify the credentials first. Use setCredentials()');
137118

138119
$this->authenticated = true;
@@ -177,11 +158,9 @@ public function getTransport()
177158
* @param array $params Any GET params
178159
* @return mixed API response
179160
*/
180-
public function requestGet($url, $params = array(), $options = array())
161+
public function requestGet($url, $params = array(), $headers = array())
181162
{
182-
$options = $this->applyAuthentication($options);
183-
184-
return $this->transport->get(self::API_URL . $url, $params, $options);
163+
return $this->doRequest('GET', self::API_URL . $url, $params, $headers);
185164
}
186165

187166
/**
@@ -191,13 +170,11 @@ public function requestGet($url, $params = array(), $options = array())
191170
* @param array $params Any POST params
192171
* @return mixed API response
193172
*/
194-
public function requestPost($url, $params = array(), $options = array())
173+
public function requestPost($url, $params = array(), $headers = array())
195174
{
196-
$options = $this->applyAuthentication($options);
197-
198175
$params = (count($params)) ? json_encode($params) : null;
199176

200-
return $this->transport->post(self::API_URL . $url, $params, $options);
177+
return $this->doRequest('POST', self::API_URL . $url, $params, $headers);
201178
}
202179

203180
/**
@@ -207,13 +184,11 @@ public function requestPost($url, $params = array(), $options = array())
207184
* @param array $params Any PUT params
208185
* @return mixed API response
209186
*/
210-
public function requestPut($url, $params = array(), $options = array())
187+
public function requestPut($url, $params = array(), $headers = array())
211188
{
212-
$options = $this->applyAuthentication($options);
213-
214189
$params = (count($params)) ? json_encode($params) : null;
215190

216-
return $this->transport->put(self::API_URL . $url, $params, $options);
191+
return $this->doRequest('PUT', self::API_URL . $url, $params, $headers);
217192
}
218193

219194
/**
@@ -223,13 +198,11 @@ public function requestPut($url, $params = array(), $options = array())
223198
* @param array $params Any PATCH params
224199
* @return mixed API response
225200
*/
226-
public function requestPatch($url, $params = array(), $options = array())
201+
public function requestPatch($url, $params = array(), $headers = array())
227202
{
228-
$options = $this->applyAuthentication($options);
229-
230203
$params = (count($params)) ? json_encode($params) : null;
231204

232-
return $this->transport->patch(self::API_URL . $url, $params, $options);
205+
return $this->doRequest('PATCH', self::API_URL . $url, $params, $headers);
233206
}
234207

235208
/**
@@ -239,34 +212,36 @@ public function requestPatch($url, $params = array(), $options = array())
239212
* @param array $params Any DELETE params
240213
* @return mixed API response
241214
*/
242-
public function requestDelete($url, $params = array(), $options = array())
215+
public function requestDelete($url, $params = array(), $headers = array())
243216
{
244-
$options = $this->applyAuthentication($options);
245-
246217
$params = (count($params)) ? json_encode($params) : null;
247218

248-
return $this->transport->delete(self::API_URL . $url, $params, $options);
219+
return $this->doRequest('DELETE', self::API_URL . $url, $params, $headers);
249220
}
250221

251222
/**
252-
* Check if authentication needs to be applied to requests
223+
* Perform HTTP request
253224
*
254-
* @param array $options Array of options to add auth to
255-
* @return array Updated options
225+
* @param string $method HTTP method
226+
* @param string $url Full URL including protocol
227+
* @param array $params Any params
228+
* @return mixed API response
256229
*/
257-
public function applyAuthentication($options)
230+
protected function doRequest($method, $url, $params, $headers)
258231
{
259-
if ($this->isAuthenticated())
232+
$request = $this->transport->createRequest();
233+
234+
$request->setMethod($method);
235+
$request->fromUrl($url);
236+
$request->addHeaders($headers);
237+
$request->setContent($params);
238+
239+
if ($this->isAuthenticated() && null !== $this->authenticator)
260240
{
261-
// Only supports basic auth for now
262-
$options['auth'] = array(
263-
'type' => self::AUTH_TYPE_BASIC,
264-
'username' => $this->authUsername,
265-
'password' => $this->authPassword
266-
);
241+
$request = $this->authenticator->authenticate($request);
267242
}
268-
269-
return $options;
243+
244+
return $this->transport->send($request);
270245
}
271246

272247
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace GitHub\API\Authentication;
4+
5+
interface AuthenticationInterface
6+
{
7+
public function authenticate(\Buzz\Message\Request $request);
8+
}
+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
namespace GitHub\API\Authentication;
4+
5+
/**
6+
* Basic HTTP Authentication
7+
*
8+
* @author dsyph3r <d.syph.3r@gmail.com>
9+
*/
10+
class Basic implements AuthenticationInterface
11+
{
12+
/**
13+
* Username
14+
*
15+
* @var string
16+
*/
17+
private $username;
18+
19+
/**
20+
* Password
21+
*
22+
* @var string
23+
*/
24+
private $password;
25+
26+
/**
27+
* Create with basic HTTP credentials set
28+
*
29+
* @param string $username Username
30+
* @param string $password Password
31+
*/
32+
public function __construct($username, $password)
33+
{
34+
$this->username = $username;
35+
$this->password = $password;
36+
}
37+
38+
public function getUsername()
39+
{
40+
return $this->username;
41+
}
42+
43+
public function getPassword()
44+
{
45+
return $this->password;
46+
}
47+
48+
public function setUsername($username)
49+
{
50+
$this->username = $username;
51+
}
52+
53+
public function setPassword($password)
54+
{
55+
$this->password = $password;
56+
}
57+
58+
/**
59+
* Authenticate the request object. Apply basic HTTP headers
60+
*
61+
* @param Request $request Request object to authenticate
62+
*/
63+
public function authenticate(\Buzz\Message\Request $request)
64+
{
65+
$encoded = base64_encode($this->username . ':' . $this->password);
66+
$request->addHeader('Authorization: Basic ' . $encoded);
67+
68+
return $request;
69+
}
70+
}
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace GitHub\API\Authentication;
4+
5+
/**
6+
* OAuth Authentication
7+
*
8+
* @author dsyph3r <d.syph.3r@gmail.com>
9+
*/
10+
class OAuth implements AuthenticationInterface
11+
{
12+
/**
13+
* OAuth access token
14+
*
15+
* @var string
16+
*/
17+
private $accessToken;
18+
19+
/**
20+
* Create with OAuth access token
21+
*
22+
* @param string $accessToken OAuth access token
23+
*/
24+
public function __construct($accessToken)
25+
{
26+
$this->accessToken = $accessToken;
27+
}
28+
29+
public function getToken()
30+
{
31+
return $this->accessToken;
32+
}
33+
34+
public function setToken($accessToken)
35+
{
36+
$this->accessToken = $accessToken;
37+
}
38+
39+
/**
40+
* Authenticate the request object. Apply the access_token to the URL
41+
*
42+
* TODO: implement
43+
*
44+
* @param Request $request Request object to authenticate
45+
*/
46+
public function authenticate(\Buzz\Message\Request $request)
47+
{
48+
$url = $request->getUrl();
49+
$prefix = (strpos($url, '?') > 0) ? '&' : '?';
50+
51+
$request->fromUrl($url . $prefix . 'access_token=' . $this->accessToken);
52+
53+
return $request;
54+
}
55+
}

0 commit comments

Comments
 (0)