From 78ca607608ce52dd6b9b6b558306a99f3fc93882 Mon Sep 17 00:00:00 2001 From: Andrew Williams Date: Tue, 15 Jun 2010 21:05:53 +0100 Subject: [PATCH] Auth via API key, also added Admin interface to edit keys --- api/admin.py | 13 +++++++++++++ api/auth.py | 24 ++++++++++++++++++++++++ api/models.py | 21 ++++++++++++++++++--- api/urls.py | 4 +++- 4 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 api/admin.py create mode 100644 api/auth.py diff --git a/api/admin.py b/api/admin.py new file mode 100644 index 0000000..8b7dea5 --- /dev/null +++ b/api/admin.py @@ -0,0 +1,13 @@ +from django.contrib import admin +from api.models import AuthAPIKey, AuthAPILog + +class AuthAPIKeyAdmin(admin.ModelAdmin): + list_display = ('key', 'name', 'url', 'active') + search_fields = ['name'] + +admin.site.register(AuthAPIKey, AuthAPIKeyAdmin) + +class AuthAPILogAdmin(admin.ModelAdmin): + list_display = ('key', 'url', 'access_datetime') + +admin.site.register(AuthAPILog, AuthAPILogAdmin) diff --git a/api/auth.py b/api/auth.py new file mode 100644 index 0000000..1143fe6 --- /dev/null +++ b/api/auth.py @@ -0,0 +1,24 @@ +from django.http import HttpResponseForbidden +from django.contrib.auth.models import AnonymousUser +from api.models import AuthAPIKey + +class APIKeyAuthentication(object): + + def is_authenticated(self, request): + + apikey = request.GET.get('apikey', None) + if apikey: + try: + keyobj = AuthAPIKey.objects.get(key=apikey) + except: + keyobj = None + + if keyobj and keyobj.active: + request.user = AnonymousUser() + return True + + return False + + def challenge(self): + return HttpResponseForbidden('Access Denied, use a API Key') + diff --git a/api/models.py b/api/models.py index 7077e5f..1e13449 100644 --- a/api/models.py +++ b/api/models.py @@ -7,16 +7,31 @@ class AuthAPIKey(models.Model): name = models.CharField("Service Name", max_length=200) url = models.CharField("Service URL", max_length=200, blank=True) active = models.BooleanField(default=True) - key = models.CharField("API Key", max_length=200) + key = models.CharField("API Key", max_length=200, blank=True) def save(self, *args, **kwargs): - if not key or key == '': + if not self.key or self.key == '': self.key = uuid.uuid4() models.Model.save(self, *args, **kwargs) + def __unicode__(self): + return self.name + + def __str__(self): + return self.__unicode__() + + class Meta: + verbose_name = 'API Key' + verbose_name_plural = "API Keys" + class AuthAPILog(models.Model): - access_datetime = models.DateTimeField() + access_datetime = models.DateTimeField("Date/Time Accessed") key = models.ForeignKey(AuthAPIKey) url = models.CharField("Accessed URL", max_length=200) + + class Meta: + ordering = ['access_datetime'] + verbose_name = 'API Access Log' + verbose_name_plural = "API Access Logs" diff --git a/api/urls.py b/api/urls.py index 3ad2e40..3182177 100644 --- a/api/urls.py +++ b/api/urls.py @@ -2,14 +2,16 @@ from django.conf.urls.defaults import * from piston.resource import Resource from piston.authentication import HttpBasicAuthentication, OAuthAuthentication, NoAuthentication +from api.auth import APIKeyAuthentication from api.handlers import * oauth = { 'authentication': OAuthAuthentication() } noauth = { 'authentication': NoAuthentication() } +apikeyauth = { 'authentication': APIKeyAuthentication() } user_resource = Resource(handler=UserHandler, **oauth) login_resource = Resource(handler=LoginHandler, **noauth) -eveapi_resource = Resource(handler=EveAPIHandler, **noauth) +eveapi_resource = Resource(handler=EveAPIHandler, **apikeyauth) urlpatterns = patterns('', url(r'^user/$', user_resource),