mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-04-23 19:31:00 +08:00
add support for address based verifications, bump version requirement of blockstack-proofs
This commit is contained in:
@@ -15,6 +15,6 @@ urllib3>=1.20
|
||||
utilitybelt>=0.2.6
|
||||
blockstack>=0.14.1
|
||||
blockstack-profiles>=0.14.1
|
||||
blockstack-proofs>=0.0.8
|
||||
blockstack-proofs>=0.0.9
|
||||
blockstack-zones>=0.14.1
|
||||
pymongo>=3.4.0
|
||||
|
||||
101
api/resolver.py
101
api/resolver.py
@@ -90,18 +90,12 @@ def site_data_to_fixed_proof_url(account, zonefile):
|
||||
account['proofUrl'] = proof
|
||||
|
||||
|
||||
def fetch_proofs(profile, username, profile_ver=2, zonefile = None, refresh=False):
|
||||
def fetch_proofs(profile, username, address, profile_ver=2, zonefile = None):
|
||||
""" Get proofs for a profile and:
|
||||
a) check cached entries
|
||||
b) check which version of profile we're using
|
||||
"""
|
||||
|
||||
if MEMCACHED_ENABLED and not refresh:
|
||||
log.debug("Memcache get proofs: %s" % username)
|
||||
proofs_cache_reply = mc.get("proofs_" + str(username))
|
||||
else:
|
||||
proofs_cache_reply = None
|
||||
|
||||
if 'account' not in profile:
|
||||
return []
|
||||
# fix up missing proofUrls
|
||||
@@ -110,20 +104,10 @@ def fetch_proofs(profile, username, profile_ver=2, zonefile = None, refresh=Fals
|
||||
and 'proofUrl' not in account):
|
||||
site_data_to_fixed_proof_url(account, zonefile)
|
||||
|
||||
if proofs_cache_reply is None:
|
||||
|
||||
if profile_ver == 3:
|
||||
proofs = profile_v3_to_proofs(profile, username)
|
||||
else:
|
||||
proofs = profile_to_proofs(profile, username)
|
||||
|
||||
if MEMCACHED_ENABLED or refresh:
|
||||
log.debug("Memcache set proofs: %s" % username)
|
||||
mc.set("proofs_" + str(username), json.dumps(proofs),
|
||||
int(time() + MEMCACHED_TIMEOUT))
|
||||
if profile_ver == 3:
|
||||
proofs = profile_v3_to_proofs(profile, username, address = address)
|
||||
else:
|
||||
|
||||
proofs = json.loads(proofs_cache_reply)
|
||||
proofs = profile_to_proofs(profile, username, address = address)
|
||||
|
||||
return proofs
|
||||
|
||||
@@ -162,7 +146,7 @@ def is_profile_in_legacy_format(profile):
|
||||
|
||||
return is_in_legacy_format
|
||||
|
||||
def format_profile(profile, fqa, zone_file, refresh=False):
|
||||
def format_profile(profile, fqa, zone_file, address):
|
||||
""" Process profile data and
|
||||
1) Insert verifications
|
||||
2) Check if profile data is valid JSON
|
||||
@@ -171,26 +155,19 @@ def format_profile(profile, fqa, zone_file, refresh=False):
|
||||
data = {'profile' : profile,
|
||||
'zone_file' : zone_file}
|
||||
|
||||
try:
|
||||
username, ns = fqa.split(".")
|
||||
except:
|
||||
data = {'error' : "Failed to split fqa into name and namespace."}
|
||||
return data
|
||||
if ns != 'id':
|
||||
if not fqa.endswith('.id'):
|
||||
data['verifications'] = ["No verifications for non-id namespaces."]
|
||||
return data
|
||||
|
||||
profile_in_legacy_format = is_profile_in_legacy_format(profile)
|
||||
|
||||
if not profile_in_legacy_format:
|
||||
data['verifications'] = fetch_proofs(data['profile'], username,
|
||||
profile_ver=3, zonefile=zone_file,
|
||||
refresh=refresh)
|
||||
data['verifications'] = fetch_proofs(data['profile'], fqa, address,
|
||||
profile_ver=3, zonefile=zone_file)
|
||||
else:
|
||||
if type(profile) is not dict:
|
||||
data['profile'] = json.loads(profile)
|
||||
data['verifications'] = fetch_proofs(data['profile'], username,
|
||||
refresh=refresh)
|
||||
data['verifications'] = fetch_proofs(data['profile'], fqa, address)
|
||||
|
||||
return data
|
||||
|
||||
@@ -205,15 +182,12 @@ def is_valid_fqa(fqa):
|
||||
return False
|
||||
return (NS_PATTERN.match(ns) is not None)
|
||||
|
||||
def get_profile(fqa, refresh=False):
|
||||
def get_profile(fqa):
|
||||
""" Given a fully-qualified username (username.namespace)
|
||||
get the data associated with that fqu.
|
||||
Return cached entries, if possible.
|
||||
"""
|
||||
|
||||
global MEMCACHED_ENABLED
|
||||
global mc
|
||||
|
||||
fqa = fqa.lower()
|
||||
if not is_valid_fqa(fqa):
|
||||
fqa = str(fqa)
|
||||
@@ -232,37 +206,28 @@ def get_profile(fqa, refresh=False):
|
||||
|
||||
return {'error' : 'Malformed name {}'.format(fqa)}
|
||||
|
||||
if MEMCACHED_ENABLED and not refresh:
|
||||
log.debug("Memcache get DHT: %s" % fqa)
|
||||
dht_cache_reply = mc.get("dht_" + str(fqa))
|
||||
else:
|
||||
dht_cache_reply = None
|
||||
|
||||
if dht_cache_reply is None:
|
||||
try:
|
||||
res = blockstack_client.profile.get_profile(fqa, use_legacy = True)
|
||||
if 'error' in res:
|
||||
log.error('Error from profile.get_profile: {}'.format(res['error']))
|
||||
return res
|
||||
profile = res['profile']
|
||||
zonefile = res['zonefile']
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
abort(500, "Connection to blockstack-server %s:%s timed out" %
|
||||
(BLOCKSTACKD_IP, BLOCKSTACKD_PORT))
|
||||
try:
|
||||
res = blockstack_client.profile.get_profile(
|
||||
fqa, use_legacy = True, include_name_record = True)
|
||||
if 'error' in res:
|
||||
log.error('Error from profile.get_profile: {}'.format(res['error']))
|
||||
return res
|
||||
profile = res['profile']
|
||||
zonefile = res['zonefile']
|
||||
address = res['name_record']['address']
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
abort(500, "Connection to blockstack-server %s:%s timed out" %
|
||||
(BLOCKSTACKD_IP, BLOCKSTACKD_PORT))
|
||||
|
||||
if profile is None or 'error' in zonefile:
|
||||
log.error("{}".format(zonefile))
|
||||
abort(404)
|
||||
prof_data = {'response' : profile}
|
||||
if MEMCACHED_ENABLED or refresh:
|
||||
log.debug("Memcache set DHT: %s" % fqa)
|
||||
mc.set("dht_" + str(fqa), json.dumps(data),
|
||||
int(time() + MEMCACHED_TIMEOUT))
|
||||
else:
|
||||
prof_data = json.loads(dht_cache_reply)
|
||||
if profile is None or 'error' in zonefile:
|
||||
log.error("{}".format(zonefile))
|
||||
abort(404)
|
||||
|
||||
data = format_profile(prof_data['response'], fqa, zonefile)
|
||||
prof_data = {'response' : profile}
|
||||
|
||||
data = format_profile(prof_data['response'], fqa, zonefile, address)
|
||||
|
||||
return data
|
||||
|
||||
@@ -274,12 +239,7 @@ def get_users(username):
|
||||
""" Fetch data from username in .id namespace
|
||||
"""
|
||||
reply = {}
|
||||
refresh = False
|
||||
|
||||
try:
|
||||
refresh = request.args.get('refresh')
|
||||
except:
|
||||
pass
|
||||
|
||||
if username is None:
|
||||
reply['error'] = "No username given"
|
||||
@@ -294,7 +254,8 @@ def get_users(username):
|
||||
fqa = "{}.{}".format(username, 'id')
|
||||
else:
|
||||
fqa = username
|
||||
profile = get_profile(fqa, refresh=refresh)
|
||||
|
||||
profile = get_profile(fqa)
|
||||
|
||||
reply[username] = profile
|
||||
if 'error' in profile:
|
||||
|
||||
@@ -28,7 +28,7 @@ import unittest
|
||||
|
||||
import api
|
||||
|
||||
PROFILE_URL = "/v2/users/{}"
|
||||
PROFILE_URL = "/v1/users/{}"
|
||||
|
||||
class ResolverTestCase(unittest.TestCase):
|
||||
|
||||
@@ -39,7 +39,7 @@ class ResolverTestCase(unittest.TestCase):
|
||||
url = PROFILE_URL.format(username)
|
||||
r = self.client.get(url)
|
||||
return json.loads(r.data)
|
||||
|
||||
|
||||
|
||||
def test_valid_profiles(self):
|
||||
""" Check valid profiles
|
||||
|
||||
Reference in New Issue
Block a user