Completed
Push — master ( df062e...3563b3 )
by Tharanga
02:22
created

YahooConnection::getGrantUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 0
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Tharanga Kothalawala <[email protected]>
4
 * @date 22-01-2019
5
 */
6
7
namespace TSK\SSO\ThirdParty\Yahoo;
8
9
use TSK\SSO\Http\CurlRequest;
10
use TSK\SSO\ThirdParty;
11
use TSK\SSO\ThirdParty\CommonAccessToken;
12
use TSK\SSO\ThirdParty\Exception\NoThirdPartyEmailFoundException;
13
use TSK\SSO\ThirdParty\Exception\ThirdPartyConnectionFailedException;
14
use TSK\SSO\ThirdParty\ThirdPartyUser;
15
use TSK\SSO\ThirdParty\VendorConnection;
16
17
/**
18
 * @codeCoverageIgnore
19
 * @package TSK\SSO\ThirdParty\Yahoo
20
 * @see https://developer.yahoo.com/oauth2/guide/flows_authcode
21
 */
22
class YahooConnection implements VendorConnection
23
{
24
    const API_BASE = 'https://api.login.yahoo.com/oauth2';
25
26
    /**
27
     * @var YahooApiConfiguration
28
     */
29
    private $apiConfiguration;
30
31
    /**
32
     * @var CurlRequest
33
     */
34
    private $curlClient;
35
36
    /**
37
     * YahooConnection constructor.
38
     * @param YahooApiConfiguration $apiConfiguration
39
     * @param CurlRequest $curlClient
40
     */
41
    public function __construct(YahooApiConfiguration $apiConfiguration, CurlRequest $curlClient)
42
    {
43
        $this->apiConfiguration = $apiConfiguration;
44
        $this->curlClient = $curlClient;
45
    }
46
47
    /**
48
     * Use this to get a link to redirect a user to the third party login
49
     *
50
     * @return string|null
51
     */
52
    public function getGrantUrl()
53
    {
54
        return sprintf(
55
            '%s/request_auth?client_id=%s&redirect_uri=%s&response_type=code&language=en-us&state=%s',
56
            self::API_BASE,
57
            $this->apiConfiguration->clientId(),
58
            urlencode($this->apiConfiguration->redirectUrl()),
59
            $this->apiConfiguration->ourSecretState()
60
        );
61
    }
62
63
    /**
64
     * Grants a new access token
65
     *
66
     * @return CommonAccessToken
67
     * @throws ThirdPartyConnectionFailedException
68
     */
69
    public function grantNewAccessToken()
70
    {
71
        if (empty($_GET['code'])
72
            || empty($_GET['state'])
73
            || $_GET['state'] !== $this->apiConfiguration->ourSecretState()
74
        ) {
75
            throw new ThirdPartyConnectionFailedException('Invalid request!');
76
        }
77
78
        $accessTokenJsonInfo = $this->curlClient->postUrlEncoded(
79
            sprintf("%s/get_token", self::API_BASE),
80
            sprintf(
81
                'client_id=%s&client_secret=%s&grant_type=authorization_code&redirect_uri=%s&code=%s',
82
                $this->apiConfiguration->clientId(),
83
                $this->apiConfiguration->clientSecret(),
84
                urlencode($this->apiConfiguration->redirectUrl()),
85
                $_GET['code']
86
            ),
87
            array(
88
                'Authorization' => sprintf(
89
                    'Basic %s',
90
                    base64_encode(
91
                        sprintf('%s:%s', $this->apiConfiguration->clientId(), $this->apiConfiguration->clientSecret())
92
                    )
93
                )
94
            )
95
        );
96
97
        $accessTokenJson = json_decode($accessTokenJsonInfo, true);
98
        if (empty($accessTokenJson['access_token'])) {
99
            throw new ThirdPartyConnectionFailedException('Failed to establish a new third party vendor connection.');
100
        }
101
102
        return new CommonAccessToken(
103
            $accessTokenJson['access_token'],
104
            ThirdParty::YAHOO
105
        );
106
    }
107
108
    /**
109
     * Use this to retrieve the current user's third party user data using there existing granted access token
110
     *
111
     * @param CommonAccessToken $accessToken
112
     * @return ThirdPartyUser
113
     * @throws NoThirdPartyEmailFoundException
114
     * @throws ThirdPartyConnectionFailedException
115
     */
116
    public function getSelf(CommonAccessToken $accessToken)
117
    {
118
        $userJsonInfo = $this->curlClient->get(
119
            'https://social.yahooapis.com/v1/user/me/profile?format=json',
120
            array(
121
                sprintf('Authorization: Bearer %s', $accessToken->token()),
122
                'Accept: application/json',
123
            )
124
        );
125
126
        $userInfo = json_decode($userJsonInfo, true);
127
        if (empty($userInfo['profile']['emails'][0]['handle'])) {
128
            throw new NoThirdPartyEmailFoundException('An email address cannot be found from vendor');
129
        }
130
131
        return new ThirdPartyUser(
132
            $userInfo['profile']['guid'],
133
            sprintf('%s %s', $userInfo['profile']['givenName'], $userInfo['profile']['familyName']),
134
            $userInfo['profile']['emails'][0]['handle'],
135
            !empty($userInfo['profile']['image']['imageUrl']) ? $userInfo['profile']['image']['imageUrl'] : '',
136
            !empty($userInfo['profile']['gender']) ? $userInfo['profile']['gender'] : ''
137
        );
138
    }
139
140
    /**
141
     * Use this to revoke the access to the third party data.
142
     * This will completely remove the access from the vendor side.
143
     *
144
     * @param CommonAccessToken $accessToken
145
     * @return bool
146
     */
147
    public function revokeAccess(CommonAccessToken $accessToken)
148
    {
149
        // noop : cannot find documentation on how to revoke the app's access.
150
        return true;
151
    }
152
}
153