@allowed_methods to check for correct HTTP method
authorStefan Koegl <stefan@skoegl.net>
Thu, 16 Sep 2010 12:33:26 +0000 (16 15:33 +0300)
committerStefan Koegl <stefan@skoegl.net>
Thu, 16 Sep 2010 12:33:26 +0000 (16 15:33 +0300)
14 files changed:
mygpo/api/advanced/__init__.py
mygpo/api/advanced/auth.py
mygpo/api/advanced/directory.py
mygpo/api/advanced/episode.py
mygpo/api/advanced/settings.py
mygpo/api/simple.py
mygpo/decorators.py
mygpo/publisher/views.py
mygpo/web/views/device.py
mygpo/web/views/episode.py
mygpo/web/views/podcast.py
mygpo/web/views/public.py
mygpo/web/views/settings.py
mygpo/web/views/users.py

index 83fcaf8..902399d 100644 (file)
@@ -16,7 +16,7 @@
 #
 
 from mygpo.api.basic_auth import require_valid_user, check_username
-from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, Http404, HttpResponseNotAllowed
+from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, Http404
 from mygpo.api.models import Device, Podcast, SubscriptionAction, Episode, EpisodeAction, SUBSCRIBE_ACTION, UNSUBSCRIBE_ACTION, EPISODE_ACTION_TYPES, DEVICE_TYPES, Subscription
 from mygpo.api.models.users import EpisodeFavorite
 from mygpo.api.httpresponse import JsonResponse
@@ -30,6 +30,7 @@ from datetime import datetime, timedelta
 import dateutil.parser
 from mygpo.log import log
 from mygpo.utils import parse_time, parse_bool
+from mygpo.decorators import allowed_methods
 from django.db import IntegrityError
 import re
 from django.views.decorators.csrf import csrf_exempt
@@ -51,6 +52,7 @@ except ImportError:
 @csrf_exempt
 @require_valid_user
 @check_username
+@allowed_methods(['GET', 'POST'])
 def subscriptions(request, username, device_uid):
 
     now = datetime.now()
@@ -94,9 +96,6 @@ def subscriptions(request, username, device_uid):
             'update_urls': update_urls,
             })
 
-    else:
-        return HttpResponseNotAllowed(['GET', 'POST'])
-
 
 def update_subscriptions(user, device, add, remove):
     updated_urls = []
@@ -156,6 +155,7 @@ def get_subscription_changes(user, device, since, until):
 @csrf_exempt
 @require_valid_user
 @check_username
+@allowed_methods(['GET', 'POST'])
 def episodes(request, username, version=1):
 
     version = int(version)
@@ -193,9 +193,6 @@ def episodes(request, username, version=1):
 
         return JsonResponse(get_episode_changes(request.user, podcast, device, since, now, aggregated, version))
 
-    else:
-        return HttpResponseNotAllowed(['POST', 'GET'])
-
 
 def get_episode_changes(user, podcast, device, since, until, aggregated, version):
     if aggregated:
@@ -325,34 +322,32 @@ def update_episodes(user, actions):
 @csrf_exempt
 @require_valid_user
 @check_username
+# Workaround for mygpoclient 1.0: It uses "PUT" requests
+# instead of "POST" requests for uploading device settings
+@allowed_methods(['POST', 'PUT'])
 def device(request, username, device_uid):
 
-    # Workaround for mygpoclient 1.0: It uses "PUT" requests
-    # instead of "POST" requests for uploading device settings
-    if request.method in ('POST', 'PUT'):
-        d, created = Device.objects.get_or_create(user=request.user, uid=device_uid)
+    d, created = Device.objects.get_or_create(user=request.user, uid=device_uid)
 
-        #undelete a previously deleted device
-        if d.deleted:
-            d.deleted = False
-            d.save()
+    #undelete a previously deleted device
+    if d.deleted:
+        d.deleted = False
+        d.save()
 
-        data = json.loads(request.raw_post_data)
+    data = json.loads(request.raw_post_data)
 
-        if 'caption' in data:
-            d.name = data['caption']
+    if 'caption' in data:
+        d.name = data['caption']
 
