Skip to content

Commit 4a67305

Browse files
committed
Add resource owner
1 parent 58b9a5a commit 4a67305

File tree

3 files changed

+239
-1
lines changed

3 files changed

+239
-1
lines changed

src/Provider/ResourceOwner.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace Bramdevries\Oauth\Client\Provider;
4+
5+
use League\OAuth2\Client\Provider\ResourceOwnerInterface;
6+
7+
class ResourceOwner implements ResourceOwnerInterface
8+
{
9+
/**
10+
* @var array
11+
*/
12+
protected $details = [];
13+
14+
/**
15+
* ResourceOwner constructor.
16+
*
17+
* @param array $details
18+
*/
19+
public function __construct(array $details)
20+
{
21+
$this->details = $details;
22+
}
23+
24+
/**
25+
* @return string
26+
*/
27+
public function getId()
28+
{
29+
return $this->details['user_id'];
30+
}
31+
32+
/**
33+
* @return array
34+
*/
35+
public function toArray()
36+
{
37+
return $this->details;
38+
}
39+
40+
}

src/Provider/Slack.php

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,81 @@
22

33
namespace Bramdevries\Oauth\Client\Provider;
44

5-
class Slack
5+
use League\OAuth2\Client\Provider\AbstractProvider;
6+
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
7+
use League\OAuth2\Client\Provider\ResourceOwnerInterface;
8+
use League\OAuth2\Client\Token\AccessToken;
9+
use Psr\Http\Message\ResponseInterface;
10+
11+
class Slack extends AbstractProvider
612
{
13+
/**
14+
* @var string
15+
*/
16+
protected $domain = 'https://slack.com';
17+
18+
/**
19+
* @return string
20+
*/
21+
public function getBaseAuthorizationUrl()
22+
{
23+
return $this->domain.'/oauth/authorize';
24+
}
25+
26+
/**
27+
* @param array $params
28+
*
29+
* @return string
30+
*/
31+
public function getBaseAccessTokenUrl(array $params)
32+
{
33+
return $this->domain.'/api/oauth.access';
34+
}
35+
36+
/**
37+
* @param AccessToken $token
38+
*
39+
* @return string
40+
*/
41+
public function getResourceOwnerDetailsUrl(AccessToken $token)
42+
{
43+
return $this->domain.'/api/auth.test?token='.$token->getToken();
44+
}
45+
46+
/**
47+
* @return array
48+
*/
49+
protected function getDefaultScopes()
50+
{
51+
return [];
52+
}
53+
54+
/**
55+
* @param ResponseInterface $response
56+
* @param array|string $data
57+
*
58+
* @throws IdentityProviderException
59+
*/
60+
protected function checkResponse(ResponseInterface $response, $data)
61+
{
62+
if (!$data['ok'] || $response->getStatusCode() >= 400) {
63+
throw new IdentityProviderException(
64+
$data['error'] ?: $response->getReasonPhrase(),
65+
$response->getStatusCode(),
66+
$response
67+
);
68+
}
69+
}
70+
71+
/**
72+
* @param array $response
73+
* @param AccessToken $token
74+
*
75+
* @return ResourceOwner
76+
*/
77+
protected function createResourceOwner(array $response, AccessToken $token)
78+
{
79+
return new ResourceOwner($response);
80+
}
81+
782
}

