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
--- a/app/soc/views/helper/access.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/helper/access.py Mon Jan 26 23:32:10 2009 +0000
@@ -74,433 +74,475 @@
'The requested Group can not be found')
-def checkAccess(access_type, rights, kwargs=None):
- """Runs all the defined checks for the specified type.
-
- Args:
- access_type: the type of request (such as 'list' or 'edit')
- rights: a dictionary containing access check functions
- kwargs: a dictionary with django's arguments
-
- Rights usage:
- The rights dictionary is used to check if the current user is allowed
- to view the page specified. The functions defined in this dictionary
- are always called with the provided kwargs dictionary as argument. On any
- request, regardless of what type, the functions in the 'any_access' value
- are called. If the specified type is not in the rights dictionary, all
- the functions in the 'unspecified' value are called. When the specified
- type _is_ in the rights dictionary, all the functions in that access_type's
- value are called.
+def denySidebar(fun):
+ """Decorator that denies access if the sidebar is calling.
"""
- # Call each access checker
- for check in rights['any_access']:
- check(kwargs)
-
- if access_type not in rights:
- for check in rights['unspecified']:
- # No checks defined, so do the 'generic' checks and bail out
- check(kwargs)
- return
-
- for check in rights[access_type]:
- check(kwargs)
-
-
-def allow(kwargs):
- """Never raises an alternate HTTP response. (an access no-op, basically).
-
- Args:
- kwargs: a dictionary with django's arguments
- """
-
- return
-
-
-def deny(kwargs):
- """Always raises an alternate HTTP response.
+ from functools import wraps
- Args:
- kwargs: a dictionary with django's arguments
-
- Raises:
- always raises AccessViolationResponse if called
- """
-
- import soc.views.helper.responses
-
- context = kwargs.get('context', {})
- context['title'] = 'Access denied'
-
- raise out_of_band.AccessViolation(DEF_PAGE_DENIED_MSG, context=context)
-
-
-def checkIsLoggedIn(kwargs):
- """Raises an alternate HTTP response if Google Account is not logged in.
-
- Args:
- kwargs: a dictionary with django's arguments
-
- Raises:
- AccessViolationResponse:
- * if no Google Account is even logged in
- """
-
- if users.get_current_user():
- return
-
- raise out_of_band.LoginRequest()
+ @wraps(fun)
+ def wrapper(self, django_args, *args, **kwargs):
+ if django_args.get('SIDEBAR_CALLING'):
+ raise out_of_band.Error("Sidebar Calling")
+ return fun(self, django_args, *args, **kwargs)
+ return wrapper
-def checkNotLoggedIn(kwargs):
- """Raises an alternate HTTP response if Google Account is logged in.
-
- Args:
- kwargs: a dictionary with django's arguments
-
- Raises:
- AccessViolationResponse:
- * if a Google Account is currently logged in
+class Checker(object):
"""
-
- if not users.get_current_user():
- return
-
- raise out_of_band.LoginRequest(message_fmt=DEF_LOGOUT_MSG_FMT)
-
-
-def checkIsUser(kwargs):
- """Raises an alternate HTTP response if Google Account has no User entity.
-
- Args:
- kwargs: a dictionary with django's arguments
-
- Raises:
- AccessViolationResponse:
- * if no User exists for the logged-in Google Account, or
- * if no Google Account is logged in at all
- """
-
- checkIsLoggedIn(kwargs)
-
- user = user_logic.getForCurrentAccount()
-
- if user:
- return
-
- raise out_of_band.LoginRequest(message_fmt=DEF_NO_USER_LOGIN_MSG_FMT)
-
-
-def checkAgreesToSiteToS(kwargs):
- """Raises an alternate HTTP response if User has not agreed to site-wide ToS.
-
- Args:
- kwargs: a dictionary with django's arguments
-
- Raises:
- AccessViolationResponse:
- * if User has not agreed to the site-wide ToS, or
- * if no User exists for the logged-in Google Account, or
- * if no Google Account is logged in at all
+ The __setitem__() and __getitem__() methods are overloaded to DTRT
+ when adding new access rights, and retrieving them, so use these
+ rather then modifying rights directly if so desired.
"""
- checkIsUser(kwargs)
+ def __init__(self, params):
+ """Adopts base.rights as rights if base is set.
+ """
+
+ base = params.get('rights') if params else None
+ self.rights = base.rights if base else {}
+
+ def __setitem__(self, key, value):
+ """Sets a value only if no old value exists.
+ """
+
+ oldvalue = self.rights.get(key)
+ self.rights[key] = oldvalue if oldvalue else value
+
+ def __getitem__(self, key):
+ """Retrieves the right checkers and massages then into a default format.
+
+ The result is guaranteed to be a list of 2-tuples, the first element is a
+ checker (iff there is an checker with the specified name), the second
+ element is a list of arguments that should be passed to the checker when
+ calling it in addition to the standard django_args.
+ """
+
+ result = []
+
+ for i in self.rights.get(key, []):
+ # Be nice an repack so that it is always a list with tuples
+ if isinstance(i, tuple):
+ name, arg = i
+ tmp = (getattr(self, name), (arg if isinstance(arg, list) else [arg]))
+ result.append(tmp)
+ else:
+ tmp = (getattr(self, i), [])
+ result.append(tmp)
+
+ return result
- user = user_logic.getForCurrentAccount()
-
- if user_logic.agreesToSiteToS(user):
+ def checkAccess(self, access_type, django_args):
+ """Runs all the defined checks for the specified type.
+
+ Args:
+ access_type: the type of request (such as 'list' or 'edit')
+ rights: a dictionary containing access check functions
+ django_args: a dictionary with django's arguments
+
+ Rights usage:
+ The rights dictionary is used to check if the current user is allowed
+ to view the page specified. The functions defined in this dictionary
+ are always called with the provided django_args dictionary as argument. On any
+ request, regardless of what type, the functions in the 'any_access' value
+ are called. If the specified type is not in the rights dictionary, all
+ the functions in the 'unspecified' value are called. When the specified
+ type _is_ in the rights dictionary, all the functions in that access_type's
+ value are called.
+ """
+
+ self.id = users.get_current_user()
+
+ # Call each access checker
+ for check, args in self['any_access']:
+ check(django_args, *args)
+
+ if access_type not in self.rights:
+ for check, args in self['unspecified']:
+ # No checks defined, so do the 'generic' checks and bail out
+ check(django_args, *args)
+ return
+
+ for check, args in self[access_type]:
+ check(django_args, *args)
+
+ def allow(self, django_args):
+ """Never raises an alternate HTTP response. (an access no-op, basically).
+
+ Args:
+ django_args: a dictionary with django's arguments
+ """
+
return
- # Would not reach this point of site-wide ToS did not exist, since
- # agreesToSiteToS() call above always returns True if no ToS is in effect.
- login_msg_fmt = DEF_AGREE_TO_TOS_MSG_FMT % {
- 'tos_link': redirects.getToSRedirect(site_logic.getSingleton())}
+ def deny(self, django_args):
+ """Always raises an alternate HTTP response.
+
+ Args:
+ django_args: a dictionary with django's arguments
+
+ Raises:
+ always raises AccessViolationResponse if called
+ """
+
+ context = django_args.get('context', {})
+ context['title'] = 'Access denied'
+
+ raise out_of_band.AccessViolation(DEF_PAGE_DENIED_MSG, context=context)
- raise out_of_band.LoginRequest(message_fmt=login_msg_fmt)
+ def checkIsLoggedIn(self, django_args):
+ """Raises an alternate HTTP response if Google Account is not logged in.
+ Args:
+ django_args: a dictionary with django's arguments
-def checkIsDeveloper(kwargs):
- """Raises an alternate HTTP response if Google Account is not a Developer.
+ Raises:
+ AccessViolationResponse:
+ * if no Google Account is even logged in
+ """
+
+ if self.id:
+ return
+
+ raise out_of_band.LoginRequest()
- Args:
- kwargs: a dictionary with django's arguments
+ def checkNotLoggedIn(self, django_args):
+ """Raises an alternate HTTP response if Google Account is logged in.
+
+ Args:
+ django_args: a dictionary with django's arguments
+
+ Raises:
+ AccessViolationResponse:
+ * if a Google Account is currently logged in
+ """
+
+ if not self.id:
+ return
+
+ raise out_of_band.LoginRequest(message_fmt=DEF_LOGOUT_MSG_FMT)
- Raises:
- AccessViolationResponse:
- * if User is not a Developer, or
- * if no User exists for the logged-in Google Account, or
- * if no Google Account is logged in at all
- """
+ def checkIsUser(self, django_args):
+ """Raises an alternate HTTP response if Google Account has no User entity.
+
+ Args:
+ django_args: a dictionary with django's arguments
- checkAgreesToSiteToS(kwargs)
+ Raises:
+ AccessViolationResponse:
+ * if no User exists for the logged-in Google Account, or
+ * if no Google Account is logged in at all
+ """
+
+ self.checkIsLoggedIn(django_args)
+
+ user = user_logic.getForCurrentAccount()
- if accounts.isDeveloper(account=users.get_current_user()):
- return
+ if user:
+ return
+
+ raise out_of_band.LoginRequest(message_fmt=DEF_NO_USER_LOGIN_MSG_FMT)
+
+ def checkAgreesToSiteToS(self, django_args):
+ """Raises an alternate HTTP response if User has not agreed to site-wide ToS.
+
+ Args:
+ django_args: a dictionary with django's arguments
- login_message_fmt = DEF_DEV_LOGOUT_LOGIN_MSG_FMT % {
- 'role': 'a Site Developer '}
+ Raises:
+ AccessViolationResponse:
+ * if User has not agreed to the site-wide ToS, or
+ * if no User exists for the logged-in Google Account, or
+ * if no Google Account is logged in at all
+ """
+
+ self.checkIsUser(django_args)
- raise out_of_band.LoginRequest(message_fmt=login_message_fmt)
+ user = user_logic.getForCurrentAccount()
+
+ if user_logic.agreesToSiteToS(user):
+ return
+ # Would not reach this point of site-wide ToS did not exist, since
+ # agreesToSiteToS() call above always returns True if no ToS is in effect.
+ login_msg_fmt = DEF_AGREE_TO_TOS_MSG_FMT % {
+ 'tos_link': redirects.getToSRedirect(site_logic.getSingleton())}
+
+ raise out_of_band.LoginRequest(message_fmt=login_msg_fmt)
-def checkCanMakeRequestToGroup(group_logic):
- """Raises an alternate HTTP response if the specified group is not in an
- active state.
-
- Note that state hasn't been implemented yet
-
- Args:
- group_logic: Logic module for the type of group which the request is for
- """
+ def checkIsDeveloper(self, django_args):
+ """Raises an alternate HTTP response if Google Account is not a Developer.
+
+ Args:
+ django_args: a dictionary with django's arguments
+
+ Raises:
+ AccessViolationResponse:
+ * if User is not a Developer, or
+ * if no User exists for the logged-in Google Account, or
+ * if no Google Account is logged in at all
+ """
+
+ self.checkAgreesToSiteToS(django_args)
+
+ if accounts.isDeveloper(account=self.id):
+ return
- def wrapper(kwargs):
+ login_message_fmt = DEF_DEV_LOGOUT_LOGIN_MSG_FMT % {
+ 'role': 'a Site Developer '}
+
+ raise out_of_band.LoginRequest(message_fmt=login_message_fmt)
+
+ def checkCanMakeRequestToGroup(self, django_args, group_logic):
+ """Raises an alternate HTTP response if the specified group is not in an
+ active state.
+
+ Note that state hasn't been implemented yet
+
+ Args:
+ group_logic: Logic module for the type of group which the request is for
+ """
+
group_entity = role_logic.getGroupEntityFromScopePath(
- group_logic.logic, kwargs['scope_path'])
+ group_logic.logic, django_args['scope_path'])
if not group_entity:
raise out_of_band.Error(DEF_GROUP_NOT_FOUND_MSG, status=404)
# TODO(ljvderijk) check if the group is active
return
- return wrapper
-
-def checkCanCreateFromRequest(role_name):
- """Raises an alternate HTTP response if the specified request does not exist
- or if it's state is not group_accepted.
- """
+ def checkCanCreateFromRequest(self, django_args, role_name):
+ """Raises an alternate HTTP response if the specified request does not exist
+ or if it's state is not group_accepted.
+ """
- def wrapper(kwargs):
- checkAgreesToSiteToS(kwargs)
+ self.checkAgreesToSiteToS(django_args)
user_entity = user_logic.getForCurrentAccount()
- if user_entity.link_id != kwargs['link_id']:
- deny(kwargs)
+ if user_entity.link_id != django_args['link_id']:
+ deny(django_args)
- fields = {'link_id': kwargs['link_id'],
- 'scope_path': kwargs['scope_path'],
+ fields = {'link_id': django_args['link_id'],
+ 'scope_path': django_args['scope_path'],
'role': role_name}
request_entity = request_logic.getFromFieldsOr404(**fields)
if request_entity.state != 'group_accepted':
# TODO tell the user that this request has not been accepted yet
- deny(kwargs)
+ deny(django_args)
return
- return wrapper
-
+ def checkCanProcessRequest(self, django_args, role_name):
+ """Raises an alternate HTTP response if the specified request does not exist
+ or if it's state is completed or denied.
+ """
-def checkCanProcessRequest(role_name):
- """Raises an alternate HTTP response if the specified request does not exist
- or if it's state is completed or denied.
- """
-
- def wrapper(kwargs):
-
- fields = {'link_id': kwargs['link_id'],
- 'scope_path': kwargs['scope_path'],
+ fields = {'link_id': django_args['link_id'],
+ 'scope_path': django_args['scope_path'],
'role': role_name}
request_entity = request_logic.getFromFieldsOr404(**fields)
if request_entity.state in ['completed', 'denied']:
# TODO tell the user that this request has been processed
- deny(kwargs)
-
- return
-
- return wrapper
-
-
-def checkIsMyGroupAcceptedRequest(kwargs):
- """Raises an alternate HTTP response if the specified request does not exist
- or if it's state is not group_accepted.
- """
-
- checkAgreesToSiteToS(kwargs)
-
- user_entity = user_logic.getForCurrentAccount()
-
- if user_entity.link_id != kwargs['link_id']:
- # not the current user's request
- return deny(kwargs)
-
- fields = {'link_id': kwargs['link_id'],
- 'scope_path': kwargs['scope_path'],
- 'role': kwargs['role']}
-
- request_entity = request_logic.getForFields(fields, unique=True)
-
- if not request_entity:
- # TODO return 404
- return deny(kwargs)
-
- if request_entity.state != 'group_accepted':
- return deny(kwargs)
+ deny(django_args)
- return
-
-
-def checkIsHost(kwargs):
- """Raises an alternate HTTP response if Google Account has no Host entity.
-
- Args:
- request: a Django HTTP request
-
- Raises:
- AccessViolationResponse:
- * if User is not already a Host, or
- * if User has not agreed to the site-wide ToS, or
- * if no User exists for the logged-in Google Account, or
- * if the user is not even logged in
- """
-
- try:
- # if the current user is a developer we allow access
- checkIsDeveloper(kwargs)
- return
- except out_of_band.Error:
- pass
-
- checkAgreesToSiteToS(kwargs)
-
- user = user_logic.getForCurrentAccount()
-
- fields = {'user': user,
- 'state': 'active'}
-
- host = host_logic.getForFields(fields, unique=True)
-
- if host:
return
- login_message_fmt = DEF_DEV_LOGOUT_LOGIN_MSG_FMT % {
- 'role': 'a Program Administrator '}
-
- raise out_of_band.LoginRequest(message_fmt=login_message_fmt)
-
-
-def checkIsHostForSponsor(kwargs):
- """Raises an alternate HTTP response if Google Account has no Host entity
- for the specified Sponsor.
+ def checkIsMyGroupAcceptedRequest(self, django_args):
+ """Raises an alternate HTTP response if the specified request does not exist
+ or if it's state is not group_accepted.
+ """
- Args:
- request: a Django HTTP request
+ self.checkAgreesToSiteToS(django_args)
+
+ user_entity = user_logic.getForCurrentAccount()
- Raises:
- AccessViolationResponse:
- * if User is not already a Host for the specified program, or
- * if User has not agreed to the site-wide ToS, or
- * if no User exists for the logged-in Google Account, or
- * if the user is not even logged in
- """
+ if user_entity.link_id != django_args['link_id']:
+ # not the current user's request
+ return deny(django_args)
- try:
- # if the current user is a developer we allow access
- checkIsDeveloper(kwargs)
- return
- except out_of_band.Error:
- pass
+ fields = {'link_id': django_args['link_id'],
+ 'scope_path': django_args['scope_path'],
+ 'role': django_args['role']}
- checkAgreesToSiteToS(kwargs)
-
- user = user_logic.getForCurrentAccount()
+ request_entity = request_logic.getForFields(fields, unique=True)
- if kwargs.get('scope_path'):
- scope_path = kwargs['scope_path']
- else:
- scope_path = kwargs['link_id']
+ if not request_entity:
+ # TODO return 404
+ return deny(django_args)
- fields = {'user': user,
- 'scope_path': scope_path,
- 'state': 'active'}
+ if request_entity.state != 'group_accepted':
+ return deny(django_args)
- host = host_logic.getForFields(fields, unique=True)
-
- if host:
return
- login_message_fmt = DEF_DEV_LOGOUT_LOGIN_MSG_FMT % {
- 'role': 'a Program Administrator '}
-
- raise out_of_band.LoginRequest(message_fmt=login_message_fmt)
-
-
-def checkIsClubAdminForClub(kwargs):
- """Returns an alternate HTTP response if Google Account has no Club Admin
- entity for the specified club.
-
- Args:
- kwargs: a dictionary with django's arguments
-
- Raises:
- AccessViolationResponse: if the required authorization is not met
+ @denySidebar
+ def checkIsHost(self, django_args):
+ """Raises an alternate HTTP response if Google Account has no Host entity.
- Returns:
- None if Club Admin exists for the specified club, or a subclass of
- django.http.HttpResponse which contains the alternate response
- should be returned by the calling view.
- """
-
- try:
- # if the current user is invited to create a host profile we allow access
- checkIsDeveloper(kwargs)
- return
- except out_of_band.Error:
- pass
-
- checkAgreesToSiteToS(kwargs)
-
- user = user_logic.getForCurrentAccount()
+ Args:
+ request: a Django HTTP request
- if kwargs.get('scope_path'):
- scope_path = kwargs['scope_path']
- else:
- scope_path = kwargs['link_id']
-
- fields = {'user': user,
- 'scope_path': scope_path,
- 'state': 'active'}
-
- club_admin_entity = club_admin_logic.getForFields(fields, unique=True)
-
- if club_admin_entity:
- return
-
- login_message_fmt = DEF_DEV_LOGOUT_LOGIN_MSG_FMT % {
- 'role': 'a Club Admin for this Club'}
-
- raise out_of_band.LoginRequest(message_fmt=login_message_fmt)
+ Raises:
+ AccessViolationResponse:
+ * if User is not already a Host, or
+ * if User has not agreed to the site-wide ToS, or
+ * if no User exists for the logged-in Google Account, or
+ * if the user is not even logged in
+ """
-
-def checkIsApplicationAccepted(app_logic):
- """Returns an alternate HTTP response if Google Account has no Club App
- entity for the specified Club.
-
- Args:
- kwargs: a dictionary with django's arguments
-
- Raises:
- AccessViolationResponse: if the required authorization is not met
-
- Returns:
- None if Club App exists for the specified program, or a subclass
- of django.http.HttpResponse which contains the alternate response
- should be returned by the calling view.
- """
-
- def wrapper(kwargs):
try:
# if the current user is a developer we allow access
- checkIsDeveloper(kwargs)
+ self.checkIsDeveloper(django_args)
return
except out_of_band.Error:
pass
- checkAgreesToSiteToS(kwargs)
+ self.checkAgreesToSiteToS(django_args)
+
+ user = user_logic.getForCurrentAccount()
+
+ if django_args.get('scope_path'):
+ scope_path = django_args['scope_path']
+ else:
+ scope_path = django_args['link_id']
+
+ fields = {'user': user,
+ 'scope_path': scope_path,
+ 'state': 'active'}
+
+ host = host_logic.getForFields(fields, unique=True)
+
+ self.checkAgreesToSiteToS(django_args)
+
+ user = user_logic.getForCurrentAccount()
+
+ fields = {'user': user,
+ 'state': 'active'}
+
+ host = host_logic.getForFields(fields, unique=True)
+
+ if host:
+ return
+
+ login_message_fmt = DEF_DEV_LOGOUT_LOGIN_MSG_FMT % {
+ 'role': 'a Program Administrator '}
+
+ raise out_of_band.LoginRequest(message_fmt=login_message_fmt)
+
+ def checkIsHostForSponsor(self, django_args):
+ """Raises an alternate HTTP response if Google Account has no Host entity
+ for the specified Sponsor.
+
+ Args:
+ request: a Django HTTP request
+
+ Raises:
+ AccessViolationResponse:
+ * if User is not already a Host for the specified program, or
+ * if User has not agreed to the site-wide ToS, or
+ * if no User exists for the logged-in Google Account, or
+ * if the user is not even logged in
+ """
+
+ self.checkAgreesToSiteToS(django_args)
+
+ user = user_logic.getForCurrentAccount()
+
+ if django_args.get('scope_path'):
+ scope_path = django_args['scope_path']
+ else:
+ scope_path = django_args['link_id']
+
+ fields = {'user': user,
+ 'scope_path': scope_path,
+ 'state': 'active'}
+
+ host = host_logic.getForFields(fields, unique=True)
+
+ if host:
+ return
+
+ login_message_fmt = DEF_DEV_LOGOUT_LOGIN_MSG_FMT % {
+ 'role': 'a Program Administrator '}
+
+ raise out_of_band.LoginRequest(message_fmt=login_message_fmt)
+
+ def checkIsClubAdminForClub(self, django_args):
+ """Returns an alternate HTTP response if Google Account has no Club Admin
+ entity for the specified club.
+
+ Args:
+ django_args: a dictionary with django's arguments
+
+ Raises:
+ AccessViolationResponse: if the required authorization is not met
+
+ Returns:
+ None if Club Admin exists for the specified club, or a subclass of
+ django.http.HttpResponse which contains the alternate response
+ should be returned by the calling view.
+ """
+
+ try:
+ # if the current user is invited to create a host profile we allow access
+ checkIsDeveloper(django_args)
+ return
+ except out_of_band.Error:
+ pass
+
+ self.checkAgreesToSiteToS(django_args)
+
+ user = user_logic.getForCurrentAccount()
+
+ if django_args.get('scope_path'):
+ scope_path = django_args['scope_path']
+ else:
+ scope_path = django_args['link_id']
+
+ fields = {'user': user,
+ 'scope_path': scope_path,
+ 'state': 'active'}
+
+ club_admin_entity = club_admin_logic.getForFields(fields, unique=True)
+
+ if club_admin_entity:
+ return
+
+ login_message_fmt = DEF_DEV_LOGOUT_LOGIN_MSG_FMT % {
+ 'role': 'a Club Admin for this Club'}
+
+ raise out_of_band.LoginRequest(message_fmt=login_message_fmt)
+
+ def checkIsApplicationAccepted(self, django_args, app_logic):
+ """Returns an alternate HTTP response if Google Account has no Club App
+ entity for the specified Club.
+
+ Args:
+ django_args: a dictionary with django's arguments
+
+ Raises:
+ AccessViolationResponse: if the required authorization is not met
+
+ Returns:
+ None if Club App exists for the specified program, or a subclass
+ of django.http.HttpResponse which contains the alternate response
+ should be returned by the calling view.
+ """
+
+ try:
+ # if the current user is a developer we allow access
+ checkIsDeveloper(django_args)
+ return
+ except out_of_band.Error:
+ pass
+
+ self.checkAgreesToSiteToS(django_args)
user = user_logic.getForCurrentAccount()
@@ -515,80 +557,75 @@
return
# TODO(srabbelier) Make this give a proper error message
- deny(kwargs)
-
- return wrapper
-
-
-def checkIsMyNotification(kwargs):
- """Returns an alternate HTTP response if this request is for
- a Notification belonging to the current user.
-
- Args:
- kwargs: a dictionary with django's arguments
+ deny(django_args)
- Raises:
- AccessViolationResponse: if the required authorization is not met
-
- Returns:
- None if the current User is allowed to access this Notification.
- """
-
- try:
- # if the current user is a developer we allow access
- checkIsDeveloper(kwargs)
- return
- except out_of_band.Error:
- pass
-
- checkAgreesToSiteToS(kwargs)
+ def checkIsMyNotification(self, django_args):
+ """Returns an alternate HTTP response if this request is for
+ a Notification belonging to the current user.
- properties = dicts.filter(kwargs, ['link_id', 'scope_path'])
-
- notification = notification_logic.getForFields(properties, unique=True)
- user = user_logic.getForCurrentAccount()
-
- # We need to check to see if the key's are equal since the User
- # objects are different and the default __eq__ method does not check
- # if the keys are equal (which is what we want).
- if user.key() == notification.scope.key():
- return None
-
- # TODO(ljvderijk) Make this give a proper error message
- deny(kwargs)
-
+ Args:
+ django_args: a dictionary with django's arguments
-def checkIsMyApplication(app_logic):
- """Returns an alternate HTTP response if this request is for
- a Application belonging to the current user.
-
- Args:
- request: a Django HTTP request
+ Raises:
+ AccessViolationResponse: if the required authorization is not met
- Raises:
- AccessViolationResponse: if the required authorization is not met
+ Returns:
+ None if the current User is allowed to access this Notification.
+ """
- Returns:
- None if the current User is allowed to access this Application.
- """
-
- def wrapper(kwargs):
try:
# if the current user is a developer we allow access
- checkIsDeveloper(kwargs)
+ checkIsDeveloper(django_args)
return
except out_of_band.Error:
pass
- checkAgreesToSiteToS(kwargs)
+ self.checkAgreesToSiteToS(django_args)
+
+ properties = dicts.filter(django_args, ['link_id', 'scope_path'])
+
+ notification = notification_logic.getForFields(properties, unique=True)
+ user = user_logic.getForCurrentAccount()
+
+ # We need to check to see if the key's are equal since the User
+ # objects are different and the default __eq__ method does not check
+ # if the keys are equal (which is what we want).
+ if user.key() == notification.scope.key():
+ return None
+
+ # TODO(ljvderijk) Make this give a proper error message
+ deny(django_args)
+
+ def checkIsMyApplication(self, django_args, app_logic):
+ """Returns an alternate HTTP response if this request is for
+ a Application belonging to the current user.
- properties = dicts.filter(kwargs, ['link_id'])
+ Args:
+ request: a Django HTTP request
+
+ Raises:
+ AccessViolationResponse: if the required authorization is not met
+
+ Returns:
+ None if the current User is allowed to access this Application.
+ """
+
+ try:
+ # if the current user is a developer we allow access
+ self.checkIsDeveloper(django_args)
+ return
+ except out_of_band.Error:
+ pass
+
+ self.checkAgreesToSiteToS(django_args)
+
+ properties = dicts.filter(django_args, ['link_id'])
application = app_logic.logic.getForFields(properties, unique=True)
-
+
if not application:
- deny(kwargs)
-
+ deny(django_args)
+
user = user_logic.getForCurrentAccount()
# We need to check to see if the key's are equal since the User
@@ -598,84 +635,76 @@
return None
# TODO(srabbelier) Make this give a proper error message
- deny(kwargs)
-
- return wrapper
+ deny(django_args)
-
-def checkIsMyActiveRole(role_logic):
- """Returns an alternate HTTP response if there is no active role found for
- the current user using the given role_logic.
+ def checkIsMyActiveRole(self, django_args, role_logic):
+ """Returns an alternate HTTP response if there is no active role found for
+ the current user using the given role_logic.
- Raises:
- AccessViolationResponse: if the required authorization is not met
+ Raises:
+ AccessViolationResponse: if the required authorization is not met
- Returns:
- None if the current User has no active role for the given role_logic.
- """
+ Returns:
+ None if the current User has no active role for the given role_logic.
+ """
- def wrapper(kwargs):
try:
# if the current user is a developer we allow access
- checkIsDeveloper(kwargs)
+ checkIsDeveloper(django_args)
return
except out_of_band.Error:
pass
user = user_logic.getForCurrentAccount()
- if not user or user.link_id != kwargs['link_id']:
+ if not user or user.link_id != django_args['link_id']:
# not my role
- deny(kwargs)
+ deny(django_args)
- fields = {'link_id': kwargs['link_id'],
- 'scope_path': kwargs['scope_path']
+ fields = {'link_id': django_args['link_id'],
+ 'scope_path': django_args['scope_path']
}
role_entity = role_logic.logic.getForFields(fields, unique=True)
if not role_entity:
# no role found
- deny(kwargs)
-
+ deny(django_args)
+
if role_entity.state == 'active':
# this role exist and is active
return
else:
# this role is not active
- deny(kwargs)
-
- return wrapper
+ deny(django_args)
+ def checkHasPickGetArgs(self, django_args):
+ """Raises an alternate HTTP response if the request misses get args.
-def checkHasPickGetArgs(kwargs):
- """Raises an alternate HTTP response if the request misses get args.
+ Args:
+ django_args: a dictionary with django's arguments
- Args:
- kwargs: a dictionary with django's arguments
+ Raises:
+ AccessViolationResponse:
+ * if continue is not in request.GET
+ * if field is not in request.GET
+ """
- Raises:
- AccessViolationResponse:
- * if continue is not in request.GET
- * if field is not in request.GET
- """
+ get_args = django_args.get('GET', {})
- get_args = kwargs.get('GET', {})
+ if 'continue' in get_args and 'field' in get_args:
+ return
- if 'continue' in get_args and 'field' in get_args:
- return
-
- #TODO(SRabbelier) inform user that return_url and field are required
- deny(kwargs)
-
+ #TODO(SRabbelier) inform user that return_url and field are required
+ deny(django_args)
-def checkIsDocumentPublic(kwargs):
- """Checks whether a document is public.
+ def checkIsDocumentPublic(self, django_args):
+ """Checks whether a document is public.
- Args:
- kwargs: a dictionary with django's arguments
- """
+ Args:
+ django_args: a dictionary with django's arguments
+ """
- # TODO(srabbelier): A proper check needs to be done to see if the document
- # is public or not, probably involving analysing it's scope or such.
- allow(kwargs)
+ # TODO(srabbelier): A proper check needs to be done to see if the document
+ # is public or not, probably involving analysing it's scope or such.
+ allow(django_args)
--- a/app/soc/views/helper/decorators.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/helper/decorators.py Mon Jan 26 23:32:10 2009 +0000
@@ -103,7 +103,7 @@
# Do the access check dance
try:
- access.checkAccess(access_type, rights, kwargs=check_kwargs)
+ rights.checkAccess(access_type, check_kwargs)
except out_of_band.Error, error:
return helper.responses.errorResponse(error, request)
return func(self, request, access_type, *args, **kwargs)
--- a/app/soc/views/helper/params.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/helper/params.py Mon Jan 26 23:32:10 2009 +0000
@@ -70,21 +70,17 @@
logic = params['logic']
- rights = {}
+ rights = access.Checker(params)
rights['unspecified'] = []
- rights['any_access'] = [access.checkIsLoggedIn]
- rights['show'] = [access.checkAgreesToSiteToS]
- rights['create'] = [access.checkIsDeveloper]
- rights['edit'] = [access.checkIsDeveloper]
- rights['delete'] = [access.checkIsDeveloper]
- rights['list'] = [access.checkIsDeveloper]
- rights['pick'] = [access.checkHasPickGetArgs]
-
- if 'rights' in params:
- rights = dicts.merge(params['rights'], rights)
+ rights['any_access'] = ['checkIsLoggedIn']
+ rights['show'] = ['checkAgreesToSiteToS']
+ rights['create'] = ['checkIsDeveloper']
+ rights['edit'] = ['checkIsDeveloper']
+ rights['delete'] = ['checkIsDeveloper']
+ rights['list'] = ['checkIsDeveloper']
+ rights['pick'] = ['checkHasPickGetArgs']
new_params = {}
- new_params['rights'] = rights
new_params['scope_logic'] = logic.getScopeLogic()
if 'name_short' not in params:
@@ -214,6 +210,9 @@
if not 'key_fields_pattern' in params:
params['key_fields_pattern'] = getKeyFieldsPattern(params)
+ # merge already done by access.Checker
+ params['rights'] = rights
+
return params
--- a/app/soc/views/models/club.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/models/club.py Mon Jan 26 23:32:10 2009 +0000
@@ -58,16 +58,16 @@
params: a dict with params for this View
"""
- rights = {}
- rights['create'] = [access.checkIsDeveloper]
- rights['edit'] = [access.checkIsClubAdminForClub]
- rights['delete'] = [access.checkIsDeveloper]
- rights['home'] = [access.allow]
- rights['list'] = [access.checkIsDeveloper]
- rights['apply_member'] = [access.checkAgreesToSiteToS]
- rights['list_requests'] = [access.checkIsClubAdminForClub]
- rights['list_roles'] = [access.checkIsClubAdminForClub]
- rights['applicant'] = [access.checkIsApplicationAccepted(club_app_logic)]
+ rights = access.Checker(params)
+ rights['create'] = ['checkIsDeveloper']
+ rights['edit'] = ['checkIsClubAdminForClub']
+ rights['delete'] = ['checkIsDeveloper']
+ rights['home'] = ['allow']
+ rights['list'] = ['checkIsDeveloper']
+ rights['apply_member'] = ['checkAgreesToSiteToS']
+ rights['list_requests'] = ['checkIsClubAdminForClub']
+ rights['list_roles'] = ['checkIsClubAdminForClub']
+ rights['applicant'] = [('checkIsApplicationAccepted', club_app_logic)]
new_params = {}
new_params['logic'] = soc.logic.models.club.logic
--- a/app/soc/views/models/club_admin.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/models/club_admin.py Mon Jan 26 23:32:10 2009 +0000
@@ -49,14 +49,14 @@
params: a dict with params for this View
"""
- rights = {}
- rights['create'] = [access.checkIsDeveloper]
- rights['edit'] = [access.checkIsMyActiveRole(soc.logic.models.club_admin)]
- rights['delete'] = [access.checkIsDeveloper]
- rights['invite'] = [access.checkIsClubAdminForClub]
- rights['accept_invite'] = [access.checkCanCreateFromRequest('club_admin')]
- rights['process_request'] = [access.checkIsClubAdminForClub,
- access.checkCanProcessRequest('club_admin')]
+ rights = access.Checker(params)
+ rights['create'] = ['checkIsDeveloper']
+ rights['edit'] = [('checkIsMyActiveRole', soc.logic.models.club_admin)]
+ rights['delete'] = ['checkIsDeveloper']
+ rights['invite'] = ['checkIsClubAdminForClub']
+ rights['accept_invite'] = ['checkCanCreateFromRequest', 'club_admin']
+ rights['process_request'] = ['checkIsClubAdminForClub',
+ ('checkCanProcessRequest', 'club_admin')]
new_params = {}
new_params['logic'] = soc.logic.models.club_admin.logic
--- a/app/soc/views/models/club_app.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/models/club_app.py Mon Jan 26 23:32:10 2009 +0000
@@ -55,13 +55,13 @@
params: a dict with params for this View
"""
- rights = {}
- rights['create'] = [access.checkAgreesToSiteToS]
- rights['delete'] = [access.checkIsMyApplication(club_app_logic)]
- rights['edit'] = [access.checkIsMyApplication(club_app_logic)]
- rights['list'] = [access.checkAgreesToSiteToS]
- rights['public'] = [access.checkIsMyApplication(club_app_logic)]
- rights['review'] = [access.checkIsHost]
+ rights = access.Checker(params)
+ rights['create'] = ['checkAgreesToSiteToS']
+ rights['delete'] = [('checkIsMyApplication', club_app_logic)]
+ rights['edit'] = [('checkIsMyApplication', club_app_logic)]
+ rights['list'] = ['checkAgreesToSiteToS']
+ rights['public'] = [('checkIsMyApplication', club_app_logic)]
+ rights['review'] = ['checkIsHost']
new_params = {}
--- a/app/soc/views/models/club_member.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/models/club_member.py Mon Jan 26 23:32:10 2009 +0000
@@ -48,16 +48,16 @@
params: a dict with params for this View
"""
- rights = {}
- rights['create'] = [access.checkIsDeveloper]
- rights['edit'] = [access.checkIsMyActiveRole(soc.logic.models.club_member)]
- rights['delete'] = [access.checkIsDeveloper]
- rights['invite'] = [access.checkIsClubAdminForClub]
- rights['accept_invite'] = [access.checkCanCreateFromRequest('club_member')]
- rights['request'] = [access.checkAgreesToSiteToS,
- access.checkCanMakeRequestToGroup(club_logic)]
- rights['process_request'] = [access.checkIsClubAdminForClub,
- access.checkCanProcessRequest('club_member')]
+ rights = access.Checker(params)
+ rights['create'] = ['checkIsDeveloper']
+ rights['edit'] = [('checkIsMyActiveRole',soc.logic.models.club_member)]
+ rights['delete'] = ['checkIsDeveloper']
+ rights['invite'] = ['checkIsClubAdminForClub']
+ rights['accept_invite'] = [('checkCanCreateFromRequest','club_member')]
+ rights['request'] = ['checkAgreesToSiteToS',
+ ('checkCanMakeRequestToGroup', club_logic)]
+ rights['process_request'] = ['checkIsClubAdminForClub',
+ ('checkCanProcessRequest','club_member')]
new_params = {}
new_params['logic'] = soc.logic.models.club_member.logic
--- a/app/soc/views/models/document.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/models/document.py Mon Jan 26 23:32:10 2009 +0000
@@ -96,9 +96,9 @@
params: a dict with params for this View
"""
- rights = {}
- rights['any_access'] = [access.allow]
- rights['show'] = [access.checkIsDocumentPublic]
+ rights = access.Checker(params)
+ rights['any_access'] = ['allow']
+ rights['show'] = ['checkIsDocumentPublic']
new_params = {}
new_params['logic'] = soc.logic.models.document.logic
--- a/app/soc/views/models/host.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/models/host.py Mon Jan 26 23:32:10 2009 +0000
@@ -55,14 +55,14 @@
params: a dict with params for this View
"""
- rights = {}
- rights['create'] = [access.checkIsHost]
- rights['edit'] = [access.checkIsMyActiveRole(soc.logic.models.host)]
- rights['invite'] = [access.checkIsHost]
- rights['list'] = [access.checkIsDeveloper]
- rights['accept_invite'] = [access.checkCanCreateFromRequest('host')]
- rights['process_request'] = [access.checkIsHost,
- access.checkCanProcessRequest('host')]
+ rights = access.Checker(params)
+ rights['create'] = ['checkIsHost']
+ rights['edit'] = [('checkIsMyActiveRole', soc.logic.models.host)]
+ rights['invite'] = ['checkIsHost']
+ rights['list'] = ['checkIsDeveloper']
+ rights['accept_invite'] = [('checkCanCreateFromRequest','host')]
+ rights['process_request'] = ['checkIsHost',
+ ('checkCanProcessRequest','host')]
new_params = {}
new_params['rights'] = rights
--- a/app/soc/views/models/notification.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/models/notification.py Mon Jan 26 23:32:10 2009 +0000
@@ -82,14 +82,14 @@
params: a dict with params for this View
"""
- rights = {}
- rights['unspecified'] = [access.deny]
- rights['edit'] = [access.deny]
- rights['show'] = [access.checkIsMyNotification]
- rights['delete'] = [access.checkIsMyNotification]
- rights['list'] = [access.checkAgreesToSiteToS]
+ rights = access.Checker(params)
+ rights['unspecified'] = ['deny']
+ rights['edit'] = ['deny']
+ rights['show'] = ['checkIsMyNotification']
+ rights['delete'] = ['checkIsMyNotification']
+ rights['list'] = ['checkAgreesToSiteToS']
# create is developer only for the time being to test functionality
- rights['create'] = [access.checkIsDeveloper]
+ rights['create'] = ['checkIsDeveloper']
new_params = {}
new_params['logic'] = notification_logic.logic
--- a/app/soc/views/models/presence.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/models/presence.py Mon Jan 26 23:32:10 2009 +0000
@@ -56,8 +56,8 @@
params: a dict with params for this View
"""
- rights = {}
- rights['home'] = [access.allow]
+ rights = access.Checker(params)
+ rights['home'] = ['allow']
new_params = {}
new_params['rights'] = rights
--- a/app/soc/views/models/program.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/models/program.py Mon Jan 26 23:32:10 2009 +0000
@@ -51,9 +51,9 @@
params: a dict with params for this View
"""
- rights = {}
- rights['any_access'] = [access.allow]
- rights['show'] = [access.allow]
+ rights = access.Checker(params)
+ rights['any_access'] = ['allow']
+ rights['show'] = ['allow']
new_params = {}
new_params['logic'] = soc.logic.models.program.logic
--- a/app/soc/views/models/request.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/models/request.py Mon Jan 26 23:32:10 2009 +0000
@@ -65,13 +65,13 @@
params: a dict with params for this View
"""
- rights = {}
- rights['listSelf'] = [access.checkAgreesToSiteToS]
- rights['create'] = [access.deny]
- rights['edit'] = [access.checkIsDeveloper]
- rights['process_invite'] = [access.checkIsMyGroupAcceptedRequest]
- rights['list'] = [access.checkIsDeveloper]
- rights['delete'] = [access.checkIsDeveloper]
+ rights = access.Checker(params)
+ rights['listSelf'] = ['checkAgreesToSiteToS']
+ rights['create'] = ['deny']
+ rights['edit'] = ['checkIsDeveloper']
+ rights['process_invite'] = ['checkIsMyGroupAcceptedRequest']
+ rights['list'] = ['checkIsDeveloper']
+ rights['delete'] = ['checkIsDeveloper']
new_params = {}
new_params['rights'] = rights
--- a/app/soc/views/models/site.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/models/site.py Mon Jan 26 23:32:10 2009 +0000
@@ -46,10 +46,10 @@
params: a dict with params for this View
"""
- rights = {}
- rights['unspecified'] = [access.checkIsDeveloper]
- rights['any_access'] = [access.allow]
- rights['show'] = [access.allow]
+ rights = access.Checker(params)
+ rights['unspecified'] = ['checkIsDeveloper']
+ rights['any_access'] = ['allow']
+ rights['show'] = ['allow']
new_params = {}
new_params['logic'] = soc.logic.models.site.logic
--- a/app/soc/views/models/sponsor.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/models/sponsor.py Mon Jan 26 23:32:10 2009 +0000
@@ -45,14 +45,14 @@
params: a dict with params for this View
"""
- rights = {}
- rights['create'] = [access.checkIsDeveloper]
- rights['edit'] = [access.checkIsHostForSponsor]
- rights['delete'] = [access.checkIsDeveloper]
- rights['home'] = [access.checkIsHostForSponsor]
- rights['list'] = [access.checkIsDeveloper]
- rights['list_requests'] = [access.checkIsHostForSponsor]
- rights['list_roles'] = [access.checkIsHostForSponsor]
+ rights = access.Checker(params)
+ rights['create'] = ['checkIsDeveloper']
+ rights['edit'] = ['checkIsHostForSponsor']
+ rights['delete'] = ['checkIsDeveloper']
+ rights['home'] = ['checkIsHostForSponsor']
+ rights['list'] = ['checkIsDeveloper']
+ rights['list_requests'] = ['checkIsHostForSponsor']
+ rights['list_roles'] = ['checkIsHostForSponsor']
new_params = {}
new_params['logic'] = soc.logic.models.sponsor.logic
--- a/app/soc/views/models/user_self.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/models/user_self.py Mon Jan 26 23:32:10 2009 +0000
@@ -112,13 +112,13 @@
params: a dict with params for this View
"""
- rights = {}
- rights['unspecified'] = [access.deny]
- rights['any_access'] = [access.allow]
- rights['edit'] = [access.checkIsLoggedIn]
- rights['roles'] = [access.checkAgreesToSiteToS]
- rights['signIn'] = [access.checkNotLoggedIn]
- rights['notification'] = [access.checkAgreesToSiteToS]
+ rights = access.Checker(params)
+ rights['unspecified'] = ['deny']
+ rights['any_access'] = ['allow']
+ rights['edit'] = ['checkIsLoggedIn']
+ rights['roles'] = ['checkAgreesToSiteToS']
+ rights['signIn'] = ['checkNotLoggedIn']
+ rights['notification'] = ['checkAgreesToSiteToS']
new_params = {}
new_params['rights'] = rights
--- a/app/soc/views/sitemap/sidebar.py Mon Jan 26 21:22:53 2009 +0000
+++ b/app/soc/views/sitemap/sidebar.py Mon Jan 26 23:32:10 2009 +0000
@@ -140,7 +140,7 @@
for url, menu_text, access_type in items:
try:
- access.checkAccess(access_type, rights, kwargs)
+ rights.checkAccess(access_type, kwargs)
submenus.append({'url': url, 'title': menu_text})
except out_of_band.Error:
pass