def _query_perms(self, roles, get_related_prefixes, perms_name, force_separate, agent=ANY, target=ANY): """ This is an abstraction used by subclasses to query permissions. Roles will be normalized to a list of roles. force_separate is an optimization. If you know you are going to have multiple left joins, this will speed things up. Either agent or target can be provided. It's assumed that the queryset to be retrieved is the thing not provided. """ # Normalize inputs roles = normalize_value(roles) agent = normalize_value(agent) target = normalize_value(target) # Get all possible related queries we're doing related_prefixes = (get_related_prefixes(self, perms_name, *roles) if is_value(roles) else [perms_name]) # Create a query for each related prefix queries = [ self._get_query(roles, agent, target, prefix=prefix) for prefix in related_prefixes ] # Aggregate the queries. Query together if we don't have any # divergent left joins. query_together = (not force_separate and len(related_prefixes) <= 1 and perms_name in related_prefixes) if query_together: results = self._query_together(queries) else: results = self._query_separate(queries) return results
def _validate_actions(self, actions): if not is_value(actions): return actions actions = normalize_value(actions) if [action for action in actions if "." not in action]: raise ValueError("Prefixes are required since target is optional.") return actions
def for_role(self, roles=ANY, agent=ANY, infer_agents=True, force_separate=False): """ This filters permission targets by the given agent. infer_agents is an optimization. If you know you don't need the authority of any related agents, set it to false. """ return self._query_perms( roles=roles, get_related_prefixes=get_related_target_prefixes, perms_name='target_perms', force_separate=force_separate, agent=normalize_value(agent, normalize_agent, infer_agents=infer_agents))
def test_normalize_value(self): self.assertEqual(13, normalize_value(3, lambda x, y: x + y, 10))