forked from vinitkumar/googlecl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
service.py
142 lines (121 loc) · 5.53 KB
/
service.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# Copyright (C) 2010 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Basic service extensions for the gdata python client library for use on
the command line."""
import gdata.service
import googlecl
import googlecl.base
import logging
LOG = logging.getLogger(__name__)
class BaseServiceCL(googlecl.base.BaseCL):
"""Extension of gdata.GDataService specific to GoogleCL."""
def __init__(self, section, config,
request_error_class=gdata.service.RequestError,
*args, **kwargs):
super(BaseServiceCL, self).__init__(section,
config,
request_error_class,
*args,
**kwargs)
# Most services using old gdata API have to disable ssl.
self.ssl = False
# Used for automatic retries of Get/Delete requests that fail due to 302
# errors. See BaseCL.retry_operation.
self.original_get = self.Get
self.original_delete = self.Delete
self.original_post = self.Post
self.original_put = self.Put
self.Get = self.retry_get
self.Delete = self.retry_delete
self.Post = self.retry_post
self.Put = self.retry_put
LOG.debug('Initialized googlecl.service.BaseServiceCL')
def retry_get(self, *args, **kwargs):
"""Retries the Get method."""
self.original_operation = self.original_get
return self.retry_operation(*args, **kwargs)
def retry_delete(self, *args, **kwargs):
"""Retries the Delete method."""
self.original_operation = self.original_delete
return self.retry_operation(*args, **kwargs)
def retry_post(self, *args, **kwargs):
"""Retries the Post method."""
self.original_operation = self.original_post
return self.retry_operation(*args, **kwargs)
def retry_put(self, *args, **kwargs):
"""Retries the Put method."""
self.original_operation = self.original_put
return self.retry_operation(*args, **kwargs)
def request_access(self, domain, display_name, scopes=None, browser=None):
"""Do all the steps involved with getting an OAuth access token.
Keyword arguments:
domain: Domain to request access for.
(Sets the hd query parameter for the authorization step).
display_name: Descriptor for the machine doing the requesting.
scopes: String or list/tuple of strings describing scopes to request
access to. Default None for default scope of service.
browser: Browser to use to open authentication request url. Default None
for no browser launch, and just displaying the url.
Returns:
True if access token was succesfully retrieved and set, otherwise False.
"""
# Installed applications do not have a pre-registration and so follow
# directions for unregistered applications
self.SetOAuthInputParameters(gdata.auth.OAuthSignatureMethod.HMAC_SHA1,
consumer_key='anonymous',
consumer_secret='anonymous')
fetch_params = {'xoauth_displayname':display_name}
# First and third if statements taken from
# gdata.service.GDataService.FetchOAuthRequestToken.
# Need to do this detection/conversion here so we can add the 'email' API
if not scopes:
scopes = gdata.service.lookup_scopes(self.service)
if isinstance(scopes, tuple):
scopes = list(scopes)
if not isinstance(scopes, list):
scopes = [scopes,]
scopes.extend(['https://www.googleapis.com/auth/userinfo#email'])
LOG.debug('Scopes being requested: ' + str(scopes))
try:
request_token = self.FetchOAuthRequestToken(scopes=scopes,
extra_parameters=fetch_params)
except gdata.service.FetchingOAuthRequestTokenFailed, err:
LOG.error(err[0]['body'].strip() + '; Request token retrieval failed!')
if str(err).find('Timestamp') != -1:
LOG.info('Is your system clock up to date? See the FAQ on our wiki: '
'http://code.google.com/p/googlecl/wiki/FAQ'
'#Timestamp_too_far_from_current_time')
return False
auth_params = {'hd': domain}
auth_url = self.GenerateOAuthAuthorizationURL(request_token=request_token,
extra_params=auth_params)
if browser is not None:
try:
browser.open(str(auth_url))
except Exception, err:
# Blanket catch of Exception is a bad idea, but don't want to pass in
# error to look for.
LOG.error('Failed to launch web browser: ' + unicode(err))
message = ('Please log in and/or grant access via your browser at: \n%s\n\n'
'Then, in this terminal, hit enter. ' % auth_url)
raw_input(message)
# This upgrades the token, and if successful, sets the access token
try:
self.UpgradeToOAuthAccessToken(request_token)
except gdata.service.TokenUpgradeFailed:
LOG.error('Token upgrade failed! Could not get OAuth access token.')
return False
else:
return True
RequestAccess = request_access