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.
 #
 # 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.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
 
 
 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')
 
 
 
 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()
 
     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():
     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
 # -*- 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
 
 
 
 from api.handlers import BookHandler
 
 
-auth = HttpBasicAuthentication(realm='My sample API')
+auth = OAuthAuthentication(realm="Wolne Lektury")
 book_resource = Resource(handler=BookHandler, authentication=auth)
 
 
 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),
     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
 # 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
 
 from django.utils.translation import ugettext_lazy as _
 from slughifi import slughifi
 
@@ -12,7 +13,17 @@ from catalogue import utils
 
 
 class BookImportForm(forms.Form):
 
 
 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)
 
     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'),
 ]
 
     path.join(PROJECT_DIR, 'templates'),
 ]
 
-LOGIN_URL = '/uzytkownicy/zaloguj/'
+LOGIN_URL = '/uzytkownicy/login/'
 
 LOGIN_REDIRECT_URL = '/'
 
 
 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/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')),
 
     # API
     (r'^api/', include('api.urls')),