Major refactor of the access module
The first step to sanity is a leap into the unknown? Create an object
to represent the access checks for each module instead of a bunch of
loose functions.
Converted all views and params.py to use the new access checker.
Main differences:
* arguments to a checker can be passed by using a tuple
* checkers are referenced by string, rather than directly
* the Checker constructor handles merging with child views
Patch by: Sverre Rabbelier
#!/usr/bin/python2.5
#
# Copyright 2008 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Module contains sidebar related functions.
"""
__authors__ = [
'"Sverre Rabbelier" <sverre@rabbelier.nl>',
]
from soc.views import out_of_band
from soc.views.helper import access
import soc.cache.sidebar
SIDEBAR = []
SIDEBAR_ACCESS_ARGS = ['SIDEBAR_CALLING']
SIDEBAR_ACCESS_KWARGS = {'SIDEBAR_CALLING': True}
def addMenu(callback):
"""Adds a callback to the menu builder.
The callback should return a list of menu's when called.
"""
global SIDEBAR
SIDEBAR.append(callback)
@soc.cache.sidebar.cache
def getSidebar():
"""Constructs a sidebar for the current user.
"""
sidebar = []
for callback in SIDEBAR:
menus = callback()
for menu in (menus if menus else []):
sidebar.append(menu)
return sidebar
def getSidebarItems(params):
"""Retrieves a list of sidebar entries for this view.
Params usage:
The params dictionary is provided to the menu_text's format.
sidebar: The sidebar value is returned directly if non-False
sidebar_defaults: The sidebar_defaults are used to construct the
sidebar items for this View. It is expected to be a tuple of
three items, the item's url, it's menu_text, and it's
access_type, see getSidebarMenus on how access_type is used.
sidebar_additional: The sidebar_additional values are appended
to the list of items verbatim, and should be in the format
expected by getSidebarMenus.
Args:
params: a dict with params for this View.
"""
# Return the found result
if params['sidebar']:
default = params['sidebar']
result = default[:]
for item in params['sidebar_additional']:
result.append(item)
return result
# Construct defaults manualy
defaults = params['sidebar_defaults']
result = []
for item in params['sidebar_additional']:
result.append(item)
for url, menu_text, access_type in defaults:
url = url % params['url_name'].lower()
item = (url, menu_text % params, access_type)
result.append(item)
return result
def getSidebarMenu(items, params):
"""Returns an dictionary with one sidebar entry.
Items is expected to be a tuple with an url, a menu_text, and an
access_type. The access_type is then passed to checkAccess, if it
raises out_of_band.Error, the item will not be added.
Args:
items: see above
params: a dict with params for this View
Params usage:
The params dictionary is passed as argument to getSidebarItems,
see the docstring of getSidebarItems on how it uses it.
rights: The rights dictionary is used to check if the user has
the required rights to see a sidebar item.
See checkAccess for more details on how the rights dictionary
is used to check access rights.
sidebar_heading: The sidebar_heading value is used to set the
heading variable in the result.
name: The name value is used if sidebar_heading is not present.
Returns:
A dictionary is returned with it's 'heading' value set as explained above.
It's 'items' value is constructed by calling _getSidebarItems. It constists
of dictionaries with a url and a title field.
"""
rights = params['rights']
submenus = []
args = SIDEBAR_ACCESS_ARGS
kwargs = SIDEBAR_ACCESS_KWARGS
for url, menu_text, access_type in items:
try:
rights.checkAccess(access_type, kwargs)
submenus.append({'url': url, 'title': menu_text})
except out_of_band.Error:
pass
return submenus
def getSidebarMenus(params=None):
"""Constructs the default sidebar menu for a View.
Calls getSidebarItems to retrieve the items that should be in the
menu. Then passes the result to getSidebarMenu. See the respective
docstrings for an explanation on what they do.
Args:
params: a dict with params for this View
"""
items = getSidebarItems(params)
submenus = getSidebarMenu(items, params)
if not submenus:
return
menu = {}
if 'sidebar_heading' not in params:
params['sidebar_heading'] = params['name']
menu['heading'] = params['sidebar_heading']
menu['items'] = submenus
menus = [menu]
return menus