def test_ordered_multidict_encoding(): """"Make sure URLs are properly encoded from OrderedMultiDicts""" d = OrderedMultiDict() d.add('foo', 1) d.add('foo', 2) d.add('foo', 3) d.add('bar', 0) d.add('foo', 4) assert url_encode(d) == 'foo=1&foo=2&foo=3&bar=0&foo=4'
class Admin(object): """Class that provides a way to add admin interface to Flask applications. :param app: The Flask application :param url_prefix: The url prefix :param main_dashboard: The main dashboard object :param endpoint: The endpoint """ def __init__(self, app, url_prefix="/admin", title="flask-dashed", main_dashboard=None, endpoint='admin'): if not main_dashboard: from dashboard import DefaultDashboard main_dashboard = DefaultDashboard self.blueprint = Blueprint(endpoint, __name__, static_folder='static', template_folder='templates') self.app = app self.url_prefix = url_prefix self.endpoint = endpoint self.title = title self.secure_functions = OrderedMultiDict() # Checks security for current path self.blueprint.before_request( lambda: self.check_path_security(request.path)) self.app.register_blueprint(self.blueprint, url_prefix=url_prefix) self.root_nodes = [] self._add_node(main_dashboard, '/', 'main-dashboard', 'dashboard') # Registers recursive_getattr filter self.app.jinja_env.filters['recursive_getattr'] = recursive_getattr def register_node(self, url_prefix, endpoint, short_title, title=None, parent=None, node_class=AdminNode): """Registers admin node. :param url_prefix: The url prefix :param endpoint: The endpoint :param short_title: The short title :param title: The long title :param parent: The parent node path :param node_class: The class for node objects """ return self._add_node(node_class, url_prefix, endpoint, short_title, title=title, parent=parent) def register_module(self, module_class, url_prefix, endpoint, short_title, title=None, parent=None): """Registers new module to current admin. """ return self._add_node(module_class, url_prefix, endpoint, short_title, title=title, parent=parent) def _add_node(self, node_class, url_prefix, endpoint, short_title, title=None, parent=None): """Registers new node object to current admin object. """ title = short_title if not title else title if parent and not issubclass(parent.__class__, AdminNode): raise Exception('`parent` class must be AdminNode subclass') new_node = node_class(self, url_prefix, endpoint, short_title, title=title, parent=parent) if parent: parent.children.append(new_node) else: self.root_nodes.append(new_node) return new_node @property def main_dashboard(self): return self.root_nodes[0] def add_path_security(self, path, function, http_code=403): """Registers security function for given path. :param path: The endpoint to secure :param function: The security function :param http_code: The response http code """ self.secure_functions.add(path, (function, http_code)) def check_path_security(self, path): """Checks security for specific and path. :param path: The path to check """ for key in self.secure_functions.iterkeys(): if path.startswith("%s%s" % (self.url_prefix, key)): for function, http_code in self.secure_functions.getlist(key): if not function(): return abort(http_code)