Passed
Push — master ( 379291...a772d5 )
by Tharanga
09:14
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
        $accessTokenJsonInfo = $this->curlClient->postUrlEncoded(
76
            sprintf("%s/oauth/token", self::API_BASE),
77
            sprintf(
78
                'client_id=%s&client_secret=%s&grant_type=authorization_code&redirect_uri=%s&code=%s',
79
                $this->apiConfiguration->clientId(),
80
                $this->apiConfiguration->clientSecret(),
81
                urlencode($this->apiConfiguration->redirectUrl()),
82
                $_GET['code']
83
            ),
84
            array(
85
                'Authorization' => sprintf(
86
                    'Basic %s',
87
                    base64_encode(
88
                        sprintf('%s:%s', $this->apiConfiguration->clientId(), $this->apiConfiguration->clientSecret())
89
                    )
90
                ),
91
            )
92
        );
93
94
        $accessTokenInfo = json_decode($accessTokenJsonInfo, true);
95
        if (empty($accessTokenInfo['access_token'])) {
96
            throw new ThirdPartyConnectionFailedException(
97
                'An error occurred while getting the access.'
98
            );
99
        }
100
101
        return new CommonAccessToken($accessTokenInfo['access_token'], ThirdParty::ZOOM);
102
    }
103
104
    /**
105
     * Use this to retrieve the current user's third party user data using there existing granted access token
106
     *
107
     * @param CommonAccessToken $accessToken
108
     *
109
     * @return ThirdPartyUser
110
     * @throws NoThirdPartyEmailFoundException
111
     * @throws ThirdPartyConnectionFailedException
112
     */
113
    public function getSelf(CommonAccessToken $accessToken)
114
    {
115
        $userJsonInfo = $this->curlClient->get(
116
            'https://api.zoom.us/v2/users/me',
117
            array(
118
                sprintf('Authorization: Bearer %s', $accessToken->token()),
119
            )
120
        );
121
122
        $userInfo = json_decode($userJsonInfo, true);
123
        if (empty($userInfo['email'])) {
124
            throw new NoThirdPartyEmailFoundException('An email address cannot be found from vendor');
125
        }
126
127
        return new ThirdPartyUser(
128
            $userInfo['id'],
129
            sprintf('%s %s', $userInfo['first_name'], $userInfo['last_name']),
130
            $userInfo['email'],
131
            $userInfo['pic_url']
132
        );
133
    }
134
135
    /**
136
     * Use this to revoke the access to the third party data.
137
     * This will completely remove the access from the vendor side.
138
     *
139
     * @param CommonAccessToken $accessToken
140
     *
141
     * @return bool
142
     */
143
    public function revokeAccess(CommonAccessToken $accessToken)
144
    {
145
        $revokeJsonInfo = $this->curlClient->post(
146
            sprintf(
147
                "%s/oauth/revoke?token=%s",
148
                self::API_BASE,
149
                $accessToken->token()
150
            ),
151
            array(),
152
            array(
153
                'Authorization' => sprintf(
154
                    'Basic %s',
155
                    base64_encode(
156
                        sprintf('%s:%s', $this->apiConfiguration->clientId(), $this->apiConfiguration->clientSecret())
157
                    )
158
                ),
159
            )
160
        );
161
162
        $revokeInfo = json_decode($revokeJsonInfo, true);
163
        return (!empty($revokeInfo['status']) && $revokeInfo['status'] === 'success');
164
    }
165
}
166