tests/Provider/SlackTest.php

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
3+
namespace Bramdevries\Oauth\Client\Provider;
4+
5+
use League\OAuth2\Client\Token\AccessToken;
6+
use Mockery as m;
7+
8+
class SlackTest extends \PHPUnit_Framework_TestCase
9+
{
10+
/**
11+
* @var Slack
12+
*/
13+
protected $provider;
14+
15+
protected function setUp()
16+
{
17+
$this->provider = new Slack([
18+
'clientId' => 'foo',
19+
'clientSecret' => 'bar',
20+
'redirectUri' => 'none',
21+
]);
22+
}
23+
24+
public function testAuthorizationUrl()
25+
{
26+
$url = $this->provider->getAuthorizationUrl();
27+
$uri = parse_url($url);
28+
parse_str($uri['query'], $query);
29+
30+
$this->assertArrayHasKey('client_id', $query);
31+
$this->assertArrayHasKey('redirect_uri', $query);
32+
$this->assertArrayHasKey('state', $query);
33+
$this->assertArrayHasKey('scope', $query);
34+
$this->assertArrayHasKey('response_type', $query);
35+
$this->assertArrayHasKey('approval_prompt', $query);
36+
$this->assertNotNull($this->provider->getState());
37+
}
38+
39+
public function testScopes()
40+
{
41+
$options = ['scope' => [uniqid(), uniqid()]];
42+
$url = $this->provider->getAuthorizationUrl($options);
43+
$this->assertContains(urlencode(implode(',', $options['scope'])), $url);
44+
}
45+
46+
public function testGetAuthorizationUrl()
47+
{
48+
$url = $this->provider->getAuthorizationUrl();
49+
$uri = parse_url($url);
50+
$this->assertEquals('/oauth/authorize', $uri['path']);
51+
}
52+
53+
public function testGetBaseAccessTokenUrl()
54+
{
55+
$params = [];
56+
$url = $this->provider->getBaseAccessTokenUrl($params);
57+
$uri = parse_url($url);
58+
$this->assertEquals('/api/oauth.access', $uri['path']);
59+
}
60+
61+
public function testGetAccessToken()
62+
{
63+
$response = m::mock('Psr\Http\Message\ResponseInterface');
64+
65+
$response->shouldReceive('getBody')->andReturn('{"ok":"true", "scope":"identify,read,post", "access_token": "mock_access_token"}');
66+
$response->shouldReceive('getHeader')->andReturn(['content-type' => 'json']);
67+
$response->shouldReceive('getStatusCode')->andReturn(200);
68+
69+
$client = m::mock('GuzzleHttp\ClientInterface');
70+
$client->shouldReceive('send')->times(1)->andReturn($response);
71+
$this->provider->setHttpClient($client);
72+
73+
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
74+
$this->assertEquals('mock_access_token', $token->getToken());
75+
$this->assertNull($token->getExpires());
76+
$this->assertNull($token->getRefreshToken());
77+
$this->assertNull($token->getResourceOwnerId());
78+
}
79+
80+
public function testUserData()
81+
{
82+
$response = m::mock('Psr\Http\Message\ResponseInterface');
83+
$response->shouldReceive('getHeader')->andReturn(['content-type' => 'json']);
84+
$response->shouldReceive('getStatusCode')->andReturn(200);
85+
86+
$response->shouldReceive('getBody')->andReturn('{"ok": true, "url": "https:\/\/myteam.slack.com\/", "team": "My Team", "user": "cal", "team_id": "T1234", "user_id": "U1234"}');
87+
88+
$client = m::mock('GuzzleHttp\ClientInterface');
89+
$client->shouldReceive('send')->andReturn($response);
90+
91+
$this->provider->setHttpClient($client);
92+
$token = m::mock('League\OAuth2\Client\Token\AccessToken');
93+
$token->shouldReceive('getToken')->andReturn('foo');
94+
95+
$user = $this->provider->getResourceOwner($token);
96+
$this->assertEquals('U1234', $user->getId());
97+
$this->assertEquals([
98+
'ok' => true,
99+
'url' => 'https://myteam.slack.com/',
100+
'team' => 'My Team',
101+
'user' => 'cal',
102+
'team_id' => 'T1234',
103+
'user_id' => 'U1234',
104+
], $user->toArray());
105+
}
106+
107+
public function testCanThrowException()
108+
{
109+
$this->setExpectedException('League\OAuth2\Client\Provider\Exception\IdentityProviderException', 'code_already_used');
110+
111+
$response = m::mock('Psr\Http\Message\ResponseInterface');
112+
113+
$response->shouldReceive('getBody')->andReturn('{"ok":false, "error":"code_already_used"}');
114+
$response->shouldReceive('getHeader')->andReturn(['content-type' => 'json']);
115+
$response->shouldReceive('getStatusCode')->andReturn(200);
116+
117+
$client = m::mock('GuzzleHttp\ClientInterface');
118+
$client->shouldReceive('send')->times(1)->andReturn($response);
119+
$this->provider->setHttpClient($client);
120+
121+
$this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
122+
}
123+
}

0 commit comments

Comments
 (0)