def ensure_grants(grants_to_privs, dry_run=False, verbose=False, roles_by_slug=None): """ Adds a parameterless grant between grantee and priv, looked up by slug. :param grants_to_privs: An iterable of two-tuples: `(grantee_slug, priv_slugs)`. Will only be iterated once. """ dry_run_tag = "[DRY RUN] " if dry_run else "" if roles_by_slug is None: roles_by_slug = {role.slug: role for role in Role.objects.all()} granted = defaultdict(set) for grant in Grant.objects.select_related('from_role', 'to_role').all(): granted[grant.from_role.slug].add(grant.to_role.slug) grants_to_create = [] for grantee_slug, priv_slugs in grants_to_privs: if grantee_slug not in roles_by_slug: logger.info('grantee %s does not exist.', grantee_slug) continue for priv_slug in priv_slugs: if priv_slug not in roles_by_slug: logger.info('privilege %s does not exist.', priv_slug) continue if priv_slug in granted[grantee_slug]: if verbose or dry_run: logger.info('%sPrivilege already granted: %s => %s', dry_run_tag, grantee_slug, priv_slug) else: granted[grantee_slug].add(priv_slug) if verbose or dry_run: logger.info('%sGranting privilege: %s => %s', dry_run_tag, grantee_slug, priv_slug) if not dry_run: grants_to_create.append( Grant(from_role=roles_by_slug[grantee_slug], to_role=roles_by_slug[priv_slug])) if grants_to_create: Role.get_cache().clear() Grant.objects.bulk_create(grants_to_create)
def test_specified_priv_for_grantee_is_revoked(self): privs_to_revoke_for_grantee = [('grantee', ['privilege'])] roles_by_slug = { 'grantee': Role(slug='grantee'), 'privilege': Role(slug='privilege'), } expected_grants = [ Grant(from_role=Role(slug='grantee'), to_role=Role(slug='privilege')) ] with patch('corehq.apps.accounting.utils.get_all_roles_by_slug', return_value=roles_by_slug),\ patch('corehq.apps.accounting.utils.get_grants', return_value=expected_grants),\ patch('corehq.apps.accounting.utils.delete_grants') as mock_deletegrants: revoke_privs_for_grantees(privs_to_revoke_for_grantee) mock_deletegrants.assert_called_with(expected_grants)
def ensure_grants(privs_to_ensure_for_grantee, dry_run=False, verbose=False, roles_by_slug=None): """ Adds a parameterless grant between grantee and priv, looked up by slug. :param privs_to_ensure_for_grantee: An iterable of tuples: `(grantee_slug, [priv_slugs])` :param dry_run: if True, will not make any changes to the DB :param verbose: if True, will log additional output :param roles_by_slug: can specify your own roles to consider, otherwise will fetch all Role objects """ dry_run_tag = "[DRY RUN] " if dry_run else "" roles_by_slug = roles_by_slug or get_all_roles_by_slug() granted_privs_for_grantee = get_granted_privs_for_grantee() grants_to_create = [] for grantee_slug, priv_slugs in privs_to_ensure_for_grantee: if grantee_slug not in roles_by_slug: logger.info('grantee %s does not exist.', grantee_slug) continue for priv_slug in priv_slugs: if priv_slug not in roles_by_slug: logger.info('privilege %s does not exist.', priv_slug) continue if priv_slug in granted_privs_for_grantee[grantee_slug]: if verbose or dry_run: logger.info('%sPrivilege already granted: %s => %s', dry_run_tag, grantee_slug, priv_slug) else: granted_privs_for_grantee[grantee_slug].add(priv_slug) if verbose or dry_run: logger.info('%sGranting privilege: %s => %s', dry_run_tag, grantee_slug, priv_slug) if not dry_run: grants_to_create.append( Grant(from_role=roles_by_slug[grantee_slug], to_role=roles_by_slug[priv_slug])) if grants_to_create: Role.get_cache().clear() Grant.objects.bulk_create(grants_to_create)