Skip to content

Commit 3074976

Browse files
Merge pull request #1 from uc-cdis/feat/update-oauth
feat(update-oauth): update final step in auth
2 parents f9657c9 + 822bd9b commit 3074976

File tree

4 files changed

+64
-60
lines changed

4 files changed

+64
-60
lines changed

cdis_oauth2client/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77
from .blueprint import blueprint
88
from .client import OAuth2Client
99
from .exceptions import OAuth2Error
10-
from .oauth2 import authorize
10+
from .oauth2 import get_username

cdis_oauth2client/blueprint.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
import flask
1919
from flask import current_app
2020

21-
from .oauth2 import authorize
22-
2321

2422
blueprint = flask.Blueprint('oauth', 'oauth_v0')
2523

@@ -33,22 +31,19 @@ def get_authorization_url():
3331
@blueprint.route('/authorize', methods=['GET'])
3432
def do_authorize():
3533
"""
36-
Call ``authorize`` to authorize the user (authorize returns the username)
37-
and store the username in the Flask session.
34+
Call ``authorize`` to authorize the user by storing the access_token cookie
35+
received from the OAuth2Client.
3836
"""
39-
flask.session['username'] = authorize(
40-
current_app.oauth2,
41-
current_app.config['USER_API'],
42-
flask.request.args.get('code')
43-
)
37+
code = flask.request.args.get('code')
38+
flask.session['access_token'] = current_app.oauth2.get_access_token(code)
4439
return ''
4540

4641

4742
@blueprint.route('/logout', methods=['GET'])
4843
def logout_oauth():
4944
"""
5045
Log out the user by clearing the Flask session (thus removing the
51-
username from the session).
46+
access_token from the session).
5247
"""
5348
flask.session.clear()
5449
return ''

cdis_oauth2client/client.py

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
import urllib
88
import urlparse
99

10+
from cdispyutils.log import get_logger
1011
import requests
1112

12-
from cdispyutils.log import get_logger
13+
from .exceptions import OAuth2Error
1314

1415

1516
_PDC = 'https://bionimbus-pdc.opensciencedatacloud.org/api/oauth2/'
@@ -68,14 +69,6 @@ def authorization_url(self):
6869
})
6970
return urlparse.urljoin(self.oauth_provider, 'authorize') + '?' + tail
7071

71-
def get_authorization_url(self):
72-
"""
73-
Simply return the authorization URL.
74-
75-
Helper function useful for adding Flask URL rules, for example.
76-
"""
77-
return self.authorization_url
78-
7972
def _post_to_internal_oauth(self, data):
8073
"""
8174
Post data to the URL at ``self.internal_oauth``.
@@ -105,15 +98,16 @@ def get_token(self, code):
10598
10699
An example of the credentials returned:
107100
108-
{u'access_token': u'9ydWQi1SqGU82hAGf8M0JoNJbXhxQ1',
109-
u'expires_in': 3600,
110-
u'refresh_token': u'Ll6PfksjrCSJHtkEQV41mRRbR4tUxU',
111-
u'scope': u'user',
112-
u'token_type': u'Bearer'}
101+
{
102+
u'access_token': u'9ydWQi1SqGU82hAGf8M0JoNJbXhxQ1',
103+
u'expires_in': 3600, u'refresh_token':
104+
u'Ll6PfksjrCSJHtkEQV41mRRbR4tUxU', u'scope': u'user',
105+
u'token_type': u'Bearer'
106+
}
113107
114108
:param code: usually flask.request.args.get('code')
115109
:type code: str
116-
:return: dictionary of OAuth credentials
110+
:return: dictionary of OAuth credentials (see above)
117111
:rtype: dict
118112
"""
119113
# Formulate the data for posting to the OAuth provider.
@@ -126,6 +120,19 @@ def get_token(self, code):
126120
}
127121
return self._post_to_internal_oauth(data)
128122

123+
def get_access_token(self, code):
124+
"""
125+
Get specifically the access_token from the OAuth token response.
126+
"""
127+
token_response = self.get_token(code)
128+
access_token = token_response.get('access_token')
129+
if not access_token:
130+
raise OAuth2Error(
131+
message='did not receive access token',
132+
json=token_response
133+
)
134+
return access_token
135+
129136
def refresh_token(self, refresh_token):
130137
"""
131138
Refresh the OAuth access token.

cdis_oauth2client/oauth2.py

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,55 @@
11
"""
22
cdis_oauth2client.oauth2
3-
4-
Provides :py:func:``authorize`` to perform the OAuth2 authorization. Note that
5-
this module should be kept entirely Flask-agnostic, i.e. Flask should not be
6-
imported here and :py:func:``authorize`` should accept an ``OAuth2Client`` with
7-
a ``get_token`` method, in order to modularize the logic.
83
"""
94

5+
import flask
106
import requests
117

128
from .exceptions import OAuth2Error
139

1410

15-
def authorize(oauth_client, user_api, code):
11+
def get_username(user_api=None):
1612
"""
17-
Authorize an OAuth client.
13+
Given the URL for the user API, call user-api to get the username for the
14+
current flask session using the current access_token cookie.
15+
16+
For this function to get the username, the user must already be
17+
authenticated with an access_token cookie stored in the flask session:
18+
19+
flask.session['access_token']
20+
21+
If the `user_api` argument is not provided, get the user API URL from:
22+
23+
flask.current_app.config['USER_API']
1824
19-
:param oauth_client: the OAuth2 client to authorize
20-
:type oauth_client: OAuth2Client
2125
:param user_api: URL for the user API
2226
:type user_api: str
23-
:param code: will usually be flask.request.args.get('code')
24-
:type code: str
25-
:return: the username
27+
:return: the username:
2628
:rtype: str
2729
"""
28-
if not code:
29-
raise OAuth2Error('no authorization code provided')
30-
31-
token_response = oauth_client.get_token(code)
32-
access_token = token_response.get('access_token')
33-
if not access_token:
34-
raise OAuth2Error(
35-
message='did not receive access token in response from client',
36-
json=token_response
37-
)
30+
if user_api is None:
31+
try:
32+
user_api = flask.current_app.config['USER_API']
33+
except KeyError as e:
34+
raise OAuth2Error("'USER_API' not set in flask.current_app.config")
3835

3936
try:
40-
headers = {'Authorization': 'Bearer ' + access_token}
41-
request = requests.get(user_api + 'user/', headers=headers)
42-
user_api_response = request.json()
37+
access_token = flask.session['access_token']
38+
except KeyError:
39+
code = flask.request.args.get('code')
40+
if code is None:
41+
raise OAuth2Error('could not obtain access token')
42+
access_token = flask.current_app.oauth2.get_access_token(code)
43+
44+
url = user_api + 'user/'
45+
headers = {'Authorization': 'Bearer ' + access_token}
46+
try:
47+
response = requests.get(url, headers=headers).json()
4348
except requests.RequestException as e:
44-
raise OAuth2Error(
45-
'failed to get user info due to requests exception: {}'.format(e)
46-
)
47-
except Exception as e:
48-
raise OAuth2Error('failed due to unexpected exception: {}'.format(e))
49-
50-
username = user_api_response.get('username')
51-
if not username:
52-
raise OAuth2Error(json=user_api_response)
49+
msg = 'failed to get username due to requests exception: {}'
50+
raise OAuth2Error(msg.format(e))
51+
username = response.get('username')
52+
if username is None:
53+
msg = 'username missing from response: {}'
54+
raise OAuth2Error(msg.format(response))
5355
return username

0 commit comments

Comments
 (0)