def identity_url(request, local_id): """Returns an OpenID identity URL for the given local identifier.""" if 'x-vhm-host' in request.headers: # We are using repoze.vhm and a front-end web server to control the # URLs to the application. url = urlparse.urlparse(request.headers['x-vhm-host']) return urinorm(u'http://{local_id}.{domain}'.format( local_id=local_id, domain=url.netloc)) else: # No special virtual hosting is taking place so we can use the route # url for the identity page directly. return urinorm(route_url('openid_identity', request, local_id=local_id))
def test_path_dots(self): self.assertEqual(urinorm('http://example.com/./a'), 'http://example.com/a') self.assertEqual(urinorm('http://example.com/../a'), 'http://example.com/a') self.assertEqual(urinorm('http://example.com/a/.'), 'http://example.com/a/') self.assertEqual(urinorm('http://example.com/a/..'), 'http://example.com/') self.assertEqual(urinorm('http://example.com/a/./'), 'http://example.com/a/') self.assertEqual(urinorm('http://example.com/a/../'), 'http://example.com/') self.assertEqual(urinorm('http://example.com/a/./b'), 'http://example.com/a/b') self.assertEqual(urinorm('http://example.com/a/../b'), 'http://example.com/b') self.assertEqual(urinorm('http://example.com/a/b/c/./../../g'), 'http://example.com/a/g') self.assertEqual(urinorm('http://example.com/mid/content=5/../6'), 'http://example.com/mid/6')
def normalizeURL(url): """Normalize a URL, converting normalization failures to DiscoveryFailure""" try: normalized = urinorm.urinorm(url) except ValueError, why: raise DiscoveryFailure('Normalizing identifier: %s' % (why[0],), None)
def _parseURL(url): try: url = urinorm.urinorm(url) except ValueError: return None proto, netloc, path, params, query, frag = urlparse(url) if not path: # Python <2.4 does not parse URLs with no path properly if not query and '?' in netloc: netloc, query = netloc.split('?', 1) path = '/' path = urlunparse(('', '', path, params, query, frag)) if ':' in netloc: try: host, port = netloc.split(':') except ValueError: return None if not re.match(r'\d+$', port): return None else: host = netloc port = '' host = host.lower() if not host_segment_re.match(host): return None return proto, host, port, path
def _is_valid_openid_for_this_site(identity): try: identity = urinorm(identity) idparts = urlparse.urlparse(identity) srvparts = urlparse.urlparse(settings.SSO_ROOT_URL) if identity == IDENTIFIER_SELECT: return True if (idparts.port != srvparts.port or idparts.scheme != srvparts.scheme): return False if (idparts.hostname != srvparts.hostname and not srvparts.hostname.endswith(".%s" % idparts.hostname)): return False accept_path_patterns = [ '^/$', '^/\+id/[a-zA-Z0-9\-_\.]+$', '^/~[a-zA-Z0-9\-_\.]+$', ] for pattern in accept_path_patterns: if re.match(pattern, idparts.path) is not None: return True return False except: return False
def normalizeURL(url): """Normalize a URL, converting normalization failures to DiscoveryFailure""" try: normalized = urinorm.urinorm(url) except ValueError as why: raise DiscoveryFailure('Normalizing identifier: %s' % (why[0],), None) else: return urllib.parse.urldefrag(normalized)[0]
def _parseURL(url): try: url = urinorm.urinorm(url) except ValueError: return None split_url = urlsplit(url) path = urlunsplit(('', '', split_url.path or '/', split_url.query, split_url.fragment)) return split_url.scheme, split_url.hostname, split_url.port, path
def extract_local_id(request, id_url, relaxed=False): """Given an OpenID identity URL attempts to return the username of the local user that the identity URL refers to. If relaxed=True, the id_url may omit the URL scheme and the currently active URL scheme will be assumed. Returns an empty string if fails to extract the username. """ # Generate a regexp to extract the username from the identity url USERNAME_RE = re.compile(urinorm(identity_url(request, '_re_marker_'))\ .replace('_re_marker_', '([^/\s]+)')\ .replace('https', 'http')) try: match = USERNAME_RE.match(urinorm(id_url)) if match is not None: return match.group(1) except ValueError: if relaxed: match = USERNAME_RE.match(urinorm('http://{0}'.format(id_url))) if match is not None: return match.group(1) return u''
def test_default_ports(self): self.assertEqual(urinorm('http://example.com:80/'), 'http://example.com/') self.assertEqual(urinorm('https://example.com:443/'), 'https://example.com/')
def test_normalized(self): self.assertEqual(urinorm('http://example.com/'), 'http://example.com/') warning_msg = "Binary input for urinorm is deprecated. Use text input instead." with ShouldWarn(DeprecationWarning(warning_msg)): warnings.simplefilter('always') self.assertEqual(urinorm(b'http://example.com/'), 'http://example.com/')
def test_realms(self): # Urinorm supports OpenID realms with * in them self.assertEqual(urinorm('http://*.example.com/'), 'http://*.example.com/')
def test_lowercase_hostname(self): self.assertEqual(urinorm('http://exaMPLE.COm/'), 'http://example.com/')
def test_empty_hostname(self): self.assertEqual(urinorm('http://username@/'), 'http://username@/')
def test_path_keep_sub_delims(self): self.assertEqual(urinorm('http://example.com/foo+!bar'), 'http://example.com/foo+!bar')
def test_empty_port_section(self): self.assertEqual(urinorm('http://example.com:/'), 'http://example.com/')
def test_idn_hostname(self): self.assertEqual(urinorm('http://π.example.com/'), 'http://xn--1xa.example.com/')
def test_lowercase_scheme(self): self.assertEqual(urinorm('htTP://example.com/'), 'http://example.com/')
def test_path_percent_decode_sub_delims(self): self.assertEqual(urinorm('http://example.com/foo%2B%21bar'), 'http://example.com/foo+!bar')
def test_empty_path(self): self.assertEqual(urinorm('http://example.com'), 'http://example.com/')
def test_path_capitalize_percent_encoding(self): self.assertEqual(urinorm('http://example.com/foo%3abar'), 'http://example.com/foo%3Abar')
def test_path_percent_encoding(self): self.assertEqual(urinorm('http://example.com/'), 'http://example.com/%08') self.assertEqual(urinorm('http://example.com/Λ'), 'http://example.com/%CE%9B')
def test_path_percent_decode_unreserved(self): self.assertEqual(urinorm('http://example.com/foo%2Dbar%2dbaz'), 'http://example.com/foo-bar-baz')
def test_path_capitalize_percent_encoding(self): self.assertEqual(urinorm('http://example.com/foo%2cbar'), 'http://example.com/foo%2Cbar')