Revision 7c3549f0

b/snf-astakos-app/astakos/im/util.py
105 105
        raise ValueError(_(astakos_messages.EMAIL_RESERVED) % locals())
106 106
    return invitation
107 107

  
108

  
108 109
def restrict_next(url, domain=None, allowed_schemes=()):
109 110
    """
110
    Return url if having the supplied ``domain`` (if present) or one of the ``allowed_schemes``.
111
    Otherwise return None.
111
    Utility method to validate that provided url is safe to be used as the
112
    redirect location of an http redirect response. The method parses the
113
    provided url and identifies if it conforms CORS against provided domain
114
    AND url scheme matches any of the schemes in `allowed_schemes` parameter.
115
    If verirication succeeds sanitized safe url is returned so you must use
116
    the method's response in the response location header and not the
117
    originally provided url. If verification fails the method returns None.
112 118

  
113 119
    >>> print restrict_next('/im/feedback', '.okeanos.grnet.gr')
114 120
    /im/feedback
115
    >>> print restrict_next('pithos.okeanos.grnet.gr/im/feedback', '.okeanos.grnet.gr')
121
    >>> print restrict_next('pithos.okeanos.grnet.gr/im/feedback',
122
    ...                     '.okeanos.grnet.gr')
116 123
    //pithos.okeanos.grnet.gr/im/feedback
117
    >>> print restrict_next('https://pithos.okeanos.grnet.gr/im/feedback', '.okeanos.grnet.gr')
124
    >>> print restrict_next('https://pithos.okeanos.grnet.gr/im/feedback',
125
    ...                     '.okeanos.grnet.gr')
118 126
    https://pithos.okeanos.grnet.gr/im/feedback
119 127
    >>> print restrict_next('pithos://127.0.0.1', '.okeanos.grnet.gr')
120 128
    None
121
    >>> print restrict_next('pithos://127.0.0.1', '.okeanos.grnet.gr', allowed_schemes=('pithos'))
122
    pithos://127.0.0,1
129
    >>> print restrict_next('pithos://127.0.0.1', '.okeanos.grnet.gr',
130
    ...                     allowed_schemes=('pithos'))
131
    None
132
    >>> print restrict_next('pithos://127.0.0.1', '127.0.0.1',
133
    ...                     allowed_schemes=('pithos'))
134
    pithos://127.0.0.1
123 135
    >>> print restrict_next('node1.example.com', '.okeanos.grnet.gr')
124 136
    None
125 137
    >>> print restrict_next('//node1.example.com', '.okeanos.grnet.gr')
......
132 144
    //node1.example.com
133 145
    >>> print restrict_next('node1.example.com')
134 146
    //node1.example.com
147
    >>> print restrict_next('node1.example.com', allowed_schemes=('pithos',))
148
    None
149
    >>> print restrict_next('pithos://localhost', 'localhost',
150
    ...                     allowed_schemes=('pithos',))
151
    pithos://localhost
135 152
    """
136 153
    if not url:
137
        return
154
        return None
155

  
138 156
    parts = urlparse(url, scheme='http')
139 157
    if not parts.netloc and not parts.path.startswith('/'):
140 158
        # fix url if does not conforms RFC 1808
141 159
        url = '//%s' % url
142 160
        parts = urlparse(url, scheme='http')
143
    # TODO more scientific checks?
144
    if not parts.netloc:    # internal url
145
        return url
146
    elif not domain:
147
        return url
148
    elif parts.netloc.endswith(domain):
149
        return url
150
    elif parts.scheme in allowed_schemes:
161

  
162
    if not domain and not allowed_schemes:
151 163
        return url
152 164

  
165
    if domain:
166
        if not parts.netloc:
167
            return url
168
        if parts.netloc.endswith(domain):
169
            return url
170
        else:
171
            return None
172

  
173
    if allowed_schemes:
174
        if parts.scheme in allowed_schemes:
175
            return url
176

  
177
    return None
178

  
179

  
153 180
def prepare_response(request, user, next='', renew=False):
154 181
    """Return the unique username and the token
155 182
       as 'X-Auth-User' and 'X-Auth-Token' headers,

Also available in: Unified diff