Skip to content

Commit

Permalink
Merge pull request GeoNode#2 from camptocamp/add_basic_auth_on_api
Browse files Browse the repository at this point in the history
Add api keys for layers, documents and map
  • Loading branch information
Vampouille authored Jun 20, 2017
2 parents b7b0ad1 + 84dc5f2 commit 42fea37
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
44 changes: 44 additions & 0 deletions geonode/api/authorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
#
#########################################################################

from tastypie.authentication import ApiKeyAuthentication
from tastypie.authorization import DjangoAuthorization
from tastypie.exceptions import Unauthorized
from tastypie.compat import get_user_model, get_username_field

from guardian.shortcuts import get_objects_for_user
from tastypie.http import HttpUnauthorized


class GeoNodeAuthorization(DjangoAuthorization):
Expand Down Expand Up @@ -69,3 +72,44 @@ def delete_detail(self, object_list, bundle):
return bundle.request.user.has_perm(
'delete_resourcebase',
bundle.obj.get_self_resource())


class GeonodeApiKeyAuthentication(ApiKeyAuthentication):
"""
Override ApiKeyAuthentication to prevent 401 response when no api key is provided.
"""

def is_authenticated(self, request, **kwargs):
"""
Finds the user and checks their API key.
Should return either ``True`` if allowed, ``False`` if not or an
``HttpResponse`` if you need something custom.
"""

try:
username, api_key = self.extract_credentials(request)
except ValueError:
return self._unauthorized()

if not username or not api_key:
return True

username_field = get_username_field()
User = get_user_model()

try:
lookup_kwargs = {username_field: username}
user = User.objects.get(**lookup_kwargs)
except (User.DoesNotExist, User.MultipleObjectsReturned):
return self._unauthorized()

if not self.check_active(user):
return False

key_auth_check = self.get_key(user, api_key)
if key_auth_check and not isinstance(key_auth_check, HttpUnauthorized):
request.user = user

return key_auth_check

8 changes: 7 additions & 1 deletion geonode/api/resourcebase_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from django.db.models import Q
from django.http import HttpResponse
from django.conf import settings
from tastypie.authentication import MultiAuthentication, SessionAuthentication

from tastypie.constants import ALL, ALL_WITH_RELATIONS
from tastypie.resources import ModelResource
Expand All @@ -43,7 +44,7 @@
from geonode.base.models import ResourceBase
from geonode.base.models import HierarchicalKeyword

from .authorization import GeoNodeAuthorization
from .authorization import GeoNodeAuthorization, GeonodeApiKeyAuthentication

from .api import TagResource, RegionResource, OwnersResource
from .api import ThesaurusKeywordResource
Expand Down Expand Up @@ -565,6 +566,7 @@ class Meta(CommonMetaApi):
queryset = queryset.filter(is_published=True)
resource_name = 'base'
excludes = ['csw_anytext', 'metadata_xml']
authentication = MultiAuthentication(SessionAuthentication(), GeonodeApiKeyAuthentication())


class FeaturedResourceBaseResource(CommonModelApi):
Expand All @@ -576,6 +578,7 @@ class Meta(CommonMetaApi):
if settings.RESOURCE_PUBLISHING:
queryset = queryset.filter(is_published=True)
resource_name = 'featured'
authentication = MultiAuthentication(SessionAuthentication(), GeonodeApiKeyAuthentication())


class LayerResource(CommonModelApi):
Expand All @@ -588,6 +591,7 @@ class Meta(CommonMetaApi):
queryset = queryset.filter(is_published=True)
resource_name = 'layers'
excludes = ['csw_anytext', 'metadata_xml']
authentication = MultiAuthentication(SessionAuthentication(), GeonodeApiKeyAuthentication())


class MapResource(CommonModelApi):
Expand All @@ -599,6 +603,7 @@ class Meta(CommonMetaApi):
if settings.RESOURCE_PUBLISHING:
queryset = queryset.filter(is_published=True)
resource_name = 'maps'
authentication = MultiAuthentication(SessionAuthentication(), GeonodeApiKeyAuthentication())


class DocumentResource(CommonModelApi):
Expand All @@ -612,3 +617,4 @@ class Meta(CommonMetaApi):
if settings.RESOURCE_PUBLISHING:
queryset = queryset.filter(is_published=True)
resource_name = 'documents'
authentication = MultiAuthentication(SessionAuthentication(), GeonodeApiKeyAuthentication())

0 comments on commit 42fea37

Please sign in to comment.