Skip to content

Commit

Permalink
Pass api error messages through, fixed api_key vulnerability, updated…
Browse files Browse the repository at this point in the history
… documentation
  • Loading branch information
axelstudios committed Sep 5, 2019
1 parent 1d201f2 commit df0b2f4
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 7 deletions.
5 changes: 3 additions & 2 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ API

Authentication
--------------
Authentication is handled via an authorization token set in an HTTP header.
Authentication is handled via an encoded authorization token set in a HTTP header.
To request an API token, go to ``/app/#/profile/developer`` and click 'Get a New API Key'.

Authenticate every API request with your username (email) and the API key via `Basic Auth`_.
Authenticate every API request with your username (email, all lowercase) and the API key via `Basic Auth`_.
The header is sent in the form of ``Authorization: Basic <credentials>``, where credentials is the base64 encoding of the email and key joined by a single colon ``:``.

.. _Basic Auth: https://en.wikipedia.org/wiki/Basic_access_authentication

Expand Down
12 changes: 9 additions & 3 deletions seed/landing/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
:copyright (c) 2014 - 2019, The Regents of the University of California, through Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Department of Energy) and contributors. All rights reserved. # NOQA
:author
"""
import re
import uuid
import hmac
import base64
Expand Down Expand Up @@ -103,17 +104,22 @@ def process_header_request(cls, request):
if not auth_header.startswith('Bearer') or not getattr(request, 'user', None):
try:
if not auth_header.startswith('Basic'):
raise exceptions.AuthenticationFailed("Only Basic HTTP_AUTHORIZATION is supported")
raise exceptions.AuthenticationFailed('Only Basic HTTP_AUTHORIZATION is supported')

auth_header = auth_header.split()[1]
auth_header = base64.urlsafe_b64decode(auth_header).decode('utf-8')
username, api_key = auth_header.split(':')

valid_api_key = re.search('^[a-f0-9]{40}$', api_key)
if not valid_api_key:
raise exceptions.AuthenticationFailed('Invalid API key')

user = SEEDUser.objects.get(api_key=api_key, username=username)
return user
except ValueError:
raise exceptions.AuthenticationFailed("Invalid HTTP_AUTHORIZATION Header")
raise exceptions.AuthenticationFailed('Invalid HTTP_AUTHORIZATION Header')
except SEEDUser.DoesNotExist:
raise exceptions.AuthenticationFailed("Invalid API key")
raise exceptions.AuthenticationFailed('Invalid API key')

def get_absolute_url(self):
return "/users/%s/" % urlquote(self.username)
Expand Down
4 changes: 2 additions & 2 deletions seed/utils/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,10 @@ def __call__(self, request):
try:
if get_api_request_user(request):
request.csrf_processing_done = True
except exceptions.AuthenticationFailed:
except exceptions.AuthenticationFailed as e:
return JsonResponse({
'status': 'error',
'message': 'Invalid API key',
'message': str(e),
}, status=status.HTTP_401_UNAUTHORIZED)
return response

Expand Down

0 comments on commit df0b2f4

Please sign in to comment.