# HG changeset patch # User Sverre Rabbelier # Date 1233012730 0 # Node ID 3b66772d21a5a093bb8162b35d72a8adcb68d9ba # Parent 6abf12b9e6468bcd24329bc644f608a831534ad2 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 diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/helper/access.py --- 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) diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/helper/decorators.py --- 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) diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/helper/params.py --- 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 diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/models/club.py --- 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 diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/models/club_admin.py --- 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 diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/models/club_app.py --- 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 = {} diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/models/club_member.py --- 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 diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/models/document.py --- 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 diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/models/host.py --- 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 diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/models/notification.py --- 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 diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/models/presence.py --- 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 diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/models/program.py --- 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 diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/models/request.py --- 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 diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/models/site.py --- 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 diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/models/sponsor.py --- 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 diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/models/user_self.py --- 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 diff -r 6abf12b9e646 -r 3b66772d21a5 app/soc/views/sitemap/sidebar.py --- 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