-        if 'type' in data:
-            if not valid_devicetype(data['type']):
-                return HttpResponseBadRequest('invalid device type %s' % data['type'])
-            d.type = data['type']
+    if 'type' in data:
+        if not valid_devicetype(data['type']):
+           return HttpResponseBadRequest('invalid device type %s' % data['type'])
+        d.type = data['type']
 
-        d.save()
+    d.save()
 
-        return HttpResponse()
+    return HttpResponse()
 
-    else:
-        return HttpResponseNotAllowed(['POST'])
 
 def valid_devicetype(type):
     for t in DEVICE_TYPES:
@@ -370,22 +365,18 @@ def valid_episodeaction(type):
 @csrf_exempt
 @require_valid_user
 @check_username
+@allowed_methods(['GET'])
 def devices(request, username):
-
-    if request.method == 'GET':
-        devices = []
-        for d in Device.objects.filter(user=request.user, deleted=False):
-            devices.append({
-                'id': d.uid,
-                'caption': d.name,
-                'type': d.type,
-                'subscriptions': Subscription.objects.filter(device=d).count()
-            })
-
-        return JsonResponse(devices)
-
-    else:
-        return HttpResponseNotAllowed(['GET'])
+    devices = []
+    for d in Device.objects.filter(user=request.user, deleted=False):
+        devices.append({
+            'id': d.uid,
+            'caption': d.name,
+            'type': d.type,
+            'subscriptions': Subscription.objects.filter(device=d).count()
+        })
+
+    return JsonResponse(devices)
 
 
 @csrf_exempt
index 8ba2d73..1571133 100644 (file)
@@ -18,7 +18,7 @@
 from django.contrib.auth.models import User
 from mygpo.api.basic_auth import require_valid_user, check_username
 from django.contrib import auth
-from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, Http404, HttpResponseNotAllowed
+from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, Http404
 from mygpo.api.httpresponse import JsonResponse
 from mygpo.web.models import SecurityToken
 from django.shortcuts import get_object_or_404
index 28f0d15..ffe1b04 100644 (file)
@@ -16,7 +16,7 @@
 #
 
 from mygpo.api.basic_auth import require_valid_user, check_username
-from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, Http404, HttpResponseNotAllowed
+from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, Http404
 from mygpo.api.httpresponse import JsonResponse
 from mygpo.exceptions import ParameterMissing
 from django.shortcuts import get_object_or_404
index 7c5236d..9e03b32 100644 (file)
@@ -16,7 +16,7 @@
 #
 
 from mygpo.api.basic_auth import require_valid_user, check_username
-from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, Http404, HttpResponseNotAllowed
+from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, Http404
 from mygpo.api.httpresponse import JsonResponse
 from mygpo.exceptions import ParameterMissing
 from django.shortcuts import get_object_or_404
@@ -27,6 +27,7 @@ from django.utils.translation import ugettext as _
 from datetime import datetime, timedelta
 from mygpo.log import log
 from mygpo.utils import parse_time
+from mygpo.decorators import allowed_methods
 import dateutil.parser
 from django.views.decorators.csrf import csrf_exempt
 
@@ -47,6 +48,7 @@ except ImportError:
 @csrf_exempt
 @require_valid_user
 @check_username
+@allowed_methods(['POST', 'GET'])
 def chapters(request, username):
 
     now = datetime.now()
@@ -124,10 +126,6 @@ def chapters(request, username):
             'timestamp': now_
             })
 
-    else:
-        return HttpResponseNotAllowed(['GET', 'POST'])
-
-
 
 def update_chapters(req, user):
     podcast, c = Podcast.objects.get_or_create(url=req['podcast'])
index 946571e..d7af679 100644 (file)
 #
 
 from mygpo.api.basic_auth import require_valid_user, check_username
-from django.http import HttpResponseBadRequest, HttpResponseNotAllowed
+from django.http import HttpResponseBadRequest
 from mygpo.api.httpresponse import JsonResponse
 from django.shortcuts import get_object_or_404
 from mygpo.api.models import Device, UserProfile, SubscriptionMeta, EpisodeSettings
 from django.views.decorators.csrf import csrf_exempt
+from mygpo.decorators import allowed_methods
 import json
 
 
 @csrf_exempt
 @require_valid_user
 @check_username
