Mercurial > wikked
view wikked/views/__init__.py @ 368:831b22e93f94 0.6.3
Implement error and permission handling for UI views.
* Views are protected by decorators.
* Decorators check for permission errors and render error pages.
* Global Flask error handling is for API endpoints.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Tue, 22 Sep 2015 03:17:21 -0700 |
parents | 425c3047394d |
children | ba977a547daa |
line wrap: on
line source
import functools from flask import request, render_template from flask.ext.login import current_user from wikked.web import app, get_wiki from wikked.webimpl import PermissionError def show_unauthorized_error(error=None, error_details=None, tpl_name=None): if error is not None: error = str(error) data = {} if error: data['error'] = error if error_details: data['error_details'] = error_details add_auth_data(data) add_navigation_data(None, data) tpl_name = tpl_name or 'error-unauthorized.html' return render_template(tpl_name, **data) def errorhandling_ui(f): @functools.wraps(f) def wrapper(*args, **kwargs): try: return f(*args, **kwargs) except PermissionError as ex: return show_unauthorized_error(ex) return wrapper def errorhandling_ui2(tpl_name): def decorator(f): @functools.wraps(f) def wrapper(*args, **kwargs): try: return f(*args, **kwargs) except PermissionError as ex: return show_unauthorized_error(ex, tpl_name=tpl_name) return wrapper return decorator def requires_reader_auth(f): @functools.wraps(f) def wrapper(*args, **kwargs): wiki = get_wiki() if not wiki.auth.hasPermission('readers', current_user.get_id()): return show_unauthorized_error() return f(*args, **kwargs) return wrapper def add_auth_data(data): username = current_user.get_id() if current_user.is_authenticated(): user_page_url = 'user:/%s' % username.title() data['auth'] = { 'is_logged_in': True, 'username': username, 'is_admin': current_user.is_admin(), 'url_logout': '/logout', 'url_profile': '/read/%s' % user_page_url } else: data['auth'] = { 'is_logged_in': False, 'url_login': '/login' } def add_navigation_data( url, data, read=False, edit=False, history=False, inlinks=False, raw_url=None, extras=None, footers=None): if url is not None: url = url.lstrip('/') elif read or edit or history or inlinks: raise Exception("Default navigation entries require a valid URL.") nav = {'home': '/', 'extras': [], 'footers': []} nav['is_menu_active'] = ( request.cookies.get('wiki-menu-active') == '1') if read: nav['url_read'] = '/read/%s' % url if edit: nav['url_edit'] = '/edit/%s' % url if history: nav['url_hist'] = '/hist/%s' % url if inlinks: nav['extras'].append({ 'title': "Pages Linking Here", 'url': '/inlinks/' + url, 'icon': 'link' }) if raw_url: nav['footers'].append({ 'title': "RAW", 'url': raw_url, 'icon': 'wrench' }) nav['extras'].append({ 'title': "Special Pages", 'url': '/special', 'icon': 'dashboard'}) if extras: nav['extras'] = [{'title': e[0], 'url': e[1], 'icon': e[2]} for e in extras] if footers: nav['footers'] = [{'title': f[0], 'url': f[1], 'icon': f[2]} for f in footers] data['nav'] = nav if app.config['WIKI_DEV_ASSETS']: data['is_dev'] = True