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