+@allowed_methods(['GET', 'POST'])
 def main(request, username, scope):
 
     models = dict(
@@ -50,9 +52,6 @@ def main(request, username, scope):
         actions = json.loads(request.raw_post_data)
         return JsonResponse( update_settings(obj, actions) )
 
-    else:
-        return HttpResponseNotAllowed(['GET', 'POST'])
-
 
 def update_settings(obj, actions):
     for key, value in actions.get('set', {}).iteritems():
index 2b58d6b..d396967 100644 (file)
@@ -16,7 +16,7 @@
 #
 
 from mygpo.api.basic_auth import require_valid_user, check_username
-from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseNotAllowed
+from django.http import HttpResponse, HttpResponseBadRequest
 from mygpo.api.models import Device, SubscriptionAction, Podcast, SUBSCRIBE_ACTION, UNSUBSCRIBE_ACTION, SuggestionEntry
 from mygpo.api.opml import Exporter, Importer
 from mygpo.api.httpresponse import JsonResponse
@@ -26,6 +26,7 @@ from django.views.decorators.csrf import csrf_exempt
 from django.shortcuts import get_object_or_404
 from mygpo.search.models import SearchEntry
 from django.utils.translation import ugettext as _
+from mygpo.decorators import allowed_methods
 
 
 try:
@@ -54,6 +55,7 @@ def check_format(fn):
 @require_valid_user
 @check_username
 @check_format
+@allowed_methods(['GET', 'PUT', 'POST'])
 def subscriptions(request, username, device_uid, format):
 
     if request.method == 'GET':
@@ -65,18 +67,13 @@ def subscriptions(request, username, device_uid, format):
         subscriptions = parse_subscription(request.raw_post_data, format)
         return set_subscriptions(subscriptions, request.user, device_uid)
 
-    else:
-        return HttpResponseNotAllowed(['GET', 'PUT', 'POST'])
-
 
 @csrf_exempt
 @require_valid_user
 @check_username
 @check_format
+@allowed_methods(['GET'])
 def all_subscriptions(request, username, format):
-    if request.method != 'GET':
-        return HttpResponseNotAllowed(['GET'])
-
     subscriptions = get_all_subscriptions(request.user)
     title = _('%(username)s\'s Subscription List') % {'username': username}
     return format_podcast_list(subscriptions, format, title)
@@ -170,10 +167,8 @@ def set_subscriptions(urls, user, device_uid):
 
 
 @check_format
+@allowed_methods(['GET'])
 def toplist(request, count, format):
-    if request.method != 'GET':
-        return HttpResponseNotAllowed(['GET'])
-
     if int(count) not in range(1,100):
         count = 100
 
@@ -192,10 +187,8 @@ def toplist(request, count, format):
 
 
 @check_format
+@allowed_methods(['GET'])
 def search(request, format):
-    if request.method != 'GET':
-        return HttpResponseNotAllowed(['GET'])
-
     query = request.GET.get('q', '').encode('utf-8')
 
     if not query:
@@ -210,10 +203,8 @@ def search(request, format):
 
 @require_valid_user
 @check_format
+@allowed_methods(['GET'])
 def suggestions(request, count, format):
-    if request.method != 'GET':
-        return HttpResponseNotAllowed(['GET'])
-
     if int(count) not in range(1,100):
         count = 100
 
index 63139ca..d981880 100644 (file)
@@ -21,7 +21,7 @@ from django.shortcuts import render_to_response
 from django.template import RequestContext
 from mygpo.web.models import SecurityToken
 from django.contrib.auth.models import User
-from django.http import Http404, HttpResponseForbidden
+from django.http import Http404, HttpResponseForbidden, HttpResponseNotAllowed
 import random
 import string
 import gc
@@ -78,3 +78,16 @@ def manual_gc(view):
 
     return tmp
 
+
+def allowed_methods(methods):
+    def decorator(fn):
+        def tmp(request, *args, **kwargs):
+            if request.method in methods:
+                return fn(request, *args, **kwargs)
+            else:
+                return HttpResponseNotAllowed(methods)
+
+        return tmp
+
+    return decorator
+
index d9fe0e1..3b43fae 100644 (file)
@@ -9,7 +9,7 @@ from mygpo.publisher.forms import SearchPodcastForm, EpisodeForm, PodcastForm
 from mygpo.publisher.utils import listener_data, episode_listener_data, check_publisher_permission, episode_list, subscriber_data, device_stats, episode_heatmap
 from django.contrib.sites.models import Site
 from mygpo.data.feeddownloader import update_podcasts
-from mygpo.decorators import requires_token
+from mygpo.decorators import requires_token, allowed_methods
 from mygpo.web.models import SecurityToken
 from django.contrib.auth.models import User
 
@@ -43,6 +43,7 @@ def search_podcast(request):
         return HttpResponseRedirect('/publisher/')
 
 @require_publisher
+@allowed_methods(['GET', 'POST'])
 def podcast(request, id):
     p = get_object_or_404(Podcast, pk=id)
 
@@ -141,6 +142,7 @@ def episodes(request, id):
 
 
 @require_publisher
+@allowed_methods(['GET', 'POST'])
 def episode(request, id):
     e = get_object_or_404(Episode, pk=id)
 
index 9274651..774e59d 100644 (file)
@@ -16,7 +16,7 @@
 #
 
 from django.shortcuts import render_to_response
-from django.http import HttpResponseRedirect, HttpResponse, HttpResponseBadRequest, HttpResponseNotAllowed, Http404, HttpResponseForbidden
+from django.http import HttpResponseRedirect, HttpResponse, HttpResponseBadRequest, Http404, HttpResponseForbidden
 from django.contrib.auth.models import User
 from django.template import RequestContext
 from mygpo.api.models import Podcast, Episode, Device, EpisodeAction, SubscriptionAction, ToplistEntry, EpisodeToplistEntry, Subscription, SuggestionEntry, SyncGroup, SUBSCRIBE_ACTION, UNSUBSCRIBE_ACTION, SubscriptionMeta
@@ -33,7 +33,7 @@ from mygpo.api.sanitizing import sanitize_url
 from mygpo.log import log
 from mygpo.utils import daterange
 from mygpo.api import simple
-from mygpo.decorators import manual_gc
+from mygpo.decorators import manual_gc, allowed_methods
 import re
 import random
 import string
@@ -76,6 +76,7 @@ def show(request, device_id, error_message=None):
 
 
 @login_required
+@allowed_methods(['GET', 'POST'])
 def edit(request, device_id):
 
     device = get_object_or_404(Device, id=device_id, user=request.user)
@@ -125,10 +126,8 @@ def opml(request, device_id):
 
 @manual_gc
 @login_required
+@allowed_methods(['POST'])
 def delete(request, device_id):
-    if request.method != 'POST':
-        return HttpResponseNotAllowed(['POST'])
-
     device = Device.objects.get(pk=device_id)
     device.deleted = True
     device.save()
@@ -161,11 +160,8 @@ def undelete(request, device_id):
 
 @manual_gc
 @login_required
+@allowed_methods(['POST'])
 def sync(request, device_id):
-
-    if request.method != 'POST':
-        return HttpResponseNotAllowed(['POST'])
-
     form = SyncForm(request.POST)
     if not form.is_valid():
         return HttpResponseBadRequest('invalid')
@@ -184,10 +180,8 @@ def sync(request, device_id):
 
 @manual_gc
 @login_required
+@allowed_methods(['GET'])
 def unsync(request, device_id):
-    if request.method != 'GET':
-        return HttpResponseNotAllowed(['GET'])
-
     dev = Device.objects.get(pk=device_id)
 
     try:
index 86d40ad..4e5aa33 100644 (file)
@@ -16,7 +16,7 @@
 #
 
 from django.shortcuts import render_to_response
-from django.http import HttpResponseRedirect, HttpResponse, HttpResponseBadRequest, HttpResponseNotAllowed, Http404, HttpResponseForbidden
+from django.http import HttpResponseRedirect, HttpResponse, HttpResponseBadRequest, Http404, HttpResponseForbidden
 from django.template import RequestContext
 from mygpo.api.models import Podcast, Episode, Device, EpisodeAction, Subscription
 from mygpo.api.models.episodes import Chapter
index 3f491c7..d310fb5 100644 (file)
@@ -11,13 +11,14 @@ from django.utils.translation import ugettext as _
 from mygpo.api.models import Podcast, Episode, EpisodeAction, Device, SubscriptionAction, Subscription, SUBSCRIBE_ACTION, UNSUBSCRIBE_ACTION, SyncGroup
 from mygpo.web.forms import PrivacyForm, SyncForm
 from mygpo.data.models import Listener, PodcastTag
-from mygpo.decorators import manual_gc
+from mygpo.decorators import manual_gc, allowed_methods
 from mygpo.utils import daterange
 
 
 MAX_TAGS_ON_PAGE=50
 
 
+@allowed_methods(['GET', 'POST'])
 def show(request, pid):
     podcast = get_object_or_404(Podcast, pk=pid)
     episodes = episode_list(podcast, request.user)
@@ -184,6 +185,7 @@ def remove_tag(request, pid):
 
 @manual_gc
 @login_required
+@allowed_methods(['GET', 'POST'])
 def subscribe(request, pid):
     podcast = get_object_or_404(Podcast, pk=pid)
     error_message = None
index 08e7d3a..ab31a07 100644 (file)
@@ -16,7 +16,7 @@
 #
 
 from django.shortcuts import render_to_response
-from django.http import HttpResponseRedirect, HttpResponse, HttpResponseBadRequest, HttpResponseNotAllowed, Http404, HttpResponseForbidden
+from django.http import HttpResponseRedirect, HttpResponse, HttpResponseBadRequest, Http404, HttpResponseForbidden
 from django.template import RequestContext
 from mygpo.api.models import Podcast, Episode, Subscription
 from mygpo.api import backend
index 454c672..3fe8533 100644 (file)
@@ -25,7 +25,7 @@ from mygpo.web.forms import UserAccountForm
 from django.forms import ValidationError
 from django.utils.translation import ugettext as _
 from mygpo.api.basic_auth import require_valid_user
-from mygpo.decorators import manual_gc
+from mygpo.decorators import manual_gc, allowed_methods
 from django.contrib.auth.decorators import login_required
 from django.shortcuts import get_object_or_404
 from django.contrib.sites.models import Site
@@ -33,6 +33,7 @@ from django.contrib.sites.models import Site
 
 @manual_gc
 @login_required
+@allowed_methods(['GET', 'POST'])
 def account(request):
     success = False
     error_message = ''
@@ -83,6 +84,7 @@ def account(request):
 
 @manual_gc
 @login_required
+@allowed_methods(['GET', 'POST'])
 def delete_account(request):
 
     if request.method == 'GET':
@@ -102,14 +104,9 @@ def delete_account(request):
 
 @manual_gc
 @login_required
+@allowed_methods(['GET'])
 def privacy(request):
 
-    if request.method == 'GET':
-        form = UserAccountForm({
-            'email': request.user.email,
-            'public': request.user.get_profile().public_profile
-            })
-
     if 'private_subscriptions' in request.GET:
         request.user.get_profile().settings['public_profile'] = False
         request.user.get_profile().save()
index e7a40a1..1ef577b 100644 (file)
@@ -27,7 +27,7 @@ from mygpo.api.models import UserProfile
 from mygpo.web.forms import RestorePasswordForm
 from django.contrib.sites.models import Site
 from django.conf import settings
-from mygpo.decorators import requires_token, manual_gc
+from mygpo.decorators import requires_token, manual_gc, allowed_methods
 from django.utils.translation import ugettext as _
 import string
 import random
@@ -135,11 +135,9 @@ def get_user(username, email):
     else:
         raise User.DoesNotExist('neither username nor email provided')
 
-def restore_password(request):
-
-    if request.method != 'POST':
-        return HttpResponseRedirect('/login/')
 
+@allowed_methods(['POST'])
+def restore_password(request):
     form = RestorePasswordForm(request.POST)
     if not form.is_valid():
         return HttpResponseRedirect('/login/')
@@ -164,6 +162,7 @@ def restore_password(request):
 
 
 @manual_gc
+@allowed_methods(['GET', 'POST'])
 def resend_activation(request):
     error_message = ''