Skip to content

Commit 8fe1d0e

Browse files
author
api.jscudder
committed
Changed the token_store to use an object for the token which is responsible for attaching auth headers to requests as they are made.
1 parent 25dcdc4 commit 8fe1d0e

2 files changed

Lines changed: 65 additions & 5 deletions

File tree

src/atom/http_interface.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
import StringIO
2929

3030

31+
USER_AGENT = '%s GData-Python/1.2.0'
32+
33+
3134
class Error(Exception):
3235
pass
3336

@@ -84,3 +87,54 @@ def read(self, amt=None):
8487
return self._body.read()
8588
else:
8689
return self._body.read(amt)
90+
91+
92+
class GenericHttpClient(object):
93+
def __init__(self, http_client, headers=None):
94+
"""
95+
96+
Args:
97+
http_client: An object which provides a request method to make an HTTP
98+
request. The request method in GenericHttpClient performs a
99+
call-through to the contained HTTP client object.
100+
headers: A dictionary containing HTTP headers which should be included
101+
in every HTTP request. Common persistent headers include
102+
'User-Agent'.
103+
"""
104+
self.http_client = http_client
105+
self.headers = headers or {}
106+
107+
def request(self, operation, url, data=None, headers=None):
108+
all_headers = self.headers.copy()
109+
if headers:
110+
all_headers.update(headers)
111+
return self.http_client.request(operation, url, data=data,
112+
headers=all_headers)
113+
114+
def get(self, url, headers=None):
115+
return self.request('GET', url, headers=headers)
116+
117+
def post(self, url, data, headers=None):
118+
return self.request('POST', url, data=data, headers=headers)
119+
120+
def put(self, url, data, headers=None):
121+
return self.request('PUT', url, data=data, headers=headers)
122+
123+
def delete(self, url, headers=None):
124+
return self.request('DELETE', url, headers=headers)
125+
126+
127+
class GenericToken(object):
128+
"""Represents an Authorization token to be added to HTTP requests.
129+
130+
Some Authorization headers included calculated fields (digital
131+
signatures for example) which are based on the parameters of the HTTP
132+
request. Therefore the token is responsible for signing the request
133+
and adding the Authorization header.
134+
"""
135+
def perform_request(self, http_client, operation, url, data=None,
136+
headers=None):
137+
"""For the GenericToken, no Authorization token is set."""
138+
return http_client.request(operation, url, data=data, headers=headers)
139+
140+

src/atom/token_store.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
__author__ = 'api.jscudder (Jeff Scudder)'
2929

3030

31+
import http_interface
32+
33+
3134
SCOPE_ALL = 'http://'
3235

3336

@@ -40,8 +43,8 @@ def add_token(self, token, scopes):
4043
"""Adds a new token to the store (replaces tokens with the same scope).
4144
4245
Args:
43-
token: str The token value to be sent as the value for the
44-
Authorization header in an HTTP request.
46+
token: A subclass of http_interface.GenericToken. The token object is
47+
responsible for adding the Authorization header to the HTTP request.
4548
scopes: list of atom.url.Url objects, or strings which specify the
4649
URLs for which this token can be used. These do not need to be
4750
full URLs, any URL that begins with the scope will be considered
@@ -67,8 +70,11 @@ def find_token(self, url):
6770
of the URL. The first match found is returned.
6871
6972
Returns:
70-
The token string to be used in the Authorization headers, or None, if
71-
the url did not begin with any of the token scopes available.
73+
The token object which should execute the HTTP request. If there was
74+
no token for the url (the url did not begin with any of the token
75+
scopes available), then the http_interface.GenericToken will be
76+
returned because the GenericToken calls through to the http client
77+
without adding an Authorization header.
7278
"""
7379
url = str(url)
7480
if url in self._tokens:
@@ -77,7 +83,7 @@ def find_token(self, url):
7783
for scope, token in self._tokens.iteritems():
7884
if url.startswith(scope):
7985
return token
80-
return None
86+
return http_interface.GenericToken()
8187

8288
def remove_token(self, url):
8389
"""Removes the first token which is considered valid for the URL.

0 commit comments

Comments
 (0)