diff --git a/README.md b/README.md index 50f450b..bad78a6 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ You can find the documentation at [dusken.readthedocs.org](http://dusken.readthe ## Installation -### Manual install: sudo apt-get install python-virtualenv python-dev postgresql libpq-dev pgadmin3 cd dusken virtualenv --distribute venv @@ -21,17 +20,8 @@ You can find the documentation at [dusken.readthedocs.org](http://dusken.readthe ./manage.py syncdb --all ./manage.py runserver - See [the EDB wiki](http://edb.neuf.no/wiki/index.php/DUSKEN) for more info. - -### TODO Vagrant install: - -Download latest version of Vagrant from [downloads.vagrantup.com](http://downloads.vagrantup.com/) and then do: - - vagrant plugin install vagrant-salt - vagrant up - vagrant ssh - + ## Development tasks # Reset DB python manage.py reset_db --router=default && python manage.py syncdb --all diff --git a/README.vagrant.md b/README.vagrant.md new file mode 100644 index 0000000..544a02a --- /dev/null +++ b/README.vagrant.md @@ -0,0 +1,7 @@ +## TODO + +Download latest version of Vagrant from [downloads.vagrantup.com](http://downloads.vagrantup.com/) and then do: + + vagrant plugin install vagrant-salt + vagrant up + vagrant ssh diff --git a/dusken/authentication.py b/dusken/authentication.py index c8aba44..65226f8 100644 --- a/dusken/authentication.py +++ b/dusken/authentication.py @@ -7,6 +7,84 @@ from provider.oauth2.models import AccessToken, Client from tastypie.authentication import ApiKeyAuthentication, Authentication from tastypie.http import HttpUnauthorized +class OAuth20Authentication(Authentication): + """ + OAuth authenticator. + + This Authentication method checks for a provided HTTP_AUTHORIZATION + and looks up to see if this is a valid OAuth Access Token + """ + def __init__(self, realm='API'): + self.realm = realm + + def is_authenticated(self, request, **kwargs): + """ + Verify 2-legged oauth request. Parameters accepted as + values in "Authorization" header, or as a GET request + or in a POST body. + """ + logging.info("OAuth20Authentication") + + try: + key = request.GET.get('oauth_consumer_key') + if not key: + key = request.POST.get('oauth_consumer_key') + if not key: + auth_header_value = request.META.get('HTTP_AUTHORIZATION') + if auth_header_value: + key = auth_header_value.split(': ')[1].split(" ")[1] + if not key: + logging.info('OAuth20Authentication. No consumer_key found.') + return None + """ + If verify_access_token() does not pass, it will raise an error + """ + token = verify_access_token(key) + + # If OAuth authentication is successful, set the request user to the token user for authorization + request.user = token.user + + # If OAuth authentication is successful, set oauth_consumer_key on request in case we need it later + request.META['oauth_consumer_key'] = key + return True + except KeyError, e: + logging.exception("Error in OAuth20Authentication.") + request.user = AnonymousUser() + return False + except Exception, e: + logging.exception("Error in OAuth20Authentication.") + return False + return True + +def verify_access_token(key): + # Check if key is in AccessToken key + try: + token = AccessToken.objects.get(token=key) + + # Check if token has expired + if token.expires < timezone.now(): + raise OAuthError('AccessToken has expired.') + except AccessToken.DoesNotExist, e: + raise OAuthError("AccessToken not found at all.") + + logging.info('Valid access') + return token + +def create_access_token(user): + # Create a Oauth2 Client (each test gets a new one) + oauth2_client = Client.objects.create( + user=user, + name="example.com testclient", + client_type=1, # ?? + url="http://example.com") + # Create a Oauth2 AccessToken (each test gets a new one) + access_token = AccessToken(user=user, client=oauth2_client) + access_token.save() + + # Return HTTP authorization header + return "Authorization: OAuth {}".format(access_token.token) + + class MyApiKeyAuthentication(ApiKeyAuthentication): """ Override method below to use our custom User model @@ -75,81 +153,3 @@ class OAuthError(RuntimeError): """Generic exception class.""" def __init__(self, message='OAuth error occured.'): self.message = message - - -class OAuth20Authentication(Authentication): - """ - OAuth authenticator. - - This Authentication method checks for a provided HTTP_AUTHORIZATION - and looks up to see if this is a valid OAuth Access Token - """ - def __init__(self, realm='API'): - self.realm = realm - - def is_authenticated(self, request, **kwargs): - """ - Verify 2-legged oauth request. Parameters accepted as - values in "Authorization" header, or as a GET request - or in a POST body. - """ - logging.info("OAuth20Authentication") - - try: - key = request.GET.get('oauth_consumer_key') - if not key: - key = request.POST.get('oauth_consumer_key') - if not key: - auth_header_value = request.META.get('HTTP_AUTHORIZATION') - if auth_header_value: - key = auth_header_value.split(': ')[1].split(" ")[1] - if not key: - logging.error('OAuth20Authentication. No consumer_key found.') - return None - """ - If verify_access_token() does not pass, it will raise an error - """ - token = verify_access_token(key) - - # If OAuth authentication is successful, set the request user to the token user for authorization - request.user = token.user - - # If OAuth authentication is successful, set oauth_consumer_key on request in case we need it later - request.META['oauth_consumer_key'] = key - return True - except KeyError, e: - logging.exception("Error in OAuth20Authentication.") - request.user = AnonymousUser() - return False - except Exception, e: - logging.exception("Error in OAuth20Authentication.") - return False - return True - -def verify_access_token(key): - # Check if key is in AccessToken key - try: - token = AccessToken.objects.get(token=key) - - # Check if token has expired - if token.expires < timezone.now(): - raise OAuthError('AccessToken has expired.') - except AccessToken.DoesNotExist, e: - raise OAuthError("AccessToken not found at all.") - - logging.info('Valid access') - return token - -def create_access_token(user): - # Create a Oauth2 Client (each test gets a new one) - oauth2_client = Client.objects.create( - user=user, - name="example.com testclient", - client_type=1, # ?? - url="http://example.com") - # Create a Oauth2 AccessToken (each test gets a new one) - access_token = AccessToken(user=user, client=oauth2_client) - access_token.save() - - # Return HTTP authorization header - return "Authorization: OAuth {}".format(access_token.token) diff --git a/dusken/tests/test_member.py b/dusken/tests/test_member.py index f7dcac2..eb3938f 100644 --- a/dusken/tests/test_member.py +++ b/dusken/tests/test_member.py @@ -17,7 +17,7 @@ class MemberTestBase(ResourceTestCase): # Get the preloaded member, which will be used for # comparison with fetched object. self.member = Member.objects.get(pk=2) - # Create a OAuth2 Authorization HTTP header + # Put OAuth2 Authorization in HTTP header self.creds = create_access_token(self.member) # URIs to the member api