Completed
Pull Request — master (#483)
by
unknown
03:10
created

Google::getAccessTokenEndpoint()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace OAuth\OAuth2\Service;
4
5
use OAuth\Common\Consumer\CredentialsInterface;
6
use OAuth\Common\Http\Client\ClientInterface;
7
use OAuth\Common\Http\Uri\UriInterface;
8
use OAuth\Common\Storage\TokenStorageInterface;
9
use OAuth\OAuth2\Token\StdOAuth2Token;
10
use OAuth\Common\Http\Exception\TokenResponseException;
11
use OAuth\OAuth2\Service\Exception\InvalidAccessTypeException;
12
use OAuth\Common\Http\Uri\Uri;
13
14
class Google extends AbstractService
15
{
16
    /**
17
     * Defined scopes - More scopes are listed here:
18
     * https://developers.google.com/oauthplayground/
19
     *
20
     * Make a pull request if you need more scopes.
21
     */
22
23
    // Basic
24
    const SCOPE_EMAIL                       = 'email';
25
    const SCOPE_PROFILE                     = 'profile';
26
27
    const SCOPE_USERINFO_EMAIL              = 'https://www.googleapis.com/auth/userinfo.email';
28
    const SCOPE_USERINFO_PROFILE            = 'https://www.googleapis.com/auth/userinfo.profile';
29
30
    // Google+
31
    const SCOPE_GPLUS_ME                    = 'https://www.googleapis.com/auth/plus.me';
32
    const SCOPE_GPLUS_LOGIN                 = 'https://www.googleapis.com/auth/plus.login';
33
    const SCOPE_GPLUS_CIRCLES_READ          = 'https://www.googleapis.com/auth/plus.circles.read';
34
    const SCOPE_GPLUS_CIRCLES_WRITE         = 'https://www.googleapis.com/auth/plus.circles.write';
35
    const SCOPE_GPLUS_STREAM_READ           = 'https://www.googleapis.com/auth/plus.stream.read';
36
    const SCOPE_GPLUS_STREAM_WRITE          = 'https://www.googleapis.com/auth/plus.stream.write';
37
    const SCOPE_GPLUS_MEDIA                 = 'https://www.googleapis.com/auth/plus.media.upload';
38
39
    // Google Drive
40
    const SCOPE_DOCUMENTSLIST               = 'https://docs.google.com/feeds/';
41
    const SCOPE_SPREADSHEETS                = 'https://spreadsheets.google.com/feeds/';
42
    const SCOPE_GOOGLEDRIVE                 = 'https://www.googleapis.com/auth/drive';
43
    const SCOPE_DRIVE_APPS                  = 'https://www.googleapis.com/auth/drive.appdata';
44
    const SCOPE_DRIVE_APPS_READ_ONLY        = 'https://www.googleapis.com/auth/drive.apps.readonly';
45
    const SCOPE_GOOGLEDRIVE_FILES           = 'https://www.googleapis.com/auth/drive.file';
46
    const SCOPE_DRIVE_METADATA_READ_ONLY    = 'https://www.googleapis.com/auth/drive.metadata.readonly';
47
    const SCOPE_DRIVE_READ_ONLY             = 'https://www.googleapis.com/auth/drive.readonly';
48
    const SCOPE_DRIVE_SCRIPTS               = 'https://www.googleapis.com/auth/drive.scripts';
49
50
    // Adwords
51
    const SCOPE_ADSENSE                     = 'https://www.googleapis.com/auth/adsense';
52
    const SCOPE_ADWORDS                     = 'https://www.googleapis.com/auth/adwords/';
53
    const SCOPE_GAN                         = 'https://www.googleapis.com/auth/gan'; // google affiliate network...?
54
55
    //Doubleclick for Publishers
56
    const SCOPE_DFP                         = 'https://www.googleapis.com/auth/dfp';
57
    const SCOPE_DFP_TRAFFICKING             = 'https://www.googleapis.com/auth/dfatrafficking';
58
    const SCOPE_DFP_REPORTING               = 'https://www.googleapis.com/auth/dfareporting';
59
60
    // Google Analytics
61
    const SCOPE_ANALYTICS                   = 'https://www.googleapis.com/auth/analytics';
62
    const SCOPE_ANALYTICS_EDIT              = 'https://www.googleapis.com/auth/analytics.edit';
63
    const SCOPE_ANALYTICS_MANAGE_USERS      = 'https://www.googleapis.com/auth/analytics.manage.users';
64
    const SCOPE_ANALYTICS_READ_ONLY         = 'https://www.googleapis.com/auth/analytics.readonly';
65
66
    //Gmail
67
    const SCOPE_GMAIL_MODIFY                = 'https://www.googleapis.com/auth/gmail.modify';
68
    const SCOPE_GMAIL_READONLY              = 'https://www.googleapis.com/auth/gmail.readonly';
69
    const SCOPE_GMAIL_COMPOSE               = 'https://www.googleapis.com/auth/gmail.compose';
70
    const SCOPE_GMAIL_SEND                  = 'https://www.googleapis.com/auth/gmail.send';
71
    const SCOPE_GMAIL_INSERT                = 'https://www.googleapis.com/auth/gmail.insert';
72
    const SCOPE_GMAIL_LABELS                = 'https://www.googleapis.com/auth/gmail.labels';
73
    const SCOPE_GMAIL_FULL                  = 'https://mail.google.com/';
74
75
    // Other services
76
    const SCOPE_BOOKS                       = 'https://www.googleapis.com/auth/books';
77
    const SCOPE_BLOGGER                     = 'https://www.googleapis.com/auth/blogger';
78
    const SCOPE_CALENDAR                    = 'https://www.googleapis.com/auth/calendar';
79
    const SCOPE_CALENDAR_READ_ONLY          = 'https://www.googleapis.com/auth/calendar.readonly';
80
    const SCOPE_CONTACT                     = 'https://www.google.com/m8/feeds/';
81
    const SCOPE_CONTACTS_RO                 = 'https://www.googleapis.com/auth/contacts.readonly';
82
    const SCOPE_CHROMEWEBSTORE              = 'https://www.googleapis.com/auth/chromewebstore.readonly';
83
    const SCOPE_GMAIL                       = 'https://mail.google.com/mail/feed/atom';
84
    const SCOPE_GMAIL_IMAP_SMTP             = 'https://mail.google.com';
85
    const SCOPE_PICASAWEB                   = 'https://picasaweb.google.com/data/';
86
    const SCOPE_SITES                       = 'https://sites.google.com/feeds/';
87
    const SCOPE_URLSHORTENER                = 'https://www.googleapis.com/auth/urlshortener';
88
    const SCOPE_WEBMASTERTOOLS              = 'https://www.google.com/webmasters/tools/feeds/';
89
    const SCOPE_TASKS                       = 'https://www.googleapis.com/auth/tasks';
90
91
    // Cloud services
92
    const SCOPE_CLOUDSTORAGE                = 'https://www.googleapis.com/auth/devstorage.read_write';
93
    const SCOPE_CONTENTFORSHOPPING          = 'https://www.googleapis.com/auth/structuredcontent'; // what even is this
94
    const SCOPE_USER_PROVISIONING           = 'https://apps-apis.google.com/a/feeds/user/';
95
    const SCOPE_GROUPS_PROVISIONING         = 'https://apps-apis.google.com/a/feeds/groups/';
96
    const SCOPE_NICKNAME_PROVISIONING       = 'https://apps-apis.google.com/a/feeds/alias/';
97
98
    // Old
99
    const SCOPE_ORKUT                       = 'https://www.googleapis.com/auth/orkut';
100
    const SCOPE_GOOGLELATITUDE =
101
        'https://www.googleapis.com/auth/latitude.all.best https://www.googleapis.com/auth/latitude.all.city';
102
    const SCOPE_OPENID                      = 'openid';
103
104
    // YouTube
105
    const SCOPE_YOUTUBE_GDATA               = 'https://gdata.youtube.com';
106
    const SCOPE_YOUTUBE_ANALYTICS_MONETARY  = 'https://www.googleapis.com/auth/yt-analytics-monetary.readonly';
107
    const SCOPE_YOUTUBE_ANALYTICS           = 'https://www.googleapis.com/auth/yt-analytics.readonly';
108
    const SCOPE_YOUTUBE                     = 'https://www.googleapis.com/auth/youtube';
109
    const SCOPE_YOUTUBE_READ_ONLY           = 'https://www.googleapis.com/auth/youtube.readonly';
110
    const SCOPE_YOUTUBE_UPLOAD              = 'https://www.googleapis.com/auth/youtube.upload';
111
    const SCOPE_YOUTUBE_PARTNER             = 'https://www.googleapis.com/auth/youtubepartner';
112
    const SCOPE_YOUTUBE_PARTNER_AUDIT       = 'https://www.googleapis.com/auth/youtubepartner-channel-audit';
113
114
    // Google Glass
115
    const SCOPE_GLASS_TIMELINE              = 'https://www.googleapis.com/auth/glass.timeline';
116
    const SCOPE_GLASS_LOCATION              = 'https://www.googleapis.com/auth/glass.location';
117
118
    // Android Publisher
119
    const SCOPE_ANDROID_PUBLISHER           = 'https://www.googleapis.com/auth/androidpublisher';
120
121
    // Google Classroom
122
    const SCOPE_CLASSROOM_COURSES           = 'https://www.googleapis.com/auth/classroom.courses';
123
    const SCOPE_CLASSROOM_COURSES_READONLY  = 'https://www.googleapis.com/auth/classroom.courses.readonly';
124
    const SCOPE_CLASSROOM_PROFILE_EMAILS    = 'https://www.googleapis.com/auth/classroom.profile.emails';
125
    const SCOPE_CLASSROOM_PROFILE_PHOTOS    = 'https://www.googleapis.com/auth/classroom.profile.photos';
126
    const SCOPE_CLASSROOM_ROSTERS           = 'https://www.googleapis.com/auth/classroom.rosters';
127
    const SCOPE_CLASSROOM_ROSTERS_READONLY  = 'https://www.googleapis.com/auth/classroom.rosters.readonly';
128
129
    protected $accessType = 'online';
130
131
    public function __construct(
132
        CredentialsInterface $credentials,
133
        ClientInterface $httpClient,
134
        TokenStorageInterface $storage,
135
        $scopes = array(),
136
        UriInterface $baseApiUri = null
137
    ) {
138
        parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true);
139
140
        if (null === $baseApiUri) {
141
            $this->baseApiUri = new Uri('https://www.googleapis.com/oauth2/v1/');
142
        }
143
    }
144
145
    public function setAccessType($accessType)
146
    {
147
        if (!in_array($accessType, array('online', 'offline'), true)) {
148
            throw new InvalidAccessTypeException('Invalid accessType, expected either online or offline');
149
        }
150
        $this->accessType = $accessType;
151
    }
152
153
    /**
154
     * {@inheritdoc}
155
     */
156
    public function getAuthorizationEndpoint()
157
    {
158
        return new Uri('https://accounts.google.com/o/oauth2/auth?access_type=' . $this->accessType);
159
    }
160
161
    /**
162
     * {@inheritdoc}
163
     */
164
    public function getAccessTokenEndpoint()
165
    {
166
        return new Uri('https://accounts.google.com/o/oauth2/token');
167
    }
168
169
    /**
170
     * {@inheritdoc}
171
     */
172
    protected function parseAccessTokenResponse($responseBody)
173
    {
174
        $data = json_decode($responseBody, true);
175
176
        if (null === $data || !is_array($data)) {
177
            throw new TokenResponseException('Unable to parse response.');
178
        } elseif (isset($data['error'])) {
179
            throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
180
        }
181
182
        $token = new StdOAuth2Token();
183
        $token->setAccessToken($data['access_token']);
184
        $token->setLifetime($data['expires_in']);
185
186
        if (isset($data['refresh_token'])) {
187
            $token->setRefreshToken($data['refresh_token']);
188
            unset($data['refresh_token']);
189
        }
190
191
        unset($data['access_token']);
192
        unset($data['expires_in']);
193
194
        $token->setExtraParams($data);
195
196
        return $token;
197
    }
198
}
199