Repository: ansible/awx
File: awx/main/access.py (Python)

Code before:
            return not obj.roles.all().exclude(
                content_type=ContentType.objects.get_for_model(User)
            ).filter(ancestors__in=self.user.roles.all()).exists()
        else:
            return self.is_all_org_admin(obj)

    def can_delete(self, obj):
        if obj == self.user:
            # cannot delete yourself
            return False
        super_users = User.objects.filter(is_superuser=True)
        if obj.is_superuser and super_users.count() == 1:
            # cannot delete the last active superuser
            return False
        if self.user.is_superuser:
            return True
        return False

    def can_attach(self, obj, sub_obj, relationship, *args, **kwargs):
        # Reverse obj and sub_obj, defer to RoleAccess if this is a role assignment.
        if relationship == 'roles':
            role_access = RoleAccess(self.user)
            return role_access.can_attach(sub_obj, obj, 'members', *args, **kwargs)

        if not settings.MANAGE_ORGANIZATION_AUTH and not self.user.is_superuser:
            return False

        return super(UserAccess, self).can_attach(obj, sub_obj, relationship, *args, **kwargs)

    def can_unattach(self, obj, sub_obj, relationship, *args, **kwargs):
        if relationship == 'roles':
            role_access = RoleAccess(self.user)
            return role_access.can_unattach(sub_obj, obj, 'members', *args, **kwargs)

        if not settings.MANAGE_ORGANIZATION_AUTH and not self.user.is_superuser:
            return False

        return super(UserAccess, self).can_unattach(obj, sub_obj, relationship, *args, **kwargs)


class OAuth2ApplicationAccess(BaseAccess):
    '''
    I can read, change or delete OAuth 2 applications when:
     - I am a superuser.
     - I am the admin of the organization of the user of the application.
     - I am a user in the organization of the application.
    I can create OAuth 2 applications when:
     - I am a superuser.
     - I am the admin of the organization of the application.
    '''


Review comment (suggestion):
I'm staring at this hard, and right now I think that this remaining `if` clause is superfluous.

I ask myself the question "what can you attach to a user?". To answer this I look at the user API "related" items. I see organizations and teams, but these views do not allow attaching. Some other views allow creation, but not attachment.

In fact, I don't think this line should ever be hit. If you're concerned about being conservative, I'd prefer to raise a RuntimeError instead of the call to super.

Code after:
            return not obj.roles.all().exclude(
                content_type=ContentType.objects.get_for_model(User)
            ).filter(ancestors__in=self.user.roles.all()).exists()
        else:
            return self.is_all_org_admin(obj)

    def can_delete(self, obj):
        if obj == self.user:
            # cannot delete yourself
            return False
        super_users = User.objects.filter(is_superuser=True)
        if obj.is_superuser and super_users.count() == 1:
            # cannot delete the last active superuser
            return False
        if self.user.is_superuser:
            return True
        return False

    def can_attach(self, obj, sub_obj, relationship, *args, **kwargs):
        # The only thing that a User should ever have attached is a Role
        if relationship == 'roles':
            role_access = RoleAccess(self.user)
            return role_access.can_attach(sub_obj, obj, 'members', *args, **kwargs)

        logger.error('Unexpected attempt to associate {} with a user.'.format(sub_obj))
        return False

    def can_unattach(self, obj, sub_obj, relationship, *args, **kwargs):
        # The only thing that a User should ever have to be unattached is a Role
        if relationship == 'roles':
            role_access = RoleAccess(self.user)
            return role_access.can_unattach(sub_obj, obj, 'members', *args, **kwargs)

        logger.error('Unexpected attempt to de-associate {} from a user.'.format(sub_obj))
        return False


class OAuth2ApplicationAccess(BaseAccess):
    '''
    I can read, change or delete OAuth 2 applications when:
     - I am a superuser.
     - I am the admin of the organization of the user of the application.
     - I am a user in the organization of the application.
    I can create OAuth 2 applications when:
     - I am a superuser.
     - I am the admin of the organization of the application.
    '''

    model = OAuth2Application
    select_related = ('user',)