Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickbussmann committed Jan 15, 2021
2 parents 06ef0a5 + 5598a94 commit 6702931
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 26 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ matrix:
- php: 7.0
- php: 7.1
- php: 7.2
- php: 7.3
- php: nightly
- php: hhvm-3.6
sudo: required
Expand Down Expand Up @@ -36,6 +35,8 @@ matrix:
- php: hhvm-3.12
- php: hhvm-3.15
- php: hhvm-nightly
- php: 7.3
- php: 7.4

before_script:
- travis_retry composer self-update
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ All Notable changes to `oauth2-apple` will be documented in this file
### Security
- Nothing

## 0.2.3 - 2021-01-05

### Added
- Using guzzle http instead of file_get_contents [#14](https://github.com/patrickbussmann/oauth2-apple/pull/14)/[#17](https://github.com/patrickbussmann/oauth2-apple/pull/17) (thanks to [jmalinens](https://github.com/jmalinens) and [williamxsp](https://github.com/williamxsp))
- README no scope instruction [#15](https://github.com/patrickbussmann/oauth2-apple/pull/15) (thanks to [NgSekLong](https://github.com/NgSekLong))
- README leeway usage [#18](https://github.com/patrickbussmann/oauth2-apple/issues/18) (thanks to [lukequinnell](https://github.com/lukequinnell))

### Fixed
- Fixed getting first and last name issues [#13](https://github.com/patrickbussmann/oauth2-apple/pull/13) (thanks to [bogdandovgopol](https://github.com/bogdandovgopol))

## 0.2.1 - 2020-02-13

### Added
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@ Usage is the same as The League's OAuth client, using `\League\OAuth2\Client\Pro
### Authorization Code Flow

```php
// $leeway is needed for clock skew
Firebase\JWT\JWT::$leeway = 60;

$provider = new League\OAuth2\Client\Provider\Apple([
'clientId' => '{apple-client-id}',
'teamId' => '{apple-team-id}', // 1A234BFK46 https://developer.apple.com/account/#/membership/ (Team ID)
'keyFileId' => '{apple-key-file-id}', // 1ABC6523AA https://developer.apple.com/account/resources/authkeys/list (Key ID)
'keyFilePath' => '{apple-key-file-path}', // __DIR__ . '/AuthKey_1ABC6523AA.p8' -> Download key above
'keyFilePath' => '{apple-key-file-path}', // __DIR__ . '/AuthKey_1ABC6523AA.p8' -> Download key above
'redirectUri' => 'https://example.com/callback-url',
]);

Expand Down Expand Up @@ -107,6 +110,7 @@ At the time of authoring this documentation, the following scopes are available.
Please note that you will get this informations only at the first log in of the user!
In the following log ins you'll get only the user id!

If you only want to get the user id, you can set the `scope` as ` `, then change all the `$_POST` to `$_GET`.

### Refresh Tokens

Expand All @@ -132,7 +136,7 @@ Please see [CONTRIBUTING](https://github.com/patrickbussmann/oauth2-apple/blob/m

- [All Contributors](https://github.com/patrickbussmann/oauth2-apple/contributors)

Template for this repository was the [LinkedIn](https://github.com/thephpleague/oauth2-linkedin).
Template for this repository was the [LinkedIn](https://github.com/thephpleague/oauth2-linkedin).

## License

Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
"lcobucci/jwt": "^3.4.1"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"mockery/mockery": "~0.9",
"phpunit/phpunit": "^4.8|^7.5",
"mockery/mockery": "~1.3.3",
"squizlabs/php_codesniffer": "~2.0",
"ext-json": "*"
},
Expand Down
3 changes: 0 additions & 3 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,10 @@
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
>
<logging>
<log type="coverage-html"
target="./build/coverage/html"
charset="UTF-8"
highlight="false"
lowUpperBound="35"
highLowerBound="70"/>
<log type="coverage-clover"
Expand Down
10 changes: 5 additions & 5 deletions src/Provider/Apple.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public function __construct(array $options = [], array $collaborators = [])
*/
protected function createAccessToken(array $response, AbstractGrant $grant)
{
return new AppleAccessToken($response);
return new AppleAccessToken($this->getHttpClient(), $response);
}

/**
Expand Down Expand Up @@ -215,15 +215,15 @@ public function getAccessToken($grant, array $options = [])
}

$signer = new Sha256();
$time = time();
$time = new \DateTimeImmutable();
$expiresAt = $time->modify('+1 Hour');

$token = (new Builder())
->issuedBy($this->teamId)
->permittedFor('https://appleid.apple.com')
->issuedAt($time)
->expiresAt($time + 600)
->issuedAt($time->getTimestamp())
->expiresAt($expiresAt->getTimestamp())
->relatedTo($this->clientId)
->withClaim('sub', $this->clientId)
->withHeader('alg', 'ES256')
->withHeader('kid', $this->keyFileId)
->getToken($signer, $this->getLocalKey());
Expand Down
12 changes: 10 additions & 2 deletions src/Provider/AppleResourceOwner.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ public function getAttribute($key)
*/
public function getFirstName()
{
return $this->getAttribute('name')['firstName'];
$name = $this->getAttribute('name');
if (isset($name)) {
return $name['firstName'];
}
return null;
}

/**
Expand All @@ -66,7 +70,11 @@ public function getId()
*/
public function getLastName()
{
return $this->getAttribute('name')['lastName'];
$name = $this->getAttribute('name');
if (isset($name)) {
return $name['lastName'];
}
return null;
}

/**
Expand Down
19 changes: 17 additions & 2 deletions src/Token/AppleAccessToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Firebase\JWT\JWK;
use Firebase\JWT\JWT;
use GuzzleHttp\ClientInterface;
use InvalidArgumentException;

class AppleAccessToken extends AccessToken
Expand All @@ -23,17 +24,25 @@ class AppleAccessToken extends AccessToken
*/
protected $isPrivateEmail;

/**
* @var ClientInterface
*/
protected $httpClient;

/**
* Constructs an access token.
*
* @param ClientInterface $httpClient the http client to use
* @param array $options An array of options returned by the service provider
* in the access token request. The `access_token` option is required.
* @throws InvalidArgumentException if `access_token` is not provided in `$options`.
*
* @throws \Exception
*/
public function __construct(array $options = [])
public function __construct($httpClient, array $options = [])
{
$this->httpClient = $httpClient;

if (array_key_exists('refresh_token', $options)) {
if (empty($options['id_token'])) {
throw new InvalidArgumentException('Required option not passed: "id_token"');
Expand Down Expand Up @@ -84,7 +93,13 @@ public function __construct(array $options = [])
*/
protected function getAppleKey()
{
return JWK::parseKeySet(json_decode(file_get_contents('https://appleid.apple.com/auth/keys'), true));
$response = $this->httpClient->request('GET', 'https://appleid.apple.com/auth/keys');

if ($response) {
return JWK::parseKeySet(json_decode($response->getBody()->getContents(), true));
}

return false;
}

/**
Expand Down
21 changes: 14 additions & 7 deletions test/src/Provider/AppleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace League\OAuth2\Client\Test\Provider;

use Exception;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Psr7\Response;
use InvalidArgumentException;
use Lcobucci\JWT\Builder;
Expand All @@ -12,9 +13,10 @@
use League\OAuth2\Client\Provider\Exception\AppleAccessDeniedException;
use League\OAuth2\Client\Token\AccessToken;
use League\OAuth2\Client\Tool\QueryBuilderTrait;
use PHPUnit\Framework\TestCase;
use Mockery as m;

class AppleTest extends \PHPUnit_Framework_TestCase
class AppleTest extends TestCase
{
use QueryBuilderTrait;

Expand Down Expand Up @@ -142,19 +144,23 @@ public function testGetAccessToken()
]);
$provider = m::mock($provider);

$time = time();
$time = new \DateTimeImmutable();
$expiresAt = $time->modify('+1 Hour');
$token = (new Builder())
->issuedBy('test-team-id')
->permittedFor('https://appleid.apple.com')
->issuedAt($time)
->expiresAt($time + 600)
->issuedAt($time->getTimestamp())
->expiresAt($expiresAt->getTimestamp())
->relatedTo('test-client')
->withClaim('sub', 'test')
->withHeader('alg', 'RS256')
->withHeader('kid', 'test')
->getToken();

$client = m::mock('GuzzleHttp\ClientInterface');
$client = m::mock(ClientInterface::class);
$client->shouldReceive('request')
->times(1)
->andReturn(new Response(200, [], file_get_contents('https://appleid.apple.com/auth/keys')));
$client->shouldReceive('send')
->times(1)
->andReturn(new Response(200, [], json_encode([
Expand Down Expand Up @@ -209,10 +215,11 @@ public function testNotImplementedGetResourceOwnerDetailsUrl()
$this->provider->getResourceOwnerDetailsUrl(new AccessToken(['access_token' => 'hello']));
}

/**
* @expectedException \League\OAuth2\Client\Provider\Exception\AppleAccessDeniedException
*/
public function testCheckResponse()
{
$this->setExpectedException(AppleAccessDeniedException::class, 'invalid_client', 400);

$class = new \ReflectionClass($this->provider);
$method = $class->getMethod('checkResponse');
$method->setAccessible(true);
Expand Down
20 changes: 18 additions & 2 deletions test/src/Token/AppleAccessTokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace League\OAuth2\Client\Test\Token;

use GuzzleHttp\ClientInterface;
use GuzzleHttp\Psr7\Response;
use League\OAuth2\Client\Token\AppleAccessToken;
use PHPUnit\Framework\TestCase;
use Mockery as m;
Expand Down Expand Up @@ -33,7 +35,7 @@ public function testCreatingAccessToken()
->once()
->andReturn(['examplekey']);

$accessToken = new AppleAccessToken([
$accessToken = new AppleAccessToken($this->getClient(1), [
'access_token' => 'access_token',
'token_type' => 'Bearer',
'expires_in' => 3600,
Expand All @@ -47,11 +49,25 @@ public function testCreatingAccessToken()

public function testCreatingRefreshToken()
{
$refreshToken = new AppleAccessToken([
$refreshToken = new AppleAccessToken($this->getClient(0), [
'access_token' => 'access_token',
'token_type' => 'Bearer',
'expires_in' => 3600
]);
$this->assertEquals('access_token', $refreshToken->getToken());
}

private function getClient($times)
{
$client = m::mock('GuzzleHttp\ClientInterface');
if ($times > 0) {
$client->shouldReceive('request')
->times($times)
->withArgs(['GET', 'https://appleid.apple.com/auth/keys'])
->andReturn(new Response())
;
}

return $client;
}
}

0 comments on commit 6702931

Please sign in to comment.