<commit_before>from rest_framework.permissions import BasePermission

from kolibri.core.auth.permissions.general import _user_is_admin_for_own_facility


class FacilitySyncPermissions(BasePermission):
    """
    A user can sync a facility with a peer or KDP if they are an admin in their
    own facility or a superuser
    """

    def has_permission(self, request, view):
        return request.user.is_superuser or _user_is_admin_for_own_facility(
            request.user
        )

    def has_object_permission(self, request, view):
        return request.user.is_superuser or _user_is_admin_for_own_facility(
            request.user
        )<commit_msg>Implement a task permissions model.<commit_after>from abc import ABCMeta
from abc import abstractmethod

from six import with_metaclass

from kolibri.core.auth.permissions.general import _user_is_admin_for_own_facility


class BasePermission(with_metaclass(ABCMeta)):
    """
    Base Permission class from which all other Permission classes should inherit.


    The following methods should be overridden in child classes:

    - The following Boolean (True/False) permission checks:
        - `user_can_run_job`
        - `user_can_read_job`
    - If a user can run a job, they will be able to create, cancel, and clear the job.
    - If a user can read a job, they will be able to see the job's status and progress.
    """

    def has_permission(self, user, job, view):
        if view.action == "list" or view.action == "retrieve":
            return self.user_can_read_job(user, job)
        return self.user_can_run_job(user, job)

    @abstractmethod
    def user_can_run_job(self, user, job):
        pass

    @abstractmethod
    def user_can_read_job(self, user, job):
        pass

    def __or__(self, other):
        """
        Allow two instances of BasePermission to be joined together with "|", which returns a permissions class
        that grants permission for an object when *either* of the instances would grant permission for that object.
        """
        return PermissionsFromAny(self, other)

    def __and__(self, other):
        """
        Allow two instances of BasePermission to be joined together with "&", which returns a permissions class
        that grants permission for an object when *both* of the instances grant permission for that object.
        """
        return PermissionsFromAll(self, other)


class PermissionsFromAny(BasePermission):
    """
    Serves as an "OR" operator for Permission classes; pass in a number of Permission classes,
    and the permission-checking methods on the PermissionsFromAny instance will return True if
    any of the Permission classes passed in (the "children" permissions) return True.
    """

    def __init__(self, *perms):
        self.perms = []
        for perm in perms:
            # ensure that perm is an instance of a subclass of BasePermission
            if not isinstance(perm, BasePermission):
                raise AssertionError(
                    "each of the arguments to __init__ must be a subclass (or instance of a subclass) of BasePermissions"
                )
            # add it into the children permissions list
            self.perms.append(perm)

    def _permissions_from_any(self, user, job, method_name):
        """
        Private helper method to do the corresponding method calls on children permissions instances,
        and succeed as soon as one of them succeeds, or fail if none of them do.
        """
        for perm in self.perms:
            if getattr(perm, method_name)(user, job):
                return True
        return False

    def user_can_run_job(self, user, job):
        return self._permissions_from_any(user, job, "user_can_run_job")

    def user_can_read_job(self, user, job):
        return self._permissions_from_any(user, job, "user_can_read_job")


class PermissionsFromAll(BasePermission):
    """
    Serves as an "AND" operator for Permission classes; pass in a number of Permission classes,
    and the permission-checking methods on the PermissionsFromAll instance will return True only if
    all of the Permission classes passed in (the "children" permissions) return True.
    """

    def __init__(self, *perms):
        self.perms = []
        for perm in perms:
            # ensure that perm is an instance of a subclass of BasePermission
            if not isinstance(perm, BasePermission):
                raise AssertionError(
                    "each of the arguments to __init__ must be a subclass (or instance of a subclass) of BasePermissions"
                )
            # add it into the children permissions list
            self.perms.append(perm)

    def _permissions_from_all(self, user, job, method_name):
        """
        Private helper method to do the corresponding method calls on children permissions instances,
        and fail as soon as one of them fails, or succeed if all of them succeed.
        """
        for perm in self.perms:
            if not getattr(perm, method_name)(user, job):
                return False
        return True

    def user_can_run_job(self, user, job):
        return self._permissions_from_all(user, job, "user_can_run_job")

    def user_can_read_job(self, user, job):
        return self._permissions_from_all(user, job, "user_can_read_job")


class IsSuperAdmin(BasePermission):
    """
    Permission class that grants permission for an object if the user is a superuser
    """

    def user_can_run_job(self, user, job):
        return user.is_superuser

    def user_can_read_job(self, user, job):
        return user.is_superuser


class CanManageContent(BasePermission):
    """
    Permission class that grants permission for an object if the user is a superuser
    """

    def user_can_run_job(self, user, job):
        return user.can_manage_content

    def user_can_read_job(self, user, job):
        return user.can_manage_content


class IsFacilityAdmin(BasePermission):
    """
    Basic permission class to check if the user is an admin.
    """

    def user_can_run_job(self, user, job):
        return _user_is_admin_for_own_facility(user)

    def user_can_read_job(self, user, job):
        return _user_is_admin_for_own_facility(user)


class IsAdmin(PermissionsFromAny):
    def __init__(self):
        super(IsAdmin, self).__init__(IsSuperAdmin(), IsFacilityAdmin())


class HasSameFacilityAsJob(BasePermission):
    def user_can_run_job(self, user, job):
        return user.facility_id == job.facility_id

    def user_can_read_job(self, user, job):
        return user.facility_id == job.facility_id


class IsFacilityAdminForJob(PermissionsFromAll):
    def __init__(self):
        super(IsFacilityAdminForJob, self).__init__(
            IsFacilityAdmin(), HasSameFacilityAsJob()
        )


class IsAdminForJob(PermissionsFromAny):
    def __init__(self):
        super(IsAdminForJob, self).__init__(IsSuperAdmin(), IsFacilityAdminForJob())


class NotProvisioned(BasePermission):
    def user_can_run_job(self, user, job):
        from kolibri.core.device.utils import device_provisioned

        return not device_provisioned()

    def user_can_read_job(self, user, job):
        from kolibri.core.device.utils import device_provisioned

        return not device_provisioned()
{'fraction_non_alphanumeric': 0.06865426695842451, 'fraction_numerical': 0.0, 'mean_word_length': 2.9508373851971905, 'pattern_counts': {'":': 1, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5810745', 'n_tokens_mistral': 2054, 'n_tokens_neox': 1988, 'n_words': 692}