示例#1
0
    def get_queryset(self):
        """
        Builds a queryset of relevant users with permissions for this website, and annotates them by group name/role
        (owner, administrator, editor, or global administrator)
        """
        website = self.website
        website_group_names = list(
            get_groups_with_perms(website).values_list(
                "name", flat=True)) + [constants.GLOBAL_ADMIN]
        owner_user_id = website.owner.id if website.owner else None

        return (User.objects.filter(
            Q(id=owner_user_id)
            | Q(groups__name__in=website_group_names)).annotate(role=Case(
                When(id=owner_user_id, then=Value(constants.ROLE_OWNER)),
                default=Group.objects.filter(
                    user__id=OuterRef("id"),
                    name__in=website_group_names).annotate(role_name=Case(
                        *([
                            When(
                                name=permissions_group_name_for_role(
                                    role, website),
                                then=Value(role),
                            ) for role in constants.ROLE_GROUP_MAPPING
                        ]),
                        output_field=CharField(),
                    )).values("role_name")[:1],
                output_field=CharField(),
            )).order_by("name", "id").distinct())
示例#2
0
def setup_website_groups_permissions(website):
    """
    Create groups and assign permissions for a website

    Args:
        website (Website): The website that the permissions are for

    Returns:
        list (int, int, bool): # groups created, # groups updated, owner updated
    """
    groups_created = 0
    groups_updated = 0
    owner_updated = False

    admin_group, admin_created = Group.objects.get_or_create(
        name=permissions_group_name_for_role(constants.ROLE_ADMINISTRATOR,
                                             website))
    if admin_created:
        groups_created += 1
    editor_group, editor_created = Group.objects.get_or_create(
        name=permissions_group_name_for_role(constants.ROLE_EDITOR, website))
    if editor_created:
        groups_created += 1

    if (assign_website_permissions(
            admin_group, constants.PERMISSIONS_ADMIN, website=website)
            and not admin_created):
        groups_updated += 1

    if (assign_website_permissions(
            editor_group, constants.PERMISSIONS_EDITOR, website=website)
            and not editor_created):
        groups_updated += 1

    if website.owner:
        owner_updated = assign_website_permissions(website.owner,
                                                   constants.PERMISSIONS_ADMIN,
                                                   website=website)

    return groups_created, groups_updated, owner_updated
示例#3
0
    def create(self, validated_data):
        """Creating a contributor adds the user to the group corresponding to the specified role"""
        website = self.website
        role = validated_data.get("role")
        user = User.objects.get(email=validated_data.get("email"))
        group_name = permissions_group_name_for_role(role, website)
        if user in get_users_with_perms(website) or user == website.owner:
            raise ValidationError(
                {"email": ["User is already a collaborator for this site"]})

        user.groups.add(Group.objects.get(name=group_name))

        # user.role normally gets set by the query in the view, but we need to manually set/update it here
        user.role = role
        return user
示例#4
0
def is_site_admin(user, website):
    """
    Determine if the user is effectively an admin for a site

    Args:
        user (users.models.User): The user to check
        website (Website): The website to check

    Returns:
        bool: True if user is an admin for the site
    """
    group_names = set(user.groups.values_list("name", flat=True))
    return (is_global_admin(user, group_names=group_names)
            or website.owner == user or permissions_group_name_for_role(
                constants.ROLE_ADMINISTRATOR, website) in group_names)
示例#5
0
    def update(self, instance, validated_data):
        """ Change a collaborator's permission group for the website """
        website = self.website
        user = instance
        role = validated_data.get("role")
        group_name = permissions_group_name_for_role(role, website)

        # User should only belong to one group per website
        for group in get_groups_with_perms(website):
            if group_name and group.name == group_name:
                user.groups.add(group)
            else:
                user.groups.remove(group)

        # user.role normally gets set by the query in the view, but we need to manually set/update it here
        user.role = role
        return user
示例#6
0
 def editor_group(self):
     """ Get the editor group """
     return Group.objects.filter(
         name=permissions_group_name_for_role(constants.ROLE_EDITOR, self)
     ).first()
示例#7
0
 def admin_group(self):
     """ Get the admin group """
     return Group.objects.filter(
         name=permissions_group_name_for_role(constants.ROLE_ADMINISTRATOR, self)
     ).first()
示例#8
0
def test_permissions_group_for_role_invalid(role):
    """permissions_group_for_role should raise a ValueError for an invalid role"""
    website = WebsiteFactory.build()
    with pytest.raises(ValueError) as exc:
        permissions_group_name_for_role(role, website)
    assert exc.value.args == (f"Invalid role for a website group: {role}", )
示例#9
0
def test_permissions_group_name_for_global_admin():
    """permissions_group_for_role should return the correct group name for global admins"""
    website = WebsiteFactory.build()
    assert (permissions_group_name_for_role(constants.ROLE_GLOBAL,
                                            website) == constants.GLOBAL_ADMIN)
示例#10
0
def test_permissions_group_name_for_role(role, group_prefix):
    """permissions_group_for_role should return the correct group name for a website and role"""
    website = WebsiteFactory.build()
    assert (permissions_group_name_for_role(
        role, website) == f"{group_prefix}{website.uuid.hex}")