api for redakcja (needs some testing and chrome)
authorRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Wed, 8 Jun 2011 11:15:32 +0000 (13:15 +0200)
committerRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Wed, 8 Jun 2011 11:15:32 +0000 (13:15 +0200)
apps/api/handlers.py
apps/api/templates/oauth/challenge.html [new file with mode: 0755]
apps/api/urls.py
apps/catalogue/forms.py
wolnelektury/settings.py
wolnelektury/templates/piston/authorize_token.html [new file with mode: 0755]
wolnelektury/templates/registration/login.html [new file with mode: 0755]
wolnelektury/urls.py

index 40121d6..ce29c61 100644 (file)
@@ -2,29 +2,43 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
+from functools import wraps
+
 from django.shortcuts import get_object_or_404
-from django.contrib.auth.decorators import login_required, user_passes_test
+from django.contrib.auth.decorators import login_required, permission_required
 from piston.handler import BaseHandler
 from piston.utils import rc, validate
 from catalogue.models import Book
 from catalogue.forms import BookImportForm
 
 
-staff_required = user_passes_test(lambda user: user.is_staff)
+def method_decorator(function_decorator):
+    """
+        Turns a function(*args, **kwargs) decorator into an
+        equivalent decorator for method(self, *args, **kwargs).
+    """
+    @wraps(function_decorator)
+    def decorator(method):
+        @wraps(method)
+        def decorated_method(self, *args, **kwargs):
+            def method_as_function(*fargs, **fkwargs):
+                return method(self, *fargs, **fkwargs)
+            return function_decorator(method_as_function)(*args, **kwargs)
+        return decorated_method
+    return decorator
 
 
 class BookHandler(BaseHandler):
     model = Book
     fields = ('slug', 'title')
 
-    @staff_required
     def read(self, request, slug=None):
         if slug:
             return get_object_or_404(Book, slug=slug)
         else:
             return Book.objects.all()
 
-    @staff_required
+    @method_decorator(permission_required('catalogue.add_book'))
     def create(self, request):
         form = BookImportForm(request.POST, request.FILES)
         if form.is_valid():
diff --git a/apps/api/templates/oauth/challenge.html b/apps/api/templates/oauth/challenge.html
new file mode 100755 (executable)
index 0000000..e69de29
index 8b1b9b0..d6f0dbf 100644 (file)
@@ -1,17 +1,22 @@
 # -*- coding: utf-8 -*-
 from django.conf.urls.defaults import *
 from piston.resource import Resource
-from piston.authentication import HttpBasicAuthentication
+from piston.authentication import OAuthAuthentication
 
 from api.handlers import BookHandler
 
 
-auth = HttpBasicAuthentication(realm='My sample API')
+auth = OAuthAuthentication(realm="Wolne Lektury")
 book_resource = Resource(handler=BookHandler, authentication=auth)
 
 
-urlpatterns = patterns('',
+urlpatterns = patterns('',  
     url(r'^books/(?P<slug>[^/]+)\.(?P<emitter_format>xml|json|yaml)$', book_resource),
     url(r'^books\.(?P<emitter_format>xml|json|yaml)$', book_resource),
-)
 
+) + patterns(
+    'piston.authentication',
+    url(r'^oauth/request_token/$','oauth_request_token'),
+    url(r'^oauth/authorize/$','oauth_user_auth'),
+    url(r'^oauth/access_token/$','oauth_access_token'),
+)
index fd75196..2bf974d 100644 (file)
@@ -3,6 +3,7 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django import forms
+from django.core.files.base import ContentFile
 from django.utils.translation import ugettext_lazy as _
 from slughifi import slughifi
 
@@ -12,7 +13,17 @@ from catalogue import utils
 
 
 class BookImportForm(forms.Form):
-    book_xml_file = forms.FileField()
+    book_xml_file = forms.FileField(required=False)
+    book_xml = forms.CharField(required=False)
+
+    def clean(self):
+        if not self.cleaned_data['book_xml_file']:
+            if self.cleaned_data['book_xml']:
+                self.cleaned_data['book_xml_file'] = \
+                        ContentFile(self.cleaned_data['book_xml'].encode('utf-8'))
+            else:
+                raise forms.ValidationError(_("Please supply an XML."))
+        return super(BookImportForm, self).clean()
 
     def save(self, commit=True, **kwargs):
         return Book.from_xml_file(self.cleaned_data['book_xml_file'], overwrite=True, **kwargs)
index a472763..2e20068 100644 (file)
@@ -110,7 +110,7 @@ TEMPLATE_DIRS = [
     path.join(PROJECT_DIR, 'templates'),
 ]
 
-LOGIN_URL = '/uzytkownicy/zaloguj/'
+LOGIN_URL = '/uzytkownicy/login/'
 
 LOGIN_REDIRECT_URL = '/'
 
diff --git a/wolnelektury/templates/piston/authorize_token.html b/wolnelektury/templates/piston/authorize_token.html
new file mode 100755 (executable)
index 0000000..ba28adc
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+  <head>
+    <title>Authorize Token</title>
+  </head>
+  <body>
+    <h1>Authorize Token</h1>
+
+    <form action="{% url piston.authentication.oauth_user_auth %}" method="POST">
+      {{ form.as_table }}
+      <button type="submit">Confirm</button>
+    </form>
+
+  </body>
+</html>
diff --git a/wolnelektury/templates/registration/login.html b/wolnelektury/templates/registration/login.html
new file mode 100755 (executable)
index 0000000..b88d4e1
--- /dev/null
@@ -0,0 +1,5 @@
+<form method="POST" action="">
+    {% csrf_token %}
+    {{ form }}
+<input type="submit" />
+</form>
index a99030f..340e58c 100644 (file)
@@ -40,6 +40,7 @@ urlpatterns = patterns('',
     url(r'^uzytkownicy/zaloguj/$', 'catalogue.views.login', name='login'),
     url(r'^uzytkownicy/wyloguj/$', 'catalogue.views.logout_then_redirect', name='logout'),
     url(r'^uzytkownicy/utworz/$', 'catalogue.views.register', name='register'),
+    url(r'^uzytkownicy/login/$', 'django.contrib.auth.views.login', name='simple_login'),
 
     # API
     (r'^api/', include('api.urls')),