1from pyramid.httpexceptions import (
2    HTTPBadRequest,
3    HTTPNotFound,
4    HTTPForbidden,
5    )
6
7NotFound = HTTPNotFound # bw compat
8Forbidden = HTTPForbidden # bw compat
9
10CR = '\n'
11
12
13class BadCSRFOrigin(HTTPBadRequest):
14    """
15    This exception indicates the request has failed cross-site request forgery
16    origin validation.
17    """
18    title = "Bad CSRF Origin"
19    explanation = (
20        "Access is denied. This server can not verify that the origin or "
21        "referrer of your request matches the current site. Either your "
22        "browser supplied the wrong Origin or Referrer or it did not supply "
23        "one at all."
24    )
25
26
27class BadCSRFToken(HTTPBadRequest):
28    """
29    This exception indicates the request has failed cross-site request
30    forgery token validation.
31    """
32    title = 'Bad CSRF Token'
33    explanation = (
34        'Access is denied.  This server can not verify that your cross-site '
35        'request forgery token belongs to your login session.  Either you '
36        'supplied the wrong cross-site request forgery token or your session '
37        'no longer exists.  This may be due to session timeout or because '
38        'browser is not supplying the credentials required, as can happen '
39        'when the browser has cookies turned off.')
40
41class PredicateMismatch(HTTPNotFound):
42    """
43    This exception is raised by multiviews when no view matches
44    all given predicates.
45
46    This exception subclasses the :class:`HTTPNotFound` exception for a
47    specific reason: if it reaches the main exception handler, it should
48    be treated as :class:`HTTPNotFound`` by any exception view
49    registrations. Thus, typically, this exception will not be seen
50    publicly.
51
52    However, this exception will be raised if the predicates of all
53    views configured to handle another exception context cannot be
54    successfully matched.  For instance, if a view is configured to
55    handle a context of ``HTTPForbidden`` and the configured with
56    additional predicates, then :class:`PredicateMismatch` will be
57    raised if:
58
59    * An original view callable has raised :class:`HTTPForbidden` (thus
60      invoking an exception view); and
61    * The given request fails to match all predicates for said
62      exception view associated with :class:`HTTPForbidden`.
63
64    The same applies to any type of exception being handled by an
65    exception view.
66    """
67
68class URLDecodeError(UnicodeDecodeError):
69    """
70    This exception is raised when :app:`Pyramid` cannot
71    successfully decode a URL or a URL path segment.  This exception
72    behaves just like the Python builtin
73    :exc:`UnicodeDecodeError`. It is a subclass of the builtin
74    :exc:`UnicodeDecodeError` exception only for identity purposes,
75    mostly so an exception view can be registered when a URL cannot be
76    decoded.
77    """
78
79class ConfigurationError(Exception):
80    """ Raised when inappropriate input values are supplied to an API
81    method of a :term:`Configurator`"""
82
83class ConfigurationConflictError(ConfigurationError):
84    """ Raised when a configuration conflict is detected during action
85    processing"""
86
87    def __init__(self, conflicts):
88        self._conflicts = conflicts
89
90    def __str__(self):
91        r = ["Conflicting configuration actions"]
92        items = sorted(self._conflicts.items())
93        for discriminator, infos in items:
94            r.append("  For: %s" % (discriminator, ))
95            for info in infos:
96                for line in str(info).rstrip().split(CR):
97                    r.append("    " + line)
98
99        return CR.join(r)
100
101
102class ConfigurationExecutionError(ConfigurationError):
103    """An error occurred during execution of a configuration action
104    """
105
106    def __init__(self, etype, evalue, info):
107        self.etype, self.evalue, self.info = etype, evalue, info
108
109    def __str__(self):
110        return "%s: %s\n  in:\n  %s" % (self.etype, self.evalue, self.info)
111
112class CyclicDependencyError(Exception):
113    """ The exception raised when the Pyramid topological sorter detects a
114    cyclic dependency."""
115    def __init__(self, cycles):
116        self.cycles = cycles
117
118    def __str__(self):
119        L = []
120        cycles = self.cycles
121        for cycle in cycles:
122            dependent = cycle
123            dependees = cycles[cycle]
124            L.append('%r sorts before %r' % (dependent, dependees))
125        msg = 'Implicit ordering cycle:' + '; '.join(L)
126        return msg
127