SlackConnection   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 48
c 1
b 0
f 0
dl 0
loc 122
rs 10
wmc 12

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getSelf() 0 22 3
A grantNewAccessToken() 0 25 5
A __construct() 0 4 1
A getGrantUrl() 0 9 1
A revokeAccess() 0 10 2
1
<?php
2
/**
3
 * @author Tharanga Kothalawala <[email protected]>
4
 * @date 31-12-2018
5
 */
6
7
namespace TSK\SSO\ThirdParty\Slack;
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\Slack
20
 * @see https://api.slack.com/docs/oauth#flow
21
 */
22
class SlackConnection implements VendorConnection
23
{
24
    const API_BASE = 'https://slack.com';
25
26
    /**
27
     * @var SlackApiConfiguration
28
     */
29
    private $apiConfiguration;
30
31
    /**
32
     * @var CurlRequest
33
     */
34
    private $curlClient;
35
36
    /**
37
     * @param SlackApiConfiguration $apiConfiguration
38
     * @param CurlRequest $curlClient
39
     */
40
    public function __construct(SlackApiConfiguration $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?scope=%s&client_id=%s&redirect_uri=%s&state=%s',
53
            self::API_BASE,
54
            $this->apiConfiguration->appPermissions(),
55
            $this->apiConfiguration->appId(),
56
            $this->apiConfiguration->redirectUrl(),
57
            $this->apiConfiguration->ourSecretState()
58
        );
59
    }
60
61
    /**
62
     * Grants a new access token
63
     *
64
     * @return CommonAccessToken
65
     * @throws ThirdPartyConnectionFailedException
66
     */
67
    public function grantNewAccessToken()
68
    {
69
        if (empty($_GET['code'])
70
            || empty($_GET['state'])
71
            || $_GET['state'] !== $this->apiConfiguration->ourSecretState()
72
        ) {
73
            throw new ThirdPartyConnectionFailedException('Invalid request!');
74
        }
75
76
        $accessTokenJsonInfo = $this->curlClient->get(sprintf(
77
            "%s/api/oauth.access?client_id=%s&client_secret=%s&code=%s",
78
            self::API_BASE,
79
            $this->apiConfiguration->appId(),
80
            $this->apiConfiguration->appSecret(),
81
            $_GET['code']
82
        ));
83
84
        $accessTokenInfo = json_decode($accessTokenJsonInfo, true);
85
        if (!empty($accessTokenInfo['error'])) {
86
            throw new ThirdPartyConnectionFailedException(
87
                'An error occurred while getting the access. Details : ' . $accessTokenInfo['error']
88
            );
89
        }
90
91
        return new CommonAccessToken($accessTokenInfo['access_token'], ThirdParty::SLACK);
92
    }
93
94
    /**
95
     * Use this to retrieve the current user's third party user data using there existing granted access token
96
     *
97
     * @param CommonAccessToken $accessToken
98
     * @return ThirdPartyUser
99
     * @throws NoThirdPartyEmailFoundException
100
     * @throws ThirdPartyConnectionFailedException
101
     */
102
    public function getSelf(CommonAccessToken $accessToken)
103
    {
104
        $userJsonInfo = $this->curlClient->get(sprintf(
105
            "%s/api/users.identity?token=%s",
106
            self::API_BASE,
107
            $accessToken->token()
108
        ));
109
110
        $userInfo = json_decode($userJsonInfo, true);
111
        if (!empty($userInfo['error'])) {
112
            throw new ThirdPartyConnectionFailedException('Error occured : ' . $userInfo['error']);
113
        }
114
115
        if (empty($userInfo['user']['email'])) {
116
            throw new NoThirdPartyEmailFoundException('An email address cannot be found from vendor');
117
        }
118
119
        return new ThirdPartyUser(
120
            $userInfo['user']['id'],
121
            $userInfo['user']['name'],
122
            $userInfo['user']['email'],
123
            $userInfo['user']['image_1024']
124
        );
125
    }
126
127
    /**
128
     * Use this to revoke the access to the third party data.
129
     * This will completely remove the access from the vendor side.
130
     *
131
     * @param CommonAccessToken $accessToken
132
     * @return bool
133
     */
134
    public function revokeAccess(CommonAccessToken $accessToken)
135
    {
136
        $revokeJsonInfo = $this->curlClient->get(sprintf(
137
            "%s/api/auth.revoke?token=%s",
138
            self::API_BASE,
139
            $accessToken->token()
140
        ));
141
142
        $revokeInfo = json_decode($revokeJsonInfo, true);
143
        return (!empty($revokeInfo['revoked']) && boolval($revokeInfo['revoked']) === true);
144
    }
145
}
146