def get_permissions(names): """ Given an iterable of permission names of the form "app_label.codename", return an iterable of the corresponding existing Permission objects. """ names = set(names) # Eliminate redundancies split_names = (name.split(".", 1) for name in names) query_elements = [ Q(content_type__app_label=app_label, codename=codename) for app_label, codename in split_names ] permissions = ( Permission.objects.filter(reduce(or_, query_elements)) if query_elements else Permission.objects.none() ) if len(permissions) != len(names): differences = names - { f"{p.content_type.app_label:s}.{p.codename:s}" for p in permissions } diff_string = ", ".join(differences) raise Permission.DoesNotExist( f"Some permission names were not found: {diff_string:s}" ) return permissions
def filter_permission_names(permissions): """ Generate a Permission model query filtered by names, e.g.: ['<app_label>.<codename>', ...] """ permission_pks = [] for permission in permissions: assert '.' in permission, f'Wrong format: {permission!r}' app_label, codename = permission.split('.') try: permission_pk = Permission.objects.only('pk').get( codename=codename, content_type__app_label=app_label).pk except Permission.DoesNotExist as err: raise Permission.DoesNotExist(f"{err}: '{app_label}.{codename}'") permission_pks.append(permission_pk) qs = Permission.objects.filter(pk__in=permission_pks) return qs
def get_perm(p): """ ``p`` format: '<ct_app_label>.<ct_model>.<p_codename>' """ try: ct_app_label, ct_model, p_codename = p.split('.') except ValueError: raise ValueError( u'Value must be in format "<ct_app_label>.<ct_model>.<p_codename>". Got "%s"' % p) try: return Permission.objects.get(content_type__app_label=ct_app_label, content_type__model=ct_model, codename=p_codename) except Permission.DoesNotExist: raise Permission.DoesNotExist(u'Permission "%s" does not exist.' % p)
def get_group(name=None, permissions=None): group = G(Group, name=(name or text(5))) permission_names = permissions or [] for permission_name in permission_names: try: app_label, codename = permission_name.split('.') except ValueError: raise ValueError( "Invalid permission name `{0}`".format(permission_name)) try: permission = Permission.objects.get( content_type__app_label=app_label, codename=codename) except Permission.DoesNotExist: raise Permission.DoesNotExist( 'Permission `{0}` does not exist'.format(permission_name)) group.permissions.add(permission) return group
def _check_perms(filtered_perms: QuerySet[Permission], perm_strings: Tuple[str, ...]): if filtered_perms.count() != len(perm_strings): perm_strings_set = set(perm_strings) if len(perm_strings_set) != len(perm_strings): raise ValueError( "The permission arguments provided contain duplicates") perms_not_found = perm_strings_set - { perm_to_str(perm) for perm in filtered_perms } if not perms_not_found: # If all the perm arguments were found, it means that the filtered perms contain duplicate # combinations of app labels and codenames, in which case it's fine to just return them return perms_not_found_str = ", ".join(f"'{perm}'" for perm in perms_not_found) raise Permission.DoesNotExist( f"The following permissions do not exist: {perms_not_found_str}")
def add_permissions(permission_obj, permissions): """ Add permissions e.g.: group = Group.objects.create(name="Foobar Group") permissions=( (YourModelClass, "the_permission_string"), ) add_permissions(permission_obj=group, permissions=permissions) """ for model_class, codename in permissions: content_type = ContentType.objects.get_for_model(model_class) try: permission = Permission.objects.get(content_type=content_type, codename=codename) except Permission.DoesNotExist: raise Permission.DoesNotExist( "Permission '%s.%s' doesn't exists!" % (content_type, codename)) permission_obj.permissions.add(permission)
def assign_website_permissions(group_or_user, perms, website=None): """ Assign appropriate permissions to a website admin group Args: group_or_user (Group or User): the group/user to add permissions to website (Object): The object that the permissions are for (typically Website) perms (list of str): The permissions to be assigned Returns: bool: True if any permissions were added, False otherwise """ if website: current_perm_codenames = set(get_perms(group_or_user, website)) elif isinstance(group_or_user, Group): current_perm_codenames = { perm.codename for perm in group_or_user.permissions.all() } elif isinstance(group_or_user, User): current_perm_codenames = { perm.codename for perm in Permission.objects.filter(user=group_or_user) } else: raise TypeError("Permissions must be assigned to a user or group") added_perm_codenames = {perm.replace("websites.", "") for perm in perms} if not added_perm_codenames.difference(current_perm_codenames): return False for perm in perms: try: if website: assign_perm(perm, group_or_user, website) else: assign_perm(perm, group_or_user) except Permission.DoesNotExist as err: raise Permission.DoesNotExist( f"Permission '{perm}' not found") from err return True