def can_access(self, user, allow_admin=True): """Checks if the user can access the object. :param user: The :class:`.User` to check. May be None if the user is not logged in. :param allow_admin: If admin users should always have access """ override = self._check_can_access_override(user, allow_admin=allow_admin) if override is not None: return override # Usually admins can access everything, so no need for checks if allow_admin and user and user.is_admin: rv = True # If there's a valid access key we can skip all other ACL checks elif self.allow_access_key and self.check_access_key(): rv = True elif self.protection_mode == ProtectionMode.public: # if it's public we completely ignore the parent protection # this is quite ugly which is why it should only be allowed # in rare cases (e.g. events which might be in a protected # category but should be public nonetheless) rv = True elif self.protection_mode == ProtectionMode.protected: # if it's protected, we also ignore the parent protection # and only check our own ACL if any(user in entry.principal for entry in iter_acl(self.acl_entries)): rv = True elif isinstance(self, ProtectionManagersMixin): rv = self.can_manage(user, allow_admin=allow_admin) else: rv = False elif self.protection_mode == ProtectionMode.inheriting: # if it's inheriting, we only check the parent protection # unless `inheriting_have_acl` is set, in which case we # might not need to check the parents at all if self.inheriting_have_acl and any(user in entry.principal for entry in iter_acl(self.acl_entries)): rv = True else: # the parent can be either an object inheriting from this # mixin or a legacy object with an AccessController parent = self.protection_parent if parent is None: # This should be the case for the top-level object, # i.e. the root category, which shouldn't allow # ProtectionMode.inheriting as it makes no sense. raise TypeError('protection_parent of {} is None'.format(self)) elif hasattr(parent, 'can_access'): rv = parent.can_access(user, allow_admin=allow_admin) else: raise TypeError('protection_parent of {} is of invalid type {} ({})'.format(self, type(parent), parent)) else: # should never happen, but since this is a sensitive area # we better fail loudly if we have garbage raise ValueError('Invalid protection mode: {}'.format(self.protection_mode)) override = self._check_can_access_override(user, allow_admin=allow_admin, authorized=rv) return override if override is not None else rv
def contains_user(self, name, user): """Checks if a user is in an ACL. To pass this check, the user can either be in the ACL itself or in a group in the ACL. :param name: Setting name :param user: A :class:`.User` """ from fossir.util.user import iter_acl return any(user in principal for principal in iter_acl(self.get(name)))
def contains_user(self, event, name, user): """Checks if a user is in an ACL. To pass this check, the user can either be in the ACL itself or in a group in the ACL. :param event: Event (or its ID) :param name: Setting name :param user: A :class:`.User` """ return any(user in principal for principal in iter_acl(self.get(event, name)))
def test_iter_acl(): user = User() user_p = MagicMock(principal=user, spec=['principal']) ipn = IPNetworkGroup() ipn_p = MagicMock(principal=ipn, spec=['principal']) local_group = GroupProxy(123, _group=MagicMock()) local_group_p = MagicMock(principal=local_group, spec=['principal']) remote_group = GroupProxy('foo', 'bar') remote_group_p = MagicMock(principal=remote_group, spec=['principal']) acl = [ ipn, user_p, remote_group, local_group_p, user, local_group, remote_group_p, ipn_p ] assert list(iter_acl(iter(acl))) == [ user_p, user, ipn, ipn_p, local_group_p, local_group, remote_group, remote_group_p ]
def can_be_overridden(self, user, room=None, explicit_only=False): """Determines if a user can override the blocking The following persons are authorized to override a blocking: - owner (the one who created the blocking) - any users on the blocking's ACL - unless explicitOnly is set: admins and room owners (if a room is given) """ if not user: return False if self.created_by_user == user: return True if not explicit_only: if rb_is_admin(user): return True elif room and room.is_owned_by(user): return True return any(user in principal for principal in iter_acl(self.allowed))
def can_manage(self, user, role=None, allow_admin=True, check_parent=True, explicit_role=False): """Checks if the user can manage the object. :param user: The :class:`.User` to check. May be None if the user is not logged in. :param: role: The management role that is needed for the check to succeed. If not specified, full management privs are required. May be set to the string ``'ANY'`` to check if the user has any management privileges. If the user has `full_access` privileges, he's assumed to have all possible roles. :param allow_admin: If admin users should always have access :param check_parent: If the parent object should be checked. In this case the role is ignored; only full management access is inherited to children. :param explicit_role: If the specified role should be checked explicitly instead of short-circuiting the check for fossir admins or managers. When this option is set to ``True``, the values of `allow_admin` and `check_parent` are ignored. This also applies if `role` is None in which case this argument being set to ``True`` is equivalent to `allow_admin` and `check_parent` being set to ``False``. """ if role is not None and role != 'ANY' and role not in get_available_roles(type(self)): raise ValueError("role '{}' is not valid for '{}' objects".format(role, type(self).__name__)) if user is None: # An unauthorized user is never allowed to perform management operations. # Not even signals may override this since management code generally # expects session.user to be not None. return False # Trigger signals for protection overrides rv = values_from_signal(signals.acl.can_manage.send(type(self), obj=self, user=user, role=role, allow_admin=allow_admin, check_parent=check_parent, explicit_role=explicit_role), single_value=True) if rv: # in case of contradictory results (shouldn't happen at all) # we stay on the safe side and deny access return all(rv) # Usually admins can access everything, so no need for checks if not explicit_role and allow_admin and user.is_admin: return True if any(user in entry.principal for entry in iter_acl(self.acl_entries) if entry.has_management_role(role, explicit=(explicit_role and role is not None))): return True if not check_parent or explicit_role: return False # the parent can be either an object inheriting from this # mixin or a legacy object with an AccessController parent = self.protection_parent if parent is None: # This should be the case for the top-level object, # i.e. the root category return False elif hasattr(parent, 'can_manage'): return parent.can_manage(user, allow_admin=allow_admin) else: raise TypeError('protection_parent of {} is of invalid type {} ({})'.format(self, type(parent), parent))