X-Git-Url: http://git.cascardo.info/?p=cascardo%2Fipsilon.git;a=blobdiff_plain;f=ipsilon%2Futil%2Fpage.py;h=1548d47f1fbb7e4cc34312a585be672aba7fa542;hp=7dda1d742a94f43af62b2716673d0d97ada1445d;hb=3f7e6358c02d0822c5fe1c2da72a3b32ffe12ec6;hpb=667901638f082e05b4ac61a14f4ddc07ec987742 diff --git a/ipsilon/util/page.py b/ipsilon/util/page.py index 7dda1d7..1548d47 100755 --- a/ipsilon/util/page.py +++ b/ipsilon/util/page.py @@ -17,7 +17,9 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +from ipsilon.util.log import Log from ipsilon.util.user import UserSession +from urllib import unquote import cherrypy @@ -32,17 +34,31 @@ def admin_protect(fn): return check -def protect(): - UserSession().remote_login() +def auth_protect(fn): + def check(self, *args, **kwargs): + if UserSession().get_user().is_anonymous: + raise cherrypy.HTTPRedirect(self.basepath) + else: + return fn(self, *args, **kwargs) + + return check -class Page(object): - def __init__(self, site): - if not 'template_env' in site: +class Page(Log): + def __init__(self, site, form=False): + if 'template_env' not in site: raise ValueError('Missing template environment') self._site = site self.basepath = cherrypy.config.get('base.mount', "") self.user = None + self._is_form_page = form + + def _compare_urls(self, url1, url2): + u1 = unquote(url1) + u2 = unquote(url2) + if u1 == u2: + return True + return False def __call__(self, *args, **kwargs): # pylint: disable=star-args @@ -50,12 +66,30 @@ class Page(object): if len(args) > 0: op = getattr(self, args[0], None) - if callable(op) and getattr(self, args[0]+'.exposed', None): + if callable(op) and getattr(op, 'public_function', None): return op(*args[1:], **kwargs) else: - op = getattr(self, 'root', None) - if callable(op): - return op(*args, **kwargs) + if self._is_form_page: + self._debug("method: %s" % cherrypy.request.method) + op = getattr(self, cherrypy.request.method, None) + if callable(op): + # Basic CSRF protection + if cherrypy.request.method != 'GET': + url = cherrypy.url(relative=False) + if 'referer' not in cherrypy.request.headers: + self._debug("Missing referer in %s request to %s" + % (cherrypy.request.method, url)) + raise cherrypy.HTTPError(403) + referer = cherrypy.request.headers['referer'] + if not self._compare_urls(referer, url): + self._debug("Wrong referer %s in request to %s" + % (referer, url)) + raise cherrypy.HTTPError(403) + return op(*args, **kwargs) + else: + op = getattr(self, 'root', None) + if callable(op): + return op(*args, **kwargs) return self.default(*args, **kwargs) @@ -73,11 +107,13 @@ class Page(object): m.update(kwargs) return t.render(**m) - def _debug(self, fact): - if cherrypy.config.get('debug', False): - cherrypy.log(fact) - def default(self, *args, **kwargs): raise cherrypy.HTTPError(404) + def add_subtree(self, name, page): + self.__dict__[name] = page + + def del_subtree(self, name): + del self.__dict__[name] + exposed = True