web: add a secure decorator to the auth module

This new decorator will make it easy to secure the render method
of twisted resources as we will be adding a fair few as more of
the interface moves to use ajax requests over json-rpc.
This commit is contained in:
Damien Churchill 2011-10-04 23:00:28 +01:00
parent 9362ec0103
commit eb9071fcb0
2 changed files with 28 additions and 8 deletions

View File

@ -51,11 +51,14 @@ import time
import random
import hashlib
import logging
from datetime import datetime, timedelta
from email.utils import formatdate
from types import FunctionType
from twisted.internet.defer import Deferred
from twisted.internet.task import LoopingCall
from twisted.web.http import FORBIDDEN
from deluge import component
from deluge.ui.web.json_api import JSONComponent, export
@ -89,6 +92,29 @@ def make_expires(timeout):
expires_str = formatdate(timeval=expires, localtime=False, usegmt=True)
return expires, expires_str
def secure(auth_level=AUTH_LEVEL_DEFAULT):
"""
Decorator function to secure a Twisted resource ensuring that the
user is authenticated with the web interface.
"""
def wrap(func, *args, **kwargs):
def secure_render(self, request):
try:
component.get("Auth").check_request(request,
level=auth_level)
except AuthError:
request.setResponseCode(FORBIDDEN)
return "<h1>Forbidden</h1>"
return func(self, request)
return secure_render
if type(auth_level) is FunctionType:
func = auth_level
auth_level = AUTH_LEVEL_DEFAULT
return wrap(func)
else:
return wrap
class Auth(JSONComponent):
"""
The component that implements authentification into the JSON interface.

View File

@ -53,7 +53,7 @@ from deluge import common, component, configmanager
from deluge.core.rpcserver import check_ssl_keys
from deluge.ui import common as uicommon
from deluge.ui.tracker_icons import TrackerIcons
from deluge.ui.web.auth import Auth, AuthError, AUTH_LEVEL_DEFAULT
from deluge.ui.web.auth import Auth, secure
from deluge.ui.web.common import Template, compress
from deluge.ui.web.json_api import JSON, WebApi
from deluge.ui.web.pluginmanager import PluginManager
@ -228,14 +228,8 @@ class Peers(TorrentResource):
"total": len(peers)
}, request)
@secure
def render(self, request):
try:
component.get("Auth").check_request(request,
level=AUTH_LEVEL_DEFAULT)
except AuthError:
request.setResponseCode(http.FORBIDDEN)
return '<h1>Forbidden</h1>'
component.get("SessionProxy"
).get_torrent_status(request.torrent_id, PEERS_KEYS
).addCallback(self.on_got_peers, request)