Merge remote-tracking branch 'refs/remotes/elrond/sql/final'
[mediagoblin.git] / mediagoblin / decorators.py
index c6b4b545109b749ec69f5a6653684c593e3d64bf..83602c7063c1d3dd64fed18b2fe8a979c7e5b378 100644 (file)
@@ -1,5 +1,5 @@
 # GNU MediaGoblin -- federated, autonomous media hosting
-# Copyright (C) 2011 Free Software Foundation, Inc
+# Copyright (C) 2011, 2012 MediaGoblin contributors.  See AUTHORS.
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as published by
@@ -17,6 +17,9 @@
 
 from webob import exc
 
+from mediagoblin.tools.response import redirect, render_404
+from mediagoblin.db.util import ObjectId, InvalidId
+
 
 def _make_safe(decorator, original):
     """
@@ -33,12 +36,105 @@ def require_active_login(controller):
     Require an active login from the user.
     """
     def new_controller_func(request, *args, **kwargs):
-        if not request.user or not request.user.get('session') == 'active':
-            # TODO: Indicate to the user that they were redirected
-            # here because an *active* user is required.
+        if request.user and \
+                request.user.get('status') == u'needs_email_verification':
+            return redirect(
+                request, 'mediagoblin.user_pages.user_home',
+                user=request.user.username)
+        elif not request.user or request.user.get('status') != u'active':
             return exc.HTTPFound(
-                location=request.urlgen("mediagoblin.auth.login"))
+                location="%s?next=%s" % (
+                    request.urlgen("mediagoblin.auth.login"),
+                    request.full_path))
 
         return controller(request, *args, **kwargs)
 
     return _make_safe(new_controller_func, controller)
+
+
+def user_may_delete_media(controller):
+    """
+    Require user ownership of the MediaEntry to delete.
+    """
+    def wrapper(request, *args, **kwargs):
+        uploader_id = request.db.MediaEntry.find_one(
+            {'_id': ObjectId(request.matchdict['media'])}).uploader
+        if not (request.user.is_admin or
+                request.user._id == uploader_id):
+            return exc.HTTPForbidden()
+
+        return controller(request, *args, **kwargs)
+
+    return _make_safe(wrapper, controller)
+
+
+def uses_pagination(controller):
+    """
+    Check request GET 'page' key for wrong values
+    """
+    def wrapper(request, *args, **kwargs):
+        try:
+            page = int(request.GET.get('page', 1))
+            if page < 0:
+                return render_404(request)
+        except ValueError:
+            return render_404(request)
+
+        return controller(request, page=page, *args, **kwargs)
+
+    return _make_safe(wrapper, controller)
+
+
+def get_user_media_entry(controller):
+    """
+    Pass in a MediaEntry based off of a url component
+    """
+    def wrapper(request, *args, **kwargs):
+        user = request.db.User.find_one(
+            {'username': request.matchdict['user']})
+
+        if not user:
+            return render_404(request)
+        media = request.db.MediaEntry.find_one(
+            {'slug': request.matchdict['media'],
+             'state': 'processed',
+             'uploader': user._id})
+
+        # no media via slug?  Grab it via ObjectId
+        if not media:
+            try:
+                media = request.db.MediaEntry.find_one(
+                    {'_id': ObjectId(request.matchdict['media']),
+                     'state': 'processed',
+                     'uploader': user._id})
+            except InvalidId:
+                return render_404(request)
+
+            # Still no media?  Okay, 404.
+            if not media:
+                return render_404(request)
+
+        return controller(request, media=media, *args, **kwargs)
+
+    return _make_safe(wrapper, controller)
+
+
+def get_media_entry_by_id(controller):
+    """
+    Pass in a MediaEntry based off of a url component
+    """
+    def wrapper(request, *args, **kwargs):
+        try:
+            media = request.db.MediaEntry.find_one(
+                {'_id': ObjectId(request.matchdict['media']),
+                 'state': 'processed'})
+        except InvalidId:
+            return render_404(request)
+
+        # Still no media?  Okay, 404.
+        if not media:
+            return render_404(request)
+
+        return controller(request, media=media, *args, **kwargs)
+
+    return _make_safe(wrapper, controller)