Completed
Pull Request — master (#1)
by Tharanga
09:26
created

TwitterConnection::getSelf()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 13
nc 2
nop 1
dl 0
loc 19
rs 9.8333
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Tharanga Kothalawala <[email protected]>
4
 * @date 13-01-2019
5
 */
6
7
namespace TSK\SSO\ThirdParty\Twitter;
8
9
use Abraham\TwitterOAuth\TwitterOAuth;
10
use Abraham\TwitterOAuth\TwitterOAuthException;
11
use TSK\SSO\ThirdParty;
12
use TSK\SSO\ThirdParty\CommonAccessToken;
13
use TSK\SSO\ThirdParty\Exception\NoThirdPartyEmailFoundException;
14
use TSK\SSO\ThirdParty\Exception\ThirdPartyConnectionFailedException;
15
use TSK\SSO\ThirdParty\ThirdPartyUser;
16
use TSK\SSO\ThirdParty\VendorConnection;
17
18
/**
19
 * @codeCoverageIgnore
20
 * @package TSK\SSO\ThirdParty\Twitter
21
 * @see https://developer.twitter.com/en/docs/twitter-for-websites/log-in-with-twitter/guides/implementing-sign-in-with-twitter
22
 */
23
class TwitterConnection implements VendorConnection
24
{
25
    const TOKEN_SEPARATOR = '::';
26
27
    /**
28
     * @var TwitterApiConfiguration
29
     */
30
    private $configuration;
31
32
    /**
33
     * @var TwitterOAuth
34
     */
35
    private $twitter;
36
37
    /**
38
     * TwitterConnection constructor.
39
     * @param TwitterApiConfiguration $configuration
40
     */
41
    public function __construct(TwitterApiConfiguration $configuration)
42
    {
43
        $this->configuration = $configuration;
44
        $this->twitter = new TwitterOAuth(
45
            $this->configuration->consumerApiKey(),
46
            $this->configuration->consumerApiSecret(),
47
            $this->configuration->oauthToken(),
48
            $this->configuration->oauthTokenSecret()
49
        );
50
    }
51
52
    /**
53
     * Use this to get a link to redirect a user to the third party login
54
     *
55
     * @return string|null
56
     */
57
    public function getGrantUrl()
58
    {
59
        try {
60
            $response = $this->twitter->oauth('oauth/request_token', array(
61
                'oauth_callback' => $this->configuration->redirectUrl()
62
            ));
63
        } catch (TwitterOAuthException $ex) {
64
            return null;
65
        }
66
67
        return sprintf('%s/oauth/authenticate?oauth_token=%s', TwitterOAuth::API_HOST, $response['oauth_token']);
68
    }
69
70
    /**
71
     * Grants a new access token
72
     *
73
     * @return CommonAccessToken
74
     * @throws ThirdPartyConnectionFailedException
75
     */
76
    public function grantNewAccessToken()
77
    {
78
        if (empty($_GET['oauth_token'])) {
79
            throw new ThirdPartyConnectionFailedException('Invalid request!');
80
        }
81
82
        $accessTokenData = $this->twitter->oauth('oauth/access_token', array(
83
            'oauth_callback' => $this->configuration->redirectUrl(),
84
            'oauth_token' => $_GET['oauth_token'],
85
            'oauth_verifier' => $_GET['oauth_verifier'],
86
        ));
87
88
        if (empty($accessTokenData['oauth_token'])) {
89
            throw new ThirdPartyConnectionFailedException(
90
                'Failed to establish a new third party vendor connection'
91
            );
92
        }
93
94
        return new CommonAccessToken(
95
            sprintf(
96
                '%s%s%s',
97
                $accessTokenData['oauth_token'],
98
                self::TOKEN_SEPARATOR,
99
                $accessTokenData['oauth_token_secret']
100
            ),
101
            ThirdParty::TWITTER
102
        );
103
    }
104
105
    /**
106
     * Use this to retrieve the current user's third party user data using there existing granted access token
107
     *
108
     * @param CommonAccessToken $accessToken
109
     * @return ThirdPartyUser
110
     * @throws NoThirdPartyEmailFoundException
111
     * @throws ThirdPartyConnectionFailedException
112
     */
113
    public function getSelf(CommonAccessToken $accessToken)
114
    {
115
        $tokenData = explode(self::TOKEN_SEPARATOR, $accessToken->token());
116
        $userInfo = (array) $this->twitter->get('account/verify_credentials', array(
117
            'oauth_token' => $tokenData[0],
118
            'oauth_token_secret' => $tokenData[1],
119
            'include_email' => true,
120
        ));
121
122
        if (empty($userInfo['email'])) {
123
            throw new NoThirdPartyEmailFoundException('An email address cannot be found from vendor');
124
        }
125
126
        return new ThirdPartyUser(
127
            $userInfo['id'],
128
            $userInfo['screen_name'],
129
            $userInfo['email'],
130
            !empty($userInfo['profile_image_url']) ? $userInfo['profile_image_url'] : '',
131
            !empty($userInfo['gender']) ? $userInfo['gender'] : ''
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
     * @return bool
141
     */
142
    public function revokeAccess(CommonAccessToken $accessToken)
143
    {
144
        $tokenData = explode(self::TOKEN_SEPARATOR, $accessToken->token());
0 ignored issues
show
Unused Code introduced by
The assignment to $tokenData is dead and can be removed.
Loading history...
145
/*
146
        // it seems it is revoking the main account's token than user specific ones. investigate more
147
        try {
148
            $this->twitter->post('oauth/invalidate_token', array(
149
                'access_token' => $tokenData[0],
150
                'access_token_secret' => $tokenData[1],
151
            ));
152
        } catch (TwitterOAuthException $ex) {
153
            return false;
154
        }
155
//*/
156
        return true;
157
    }
158
}
159