access_response.py 4.63 KB
Newer Older
1 2 3 4 5
"""
This file contains all the classes used by has_access for error handling
"""

from django.utils.translation import ugettext as _
6
from xmodule.course_metadata_utils import DEFAULT_START_DATE
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88


class AccessResponse(object):
    """Class that represents a response from a has_access permission check."""
    def __init__(self, has_access, error_code=None, developer_message=None, user_message=None):
        """
        Creates an AccessResponse object.

        Arguments:
            has_access (bool): if the user is granted access or not
            error_code (String): optional - default is None. Unique identifier
                for the specific type of error
            developer_message (String): optional - default is None. Message
                to show the developer
            user_message (String): optional - default is None. Message to
                show the user
        """
        self.has_access = has_access
        self.error_code = error_code
        self.developer_message = developer_message
        self.user_message = user_message
        if has_access:
            assert error_code is None

    def __nonzero__(self):
        """
        Overrides bool().

        Allows for truth value testing of AccessResponse objects, so callers
        who do not need the specific error information can check if access
        is granted.

        Returns:
            bool: whether or not access is granted

        """
        return self.has_access

    def to_json(self):
        """
        Creates a serializable JSON representation of an AccessResponse object.

        Returns:
            dict: JSON representation
        """
        return {
            "has_access": self.has_access,
            "error_code": self.error_code,
            "developer_message": self.developer_message,
            "user_message": self.user_message
        }


class AccessError(AccessResponse):
    """
    Class that holds information about the error in the case of an access
    denial in has_access. Contains the error code, user and developer
    messages. Subclasses represent specific errors.
    """
    def __init__(self, error_code, developer_message, user_message):
        """
        Creates an AccessError object.

        An AccessError object represents an AccessResponse where access is
        denied (has_access is False).

        Arguments:
            error_code (String): unique identifier for the specific type of
            error developer_message (String): message to show the developer
            user_message (String): message to show the user

        """
        super(AccessError, self).__init__(False, error_code, developer_message, user_message)


class StartDateError(AccessError):
    """
    Access denied because the course has not started yet and the user
    is not staff
    """
    def __init__(self, start_date):
        error_code = "course_not_started"
89 90 91 92 93 94 95
        if start_date == DEFAULT_START_DATE:
            developer_message = "Course has not started"
            user_message = _("Course has not started")
        else:
            developer_message = "Course does not start until {}".format(start_date)
            user_message = _("Course does not start until {}"  # pylint: disable=translation-of-non-string
                             .format("{:%B %d, %Y}".format(start_date)))
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
        super(StartDateError, self).__init__(error_code, developer_message, user_message)


class MilestoneError(AccessError):
    """
    Access denied because the user has unfulfilled milestones
    """
    def __init__(self):
        error_code = "unfulfilled_milestones"
        developer_message = "User has unfulfilled milestones"
        user_message = _("You have unfulfilled milestones")
        super(MilestoneError, self).__init__(error_code, developer_message, user_message)


class VisibilityError(AccessError):
    """
    Access denied because the user does have the correct role to view this
    course.
    """
    def __init__(self):
        error_code = "not_visible_to_user"
        developer_message = "Course is not visible to this user"
        user_message = _("You do not have access to this course")
        super(VisibilityError, self).__init__(error_code, developer_message, user_message)


class MobileAvailabilityError(AccessError):
    """
    Access denied because the course is not available on mobile for the user
    """
    def __init__(self):
        error_code = "mobile_unavailable"
        developer_message = "Course is not available on mobile for this user"
        user_message = _("You do not have access to this course on a mobile device")
        super(MobileAvailabilityError, self).__init__(error_code, developer_message, user_message)