Passed
Push — master ( a772d5...a1c5a5 )
by Tharanga
06:09
created

ZoomConnection::revokeAccess()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 13
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 21
rs 9.8333
1
<?php
2
/**
3
 * @author Tharanga Kothalawala <[email protected]>
4
 * @date   28-10-2020
5
 */
6
7
namespace TSK\SSO\ThirdParty\Zoom;
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\Zoom
20
 * @see     https://marketplace.zoom.us/docs/guides/auth/oauth
21
 */
22
class ZoomConnection implements VendorConnection
23
{
24
    const API_BASE = 'https://zoom.us';
25
26
    /**
27
     * @var ZoomApiConfiguration
28
     */
29
    private $apiConfiguration;
30
31
    /**
32
     * @var CurlRequest
33
     */
34
    private $curlClient;
35
36
    /**
37
     * @param ZoomApiConfiguration $apiConfiguration
38
     * @param CurlRequest          $curlClient
39
     */
40
    public function __construct(ZoomApiConfiguration $apiConfiguration, CurlRequest $curlClient)
41
    {
42
        $this->apiConfiguration = $apiConfiguration;
43
        $this->curlClient = $curlClient;
44
    }
45
46
    /**
47
     * Use this to redirect the user to the third party login page to grant permission to use their account.
48
     */
49
    public function getGrantUrl()
50
    {
51
        return sprintf(
52
            '%s/oauth/authorize?response_type=code&client_id=%s&redirect_uri=%s&state=%s',
53
            self::API_BASE,
54
            $this->apiConfiguration->clientId(),
55
            urldecode($this->apiConfiguration->redirectUrl()),
56
            $this->apiConfiguration->ourSecretState()
57
        );
58
    }
59
60
    /**
61
     * Grants a new access token
62
     *
63
     * @return CommonAccessToken
64
     * @throws ThirdPartyConnectionFailedException
65
     */
66
    public function grantNewAccessToken()
67
    {
68
        if (empty($_GET['code'])
69
            || empty($_GET['state'])
70
            || $_GET['state'] !== $this->apiConfiguration->ourSecretState()
71
        ) {
72
            throw new ThirdPartyConnectionFailedException('Invalid request!');
73
        }
74
75
        $headers = array(
76
            'Authorization' => sprintf(
77
                'Basic %s',
78
                base64_encode(
79
                    sprintf('%s:%s', $this->apiConfiguration->clientId(), $this->apiConfiguration->clientSecret())
80
                )
81
            ),
82
        );
83
84
        $accessTokenJsonInfo = $this->curlClient->postUrlEncoded(
85
            sprintf("%s/oauth/token", self::API_BASE),
86
            sprintf(
87
                'client_id=%s&client_secret=%s&grant_type=authorization_code&redirect_uri=%s&code=%s',
88
                $this->apiConfiguration->clientId(),
89
                $this->apiConfiguration->clientSecret(),
90
                urlencode($this->apiConfiguration->redirectUrl()),
91
                $_GET['code']
92
            ),
93
            $headers
94
        );
95
96
        $accessTokenInfo = json_decode($accessTokenJsonInfo, true);
97
        if (empty($accessTokenInfo['access_token'])) {
98
            throw new ThirdPartyConnectionFailedException(
99
                'An error occurred while getting the access.'
100
            );
101
        }
102
103
        $accessToken = new CommonAccessToken($accessTokenInfo['access_token'], ThirdParty::ZOOM);
104
        if (!empty($accessTokenInfo['refresh_token'])) {
105
            $accessToken->setRefreshToken($accessTokenInfo['refresh_token']);
106
        }
107
108
        /*
109
        $refreshTokenJsonInfo = $this->curlClient->post(
110
            sprintf("%s/oauth/token?grant_type=refresh_token&refresh_token=%s", self::API_BASE, $accessTokenInfo['refresh_token']),
111
            array(),
112
            $headers
113
        );
114
115
        // if refresh token found, return that or return the access token
116
        $refreshTokenInfo = json_decode($refreshTokenJsonInfo, true);
117
        if (!empty($refreshTokenInfo['access_token']) && !empty($refreshTokenInfo['refresh_token'])) {
118
            $accessToken = new CommonAccessToken($refreshTokenInfo['access_token'], ThirdParty::ZOOM);
119
            $accessToken->setRefreshToken($refreshTokenInfo['refresh_token']);
120
        }//*/
121
122
        return $accessToken;
123
    }
124
125
    /**
126
     * Use this to retrieve the current user's third party user data using there existing granted access token
127
     *
128
     * @param CommonAccessToken $accessToken
129
     *
130
     * @return ThirdPartyUser
131
     * @throws NoThirdPartyEmailFoundException
132
     * @throws ThirdPartyConnectionFailedException
133
     */
134
    public function getSelf(CommonAccessToken $accessToken)
135
    {
136
        $userJsonInfo = $this->curlClient->get(
137
            'https://api.zoom.us/v2/users/me',
138
            array(
139
                sprintf('Authorization: Bearer %s', $accessToken->token()),
140
            )
141
        );
142
143
        $userInfo = json_decode($userJsonInfo, true);
144
        if (empty($userInfo['email'])) {
145
            throw new NoThirdPartyEmailFoundException('An email address cannot be found from vendor');
146
        }
147
148
        return new ThirdPartyUser(
149
            $userInfo['id'],
150
            sprintf('%s %s', $userInfo['first_name'], $userInfo['last_name']),
151
            $userInfo['email'],
152
            $userInfo['pic_url']
153
        );
154
    }
155
156
    /**
157
     * Use this to revoke the access to the third party data.
158
     * This will completely remove the access from the vendor side.
159
     *
160
     * @param CommonAccessToken $accessToken
161
     *
162
     * @return bool
163
     */
164
    public function revokeAccess(CommonAccessToken $accessToken)
165
    {
166
        $revokeJsonInfo = $this->curlClient->post(
167
            sprintf(
168
                "%s/oauth/revoke?token=%s",
169
                self::API_BASE,
170
                $accessToken->token()
171
            ),
172
            array(),
173
            array(
174
                'Authorization' => sprintf(
175
                    'Basic %s',
176
                    base64_encode(
177
                        sprintf('%s:%s', $this->apiConfiguration->clientId(), $this->apiConfiguration->clientSecret())
178
                    )
179
                ),
180
            )
181
        );
182
183
        $revokeInfo = json_decode($revokeJsonInfo, true);
184
        return (!empty($revokeInfo['status']) && $revokeInfo['status'] === 'success');
185
    }
186
}
187