コード例 #1
0
def load_user(record_hash):
    """
    Load a user record from the storage implementation with the given hex string hash,
    The user record hash should have been loaded from the blockchain, and thereby be the
    authentic hash.

    Return the user record on success
    Return None on error
    """

    user_json = storage.get_immutable_data(record_hash)
    if user_json is None:
        log.error("Failed to load user record '%s'" % record_hash)
        return None

    # verify integrity
    user_record_hash = storage.get_data_hash(user_json)
    if user_record_hash != record_hash:
        log.error(
            "Profile hash mismatch: expected '%s', got '%s'" % record_hash,
            user_record_hash)
        return None

    user = user_db.parse_user(user_json)
    return user
コード例 #2
0
ファイル: zonefile.py プロジェクト: Redd-ID/blockstack-core
def load_name_zonefile(name, expected_zonefile_hash, storage_drivers=None, raw_zonefile=False, allow_legacy=False, proxy=None ):
    """
    Fetch and load a user zonefile from the storage implementation with the given hex string hash,
    The user zonefile hash should have been loaded from the blockchain, and thereby be the
    authentic hash.

    If raw_zonefile is True, then return the raw zonefile data.  Don't parse it.
    If however, raw_zonefile is False, the zonefile will be parsed.  If name is given, the $ORIGIN will be checked.

    Return the user zonefile (as a dict) on success
    Return None on error
    """

    proxy = get_default_proxy() if proxy is None else proxy
    conf = proxy.conf
    
    assert 'server' in conf, json.dumps(conf, indent=4, sort_keys=True)
    assert 'port' in conf, json.dumps(conf, indent=4, sort_keys=True)

    atlas_host = conf['server']
    atlas_port = conf['port']
    hostport = '{}:{}'.format( atlas_host, atlas_port )

    zonefile_txt = None
    expected_zonefile_hash = str(expected_zonefile_hash)

    # try atlas node first 
    res = get_zonefiles( hostport, [expected_zonefile_hash], proxy=proxy )
    if 'error' in res or expected_zonefile_hash not in res['zonefiles'].keys():
        # fall back to storage drivers if atlas node didn't have it
        zonefile_txt = storage.get_immutable_data(
                expected_zonefile_hash, hash_func=storage.get_zonefile_data_hash, 
                fqu=name, zonefile=True, drivers=storage_drivers
        )

        if zonefile_txt is None:
            log.error('Failed to load user zonefile "{}"'.format(expected_zonefile_hash))
            return None

    else:
        # extract 
        log.debug('Fetched {} from Atlas peer {}'.format(expected_zonefile_hash, hostport))
        zonefile_txt = res['zonefiles'][expected_zonefile_hash]

    if raw_zonefile:
        msg = 'Driver did not return a serialized zonefile'
        try:
            assert isinstance(zonefile_txt, (str, unicode)), msg
        except AssertionError as ae:
            if BLOCKSTACK_TEST is not None:
                log.exception(ae)

            log.error(msg)
            return None

        return zonefile_txt

    parsed_zonefile = decode_name_zonefile(name, zonefile_txt, allow_legacy=allow_legacy)
    return parsed_zonefile
コード例 #3
0
def load_name_zonefile(name, expected_zonefile_hash, storage_drivers=None, raw_zonefile=False, allow_legacy=False, proxy=None ):
    """
    Fetch and load a user zonefile from the storage implementation with the given hex string hash,
    The user zonefile hash should have been loaded from the blockchain, and thereby be the
    authentic hash.

    If raw_zonefile is True, then return the raw zonefile data.  Don't parse it.
    If however, raw_zonefile is False, the zonefile will be parsed.  If name is given, the $ORIGIN will be checked.

    Return the user zonefile (as a dict) on success
    Return None on error
    """

    proxy = get_default_proxy() if proxy is None else proxy
    conf = proxy.conf
    
    assert 'server' in conf, json.dumps(conf, indent=4, sort_keys=True)
    assert 'port' in conf, json.dumps(conf, indent=4, sort_keys=True)

    atlas_host = conf['server']
    atlas_port = conf['port']
    hostport = '{}:{}'.format( atlas_host, atlas_port )

    zonefile_txt = None
    expected_zonefile_hash = str(expected_zonefile_hash)

    # try atlas node first 
    res = get_zonefiles( hostport, [expected_zonefile_hash], proxy=proxy )
    if 'error' in res or expected_zonefile_hash not in res['zonefiles'].keys():
        # fall back to storage drivers if atlas node didn't have it
        zonefile_txt = storage.get_immutable_data(
                expected_zonefile_hash, hash_func=storage.get_zonefile_data_hash, 
                fqu=name, zonefile=True, drivers=storage_drivers
        )

        if zonefile_txt is None:
            log.error('Failed to load user zonefile "{}"'.format(expected_zonefile_hash))
            return None

    else:
        # extract 
        log.debug('Fetched {} from Atlas peer {}'.format(expected_zonefile_hash, hostport))
        zonefile_txt = res['zonefiles'][expected_zonefile_hash]

    if raw_zonefile:
        msg = 'Driver did not return a serialized zonefile'
        try:
            assert isinstance(zonefile_txt, (str, unicode)), msg
        except AssertionError as ae:
            if BLOCKSTACK_TEST is not None:
                log.exception(ae)

            log.error(msg)
            return None

        return zonefile_txt

    parsed_zonefile = decode_name_zonefile(name, zonefile_txt, allow_legacy=allow_legacy)
    return parsed_zonefile
コード例 #4
0
ファイル: data.py プロジェクト: paulpw/blockstack-cli
def get_immutable(name, data_hash, data_id=None, proxy=None):
    """
    get_immutable

    Fetch a piece of immutable data.  Use @data_hash to look it up
    in the user's zonefile, and then fetch and verify the data itself
    from the configured storage providers.

    Return {'data': the data, 'hash': hash} on success
    Return {'error': ...} on failure
    """

    if proxy is None:
        proxy = get_default_proxy()

    user_zonefile = get_name_zonefile(name, proxy=proxy)
    if user_zonefile is None:
        return {'error': 'No user zonefile defined'}

    if 'error' in user_zonefile:
        return user_zonefile 

    if blockstack_profiles.is_profile_in_legacy_format( user_zonefile ) or not user_db.is_user_zonefile( user_zonefile ):
        # zonefile is really a legacy profile 
        return {'error': 'Profile is in a legacy format that does not support immutable data.'}

    if data_id is not None:
        # look up hash by name 
        h = user_db.get_immutable_data_hash( user_zonefile, data_id )
        if h is None:
            return {'error': 'No such immutable datum'}
         
        if type(h) == list:
            # this tool doesn't allow this to happen (one ID matches one hash),
            # but that doesn't preclude the user from doing this with other tools.
            if data_hash is not None and data_hash not in h:
                return {'error': 'Data ID/hash mismatch'}

            else:
                return {'error': "Multiple matches for '%s': %s" % (data_id, ",".join(h))}

        if data_hash is not None:
            if h != data_hash:
                return {'error': 'Data ID/hash mismatch'}

        else:
            data_hash = h

    elif not user_db.has_immutable_data( user_zonefile, data_hash ):
        return {'error': 'No such immutable datum'}

    data_url_hint = user_db.get_immutable_data_url( user_zonefile, data_hash )
    data = storage.get_immutable_data( data_hash, fqu=name, data_id=data_id, data_url=data_url_hint )
    if data is None:
        return {'error': 'No immutable data returned'}

    return {'data': data, 'hash': data_hash}
コード例 #5
0
def load_user(record_hash):
    """
    Load a user record from the storage implementation with the given hex string hash,
    The user record hash should have been loaded from the blockchain, and thereby be the
    authentic hash.

    Return the user record on success
    Return None on error
    """

    user_json = storage.get_immutable_data(record_hash)
    if user_json is None:
        log.error("Failed to load user record '%s'" % record_hash)
        return None

    # verify integrity
    user_record_hash = storage.get_data_hash(user_json)
    if user_record_hash != record_hash:
        log.error("Profile hash mismatch: expected '%s', got '%s'" % record_hash, user_record_hash)
        return None

    user = user_db.parse_user(user_json)
    return user
コード例 #6
0
def get_immutable(name, data_key):
    """
    get_immutable
    """

    user = get_name_record(name)
    if 'error' in user:

        # no user data
        return {'error': "Unable to load user record: %s" % user['error']}

    if not user_db.has_immutable_data(user, data_key):

        # no data
        return {'error': 'Profile has no such immutable data'}

    data = storage.get_immutable_data(data_key)
    if data is None:

        # no data
        return {'error': 'No immutable data found'}

    return {'data': data}
コード例 #7
0
def get_immutable(name, data_key):
    """
    get_immutable
    """

    user = get_name_record(name)
    if 'error' in user:

        # no user data
        return {'error': "Unable to load user record: %s" % user['error']}

    if not user_db.has_immutable_data(user, data_key):

        # no data
        return {'error': 'Profile has no such immutable data'}

    data = storage.get_immutable_data(data_key)
    if data is None:

        # no data
        return {'error': 'No immutable data found'}

    return {'data': data}