The authentication flow has completed.
") 102 | s.wfile.write("") 103 | 104 | def log_message(self, format, *args): 105 | """Do not log messages to stdout while running as command line program.""" 106 | pass 107 | 108 | 109 | @util.positional(3) 110 | def run_flow(flow, storage, flags, http=None): 111 | """Core code for a command-line application. 112 | 113 | The run() function is called from your application and runs through all the 114 | steps to obtain credentials. It takes a Flow argument and attempts to open an 115 | authorization server page in the user's default web browser. The server asks 116 | the user to grant your application access to the user's data. If the user 117 | grants access, the run() function returns new credentials. The new credentials 118 | are also stored in the Storage argument, which updates the file associated 119 | with the Storage object. 120 | 121 | It presumes it is run from a command-line application and supports the 122 | following flags: 123 | 124 | --auth_host_name: Host name to use when running a local web server 125 | to handle redirects during OAuth authorization. 126 | (default: 'localhost') 127 | 128 | --auth_host_port: Port to use when running a local web server to handle 129 | redirects during OAuth authorization.; 130 | repeat this option to specify a list of values 131 | (default: '[8080, 8090]') 132 | (an integer) 133 | 134 | --[no]auth_local_webserver: Run a local web server to handle redirects 135 | during OAuth authorization. 136 | (default: 'true') 137 | 138 | The tools module defines an ArgumentParser the already contains the flag 139 | definitions that run() requires. You can pass that ArgumentParser to your 140 | ArgumentParser constructor: 141 | 142 | parser = argparse.ArgumentParser(description=__doc__, 143 | formatter_class=argparse.RawDescriptionHelpFormatter, 144 | parents=[tools.run_parser]) 145 | flags = parser.parse_args(argv) 146 | 147 | Args: 148 | flow: Flow, an OAuth 2.0 Flow to step through. 149 | storage: Storage, a Storage to store the credential in. 150 | flags: argparse.ArgumentParser, the command-line flags. 151 | http: An instance of httplib2.Http.request 152 | or something that acts like it. 153 | 154 | Returns: 155 | Credentials, the obtained credential. 156 | """ 157 | logging.getLogger().setLevel(getattr(logging, flags.logging_level)) 158 | if not flags.noauth_local_webserver: 159 | success = False 160 | port_number = 0 161 | for port in flags.auth_host_port: 162 | port_number = port 163 | try: 164 | httpd = ClientRedirectServer((flags.auth_host_name, port), 165 | ClientRedirectHandler) 166 | except socket.error, e: 167 | pass 168 | else: 169 | success = True 170 | break 171 | flags.noauth_local_webserver = not success 172 | if not success: 173 | print 'Failed to start a local webserver listening on either port 8080' 174 | print 'or port 9090. Please check your firewall settings and locally' 175 | print 'running programs that may be blocking or using those ports.' 176 | print 177 | print 'Falling back to --noauth_local_webserver and continuing with', 178 | print 'authorization.' 179 | print 180 | 181 | if not flags.noauth_local_webserver: 182 | oauth_callback = 'http://%s:%s/' % (flags.auth_host_name, port_number) 183 | else: 184 | oauth_callback = client.OOB_CALLBACK_URN 185 | flow.redirect_uri = oauth_callback 186 | authorize_url = flow.step1_get_authorize_url() 187 | 188 | if not flags.noauth_local_webserver: 189 | webbrowser.open(authorize_url, new=1, autoraise=True) 190 | print 'Your browser has been opened to visit:' 191 | print 192 | print ' ' + authorize_url 193 | print 194 | print 'If your browser is on a different machine then exit and re-run this' 195 | print 'application with the command-line parameter ' 196 | print 197 | print ' --noauth_local_webserver' 198 | print 199 | else: 200 | print 'Go to the following link in your browser:' 201 | print 202 | print ' ' + authorize_url 203 | print 204 | 205 | code = None 206 | if not flags.noauth_local_webserver: 207 | httpd.handle_request() 208 | if 'error' in httpd.query_params: 209 | sys.exit('Authentication request was rejected.') 210 | if 'code' in httpd.query_params: 211 | code = httpd.query_params['code'] 212 | else: 213 | print 'Failed to find "code" in the query parameters of the redirect.' 214 | sys.exit('Try running with --noauth_local_webserver.') 215 | else: 216 | code = raw_input('Enter verification code: ').strip() 217 | 218 | try: 219 | credential = flow.step2_exchange(code, http=http) 220 | except client.FlowExchangeError, e: 221 | sys.exit('Authentication has failed: %s' % e) 222 | 223 | storage.put(credential) 224 | credential.set_store(storage) 225 | print 'Authentication successful.' 226 | 227 | return credential 228 | 229 | 230 | def message_if_missing(filename): 231 | """Helpful message to display if the CLIENT_SECRETS file is missing.""" 232 | 233 | return _CLIENT_SECRETS_MESSAGE % filename 234 | 235 | try: 236 | from old_run import run 237 | from old_run import FLAGS 238 | except ImportError: 239 | def run(*args, **kwargs): 240 | raise NotImplementedError( 241 | 'The gflags library must be installed to use tools.run(). ' 242 | 'Please install gflags or preferrably switch to using ' 243 | 'tools.run_flow().') 244 | -------------------------------------------------------------------------------- /oauth2client/util.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2010 Google Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | """Common utility library.""" 19 | 20 | __author__ = ['rafek@google.com (Rafe Kaplan)', 21 | 'guido@google.com (Guido van Rossum)', 22 | ] 23 | __all__ = [ 24 | 'positional', 25 | 'POSITIONAL_WARNING', 26 | 'POSITIONAL_EXCEPTION', 27 | 'POSITIONAL_IGNORE', 28 | ] 29 | 30 | import inspect 31 | import logging 32 | import types 33 | import urllib 34 | import urlparse 35 | 36 | try: 37 | from urlparse import parse_qsl 38 | except ImportError: 39 | from cgi import parse_qsl 40 | 41 | logger = logging.getLogger(__name__) 42 | 43 | POSITIONAL_WARNING = 'WARNING' 44 | POSITIONAL_EXCEPTION = 'EXCEPTION' 45 | POSITIONAL_IGNORE = 'IGNORE' 46 | POSITIONAL_SET = frozenset([POSITIONAL_WARNING, POSITIONAL_EXCEPTION, 47 | POSITIONAL_IGNORE]) 48 | 49 | positional_parameters_enforcement = POSITIONAL_WARNING 50 | 51 | def positional(max_positional_args): 52 | """A decorator to declare that only the first N arguments my be positional. 53 | 54 | This decorator makes it easy to support Python 3 style key-word only 55 | parameters. For example, in Python 3 it is possible to write: 56 | 57 | def fn(pos1, *, kwonly1=None, kwonly1=None): 58 | ... 59 | 60 | All named parameters after * must be a keyword: 61 | 62 | fn(10, 'kw1', 'kw2') # Raises exception. 63 | fn(10, kwonly1='kw1') # Ok. 64 | 65 | Example: 66 | To define a function like above, do: 67 | 68 | @positional(1) 69 | def fn(pos1, kwonly1=None, kwonly2=None): 70 | ... 71 | 72 | If no default value is provided to a keyword argument, it becomes a required 73 | keyword argument: 74 | 75 | @positional(0) 76 | def fn(required_kw): 77 | ... 78 | 79 | This must be called with the keyword parameter: 80 | 81 | fn() # Raises exception. 82 | fn(10) # Raises exception. 83 | fn(required_kw=10) # Ok. 84 | 85 | When defining instance or class methods always remember to account for 86 | 'self' and 'cls': 87 | 88 | class MyClass(object): 89 | 90 | @positional(2) 91 | def my_method(self, pos1, kwonly1=None): 92 | ... 93 | 94 | @classmethod 95 | @positional(2) 96 | def my_method(cls, pos1, kwonly1=None): 97 | ... 98 | 99 | The positional decorator behavior is controlled by 100 | util.positional_parameters_enforcement, which may be set to 101 | POSITIONAL_EXCEPTION, POSITIONAL_WARNING or POSITIONAL_IGNORE to raise an 102 | exception, log a warning, or do nothing, respectively, if a declaration is 103 | violated. 104 | 105 | Args: 106 | max_positional_arguments: Maximum number of positional arguments. All 107 | parameters after the this index must be keyword only. 108 | 109 | Returns: 110 | A decorator that prevents using arguments after max_positional_args from 111 | being used as positional parameters. 112 | 113 | Raises: 114 | TypeError if a key-word only argument is provided as a positional 115 | parameter, but only if util.positional_parameters_enforcement is set to 116 | POSITIONAL_EXCEPTION. 117 | """ 118 | def positional_decorator(wrapped): 119 | def positional_wrapper(*args, **kwargs): 120 | if len(args) > max_positional_args: 121 | plural_s = '' 122 | if max_positional_args != 1: 123 | plural_s = 's' 124 | message = '%s() takes at most %d positional argument%s (%d given)' % ( 125 | wrapped.__name__, max_positional_args, plural_s, len(args)) 126 | if positional_parameters_enforcement == POSITIONAL_EXCEPTION: 127 | raise TypeError(message) 128 | elif positional_parameters_enforcement == POSITIONAL_WARNING: 129 | logger.warning(message) 130 | else: # IGNORE 131 | pass 132 | return wrapped(*args, **kwargs) 133 | return positional_wrapper 134 | 135 | if isinstance(max_positional_args, (int, long)): 136 | return positional_decorator 137 | else: 138 | args, _, _, defaults = inspect.getargspec(max_positional_args) 139 | return positional(len(args) - len(defaults))(max_positional_args) 140 | 141 | 142 | def scopes_to_string(scopes): 143 | """Converts scope value to a string. 144 | 145 | If scopes is a string then it is simply passed through. If scopes is an 146 | iterable then a string is returned that is all the individual scopes 147 | concatenated with spaces. 148 | 149 | Args: 150 | scopes: string or iterable of strings, the scopes. 151 | 152 | Returns: 153 | The scopes formatted as a single string. 154 | """ 155 | if isinstance(scopes, types.StringTypes): 156 | return scopes 157 | else: 158 | return ' '.join(scopes) 159 | 160 | 161 | def dict_to_tuple_key(dictionary): 162 | """Converts a dictionary to a tuple that can be used as an immutable key. 163 | 164 | The resulting key is always sorted so that logically equivalent dictionaries 165 | always produce an identical tuple for a key. 166 | 167 | Args: 168 | dictionary: the dictionary to use as the key. 169 | 170 | Returns: 171 | A tuple representing the dictionary in it's naturally sorted ordering. 172 | """ 173 | return tuple(sorted(dictionary.items())) 174 | 175 | 176 | def _add_query_parameter(url, name, value): 177 | """Adds a query parameter to a url. 178 | 179 | Replaces the current value if it already exists in the URL. 180 | 181 | Args: 182 | url: string, url to add the query parameter to. 183 | name: string, query parameter name. 184 | value: string, query parameter value. 185 | 186 | Returns: 187 | Updated query parameter. Does not update the url if value is None. 188 | """ 189 | if value is None: 190 | return url 191 | else: 192 | parsed = list(urlparse.urlparse(url)) 193 | q = dict(parse_qsl(parsed[4])) 194 | q[name] = value 195 | parsed[4] = urllib.urlencode(q) 196 | return urlparse.urlunparse(parsed) 197 | -------------------------------------------------------------------------------- /oauth2client/xsrfutil.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2.5 2 | # 3 | # Copyright 2010 the Melange authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Helper methods for creating & verifying XSRF tokens.""" 18 | 19 | __authors__ = [ 20 | '"Doug Coker"Sku | 49 |Amount | 50 |
---|---|
{{column}} | 54 |{{"$%.2f"|format(current_data.rows[0][loop.index])}} | 55 |