kopia lustrzana https://github.com/jcarbaugh/python-webfinger
Work towards the security stuff described at
http://code.google.com/p/webfinger/wiki/WebFingerProtocol The code now looks for the host-meta file via https. If it doesn't find it it falls back to http, but causes the response's 'insecure' attribute to be set to True. The 'insecure' attribute also gets set to True if the user's XRD URL is not an https:// url. This doesn't do any checking of certificate validity, or check whether the XML is signed.pull/1/head
rodzic
b893ca3fa8
commit
142bba7a6d
|
@ -22,7 +22,8 @@ class WebFingerExpection(Exception):
|
||||||
|
|
||||||
class WebFingerResponse(object):
|
class WebFingerResponse(object):
|
||||||
|
|
||||||
def __init__(self, xrd):
|
def __init__(self, xrd, insecure):
|
||||||
|
self.insecure = insecure
|
||||||
self._xrd = xrd
|
self._xrd = xrd
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
|
@ -32,9 +33,8 @@ class WebFingerResponse(object):
|
||||||
|
|
||||||
class WebFingerClient(object):
|
class WebFingerClient(object):
|
||||||
|
|
||||||
def __init__(self, host, secure=False):
|
def __init__(self, host):
|
||||||
self._host = host
|
self._host = host
|
||||||
self._secure = secure
|
|
||||||
self._opener = urllib2.build_opener(urllib2.HTTPRedirectHandler())
|
self._opener = urllib2.build_opener(urllib2.HTTPRedirectHandler())
|
||||||
self._opener.addheaders = [('User-agent', 'python-webfinger')]
|
self._opener.addheaders = [('User-agent', 'python-webfinger')]
|
||||||
|
|
||||||
|
@ -47,39 +47,48 @@ class WebFingerClient(object):
|
||||||
conn.close()
|
conn.close()
|
||||||
return response if raw else XRD.parse(response)
|
return response if raw else XRD.parse(response)
|
||||||
|
|
||||||
def hostmeta(self):
|
def hostmeta(self, protocol):
|
||||||
protocol = "https" if self._secure else "http"
|
|
||||||
hostmeta_url = "%s://%s/.well-known/host-meta" % (protocol, self._host)
|
hostmeta_url = "%s://%s/.well-known/host-meta" % (protocol, self._host)
|
||||||
return self.xrd(hostmeta_url)
|
return self.xrd(hostmeta_url)
|
||||||
|
|
||||||
def finger(self, username):
|
def finger(self, username):
|
||||||
|
try:
|
||||||
hm = self.hostmeta()
|
hm = self.hostmeta('https')
|
||||||
|
insecure = False
|
||||||
|
except (urllib2.URLError, urllib2.HTTPError):
|
||||||
|
hm = self.hostmeta('http')
|
||||||
|
insecure = True
|
||||||
|
|
||||||
hm_hosts = self._hm_hosts(hm)
|
hm_hosts = self._hm_hosts(hm)
|
||||||
|
|
||||||
if self._host not in hm_hosts:
|
if self._host not in hm_hosts:
|
||||||
raise WebFingerExpection("hostmeta host did not match account host")
|
raise WebFingerExpection("hostmeta host did not match account host")
|
||||||
|
|
||||||
template = hm.find_link(WEBFINGER_TYPES, attr='template')
|
template = hm.find_link(WEBFINGER_TYPES, attr='template')
|
||||||
|
if not template.startswith('https://'):
|
||||||
|
insecure = True
|
||||||
xrd_url = template.replace('{uri}',
|
xrd_url = template.replace('{uri}',
|
||||||
urllib.quote_plus('acct:%s@%s' % (username, self._host)))
|
urllib.quote_plus('acct:%s@%s' % (username, self._host)))
|
||||||
|
|
||||||
return WebFingerResponse(self.xrd(xrd_url))
|
data = self.xrd(xrd_url)
|
||||||
|
return WebFingerResponse(data, insecure)
|
||||||
|
|
||||||
def finger(identifier, secure=False):
|
def finger(identifier):
|
||||||
if identifier.startswith('acct:'):
|
if identifier.startswith('acct:'):
|
||||||
(acct, identifier) = identifier.split(':', 1)
|
(acct, identifier) = identifier.split(':', 1)
|
||||||
(username, host) = identifier.split('@')
|
(username, host) = identifier.split('@')
|
||||||
client = WebFingerClient(host, secure)
|
client = WebFingerClient(host)
|
||||||
return client.finger(username)
|
return client.finger(username)
|
||||||
|
|
||||||
# example main method
|
# example main method
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
import sys
|
||||||
wf = finger(sys.argv[1], True)
|
wf = finger(sys.argv[1])
|
||||||
print "Avatar: ", wf.avatar
|
print "Avatar: ", wf.avatar
|
||||||
print "HCard: ", wf.hcard
|
print "HCard: ", wf.hcard
|
||||||
print "OpenID: ", wf.open_id
|
print "OpenID: ", wf.open_id
|
||||||
print "Profile:", wf.profile
|
print "Profile:", wf.profile
|
||||||
print "XFN: ", wf.find_link('http://gmpg.org/xfn/11', attr='href')
|
print "XFN: ", wf.find_link('http://gmpg.org/xfn/11', attr='href')
|
||||||
|
if wf.insecure:
|
||||||
|
print "Warning: Data was retrieved over an insecure connection"
|
||||||
|
|
Ładowanie…
Reference in New Issue