示例#1
0
def test_from_uri_malformed_uri(uri):
    from cryptoconditions.condition import Condition
    from cryptoconditions.exceptions import ParsingError

    # Note that the uri will contain `sha-265` instead of `sha-256`
    with raises(ParsingError):
        Condition.from_uri(uri)
示例#2
0
def test_from_uri_parse_error_missing_cost(uri):
    from cryptoconditions.condition import Condition
    from cryptoconditions.exceptions import ParsingError
    with raises(ParsingError) as exc_info:
        Condition.from_uri(uri)
    assert exc_info.value.args == (
        'Invalid condition format: "cost" parameter or value missing.',)
示例#3
0
def test_from_uri_prefix_error(uri):
    from cryptoconditions.condition import Condition, CONDITION_URI_SCHEME
    from cryptoconditions.exceptions import PrefixError
    with raises(PrefixError) as exc_info:
        Condition.from_uri(uri)
    assert exc_info.value.args == (
        'Serialized condition must start with "{}:"'
        .format(CONDITION_URI_SCHEME),)
示例#4
0
def test_condition_cost():
    from cryptoconditions.condition import Condition
    condition = Condition()

    # raises a ValueError if the cost is not an int
    condition.cost = 'a'
    with raises(ValueError):
        condition.cost
示例#5
0
def test_from_uri_with_unsupported_type(uri):
    from cryptoconditions.condition import Condition
    from cryptoconditions.exceptions import UnsupportedTypeError
    with raises(UnsupportedTypeError) as exc_info:
        Condition.from_uri(uri)
    condition_type = parse_qs(urlparse(uri.rstrip()).query)['fpt'][0]
    assert exc_info.value.args == (
        'Type {} is not supported'.format(condition_type),)
示例#6
0
def test_condition_comparison(minimal_ed25519, minimal_prefix):
    from cryptoconditions.condition import Condition

    assert Condition.from_uri(minimal_ed25519.condition_uri) == \
        Condition.from_uri(minimal_ed25519.condition_uri)

    assert not Condition.from_uri(minimal_ed25519.condition_uri) == \
        Condition.from_uri(minimal_prefix.condition_uri)
示例#7
0
def test_from_uri_invalid_arguments(minimal_ed25519):
    from cryptoconditions.condition import Condition

    # raises a TypeError if the serialized_condition is not a str
    with raises(TypeError):
        Condition.from_uri(1)

    # Note: This should be removed in future versions of the code
    # from uri will return the the condition instance if we pass it a
    # condition instance
    condition = Condition.from_uri(minimal_ed25519.condition_uri)
    assert Condition.from_uri(condition) == condition
示例#8
0
def test_condition_hash():
    from cryptoconditions.condition import Condition
    condition = Condition()

    # raises an exception if hash is not 32 bytes long
    with raises(ValueError):
        condition.hash = 'a'

    # raises a ValueError if the hash is not set
    with raises(ValueError):
        condition.hash

    # correctly set the hash
    condition.hash = 'a' * 32
    assert condition.hash == 'a' * 32
示例#9
0
 def subcondition(self, subcondition):
     if isinstance(subcondition, str):
         subcondition = Condition.from_uri(subcondition)
     elif not isinstance(subcondition, Condition):
         raise Exception(
             'Subconditions must be URIs or objects of type Condition')
     self._subcondition = subcondition
示例#10
0
    def parse_payload(self, reader, *args):
        """
        Parse a fulfillment payload.

        Read a fulfillment payload from a Reader and populate this object with that fulfillment.

        Args:
            reader (Reader): Source to read the fulfillment payload from.
        """
        if not isinstance(reader, Reader):
            raise TypeError('reader must be a Reader instance')
        self.threshold = reader.read_var_uint()

        condition_count = reader.read_var_uint()
        for i in range(condition_count):
            weight = reader.read_var_uint()
            # reader, weight = read_weight(reader)
            fulfillment = reader.read_var_octet_string()
            condition = reader.read_var_octet_string()

            if len(fulfillment) and len(condition):
                raise TypeError('Subconditions may not provide both subcondition and fulfillment.')
            elif len(fulfillment):
                self.add_subfulfillment(Fulfillment.from_binary(fulfillment), weight)
            elif len(condition):
                self.add_subcondition(Condition.from_binary(condition), weight)
            else:
                raise TypeError('Subconditions must provide either subcondition or fulfillment.')
    def parse_dict(self, data):
        """
        Generate fulfillment payload from a dict

        Args:
            data (dict): description of the fulfillment

        Returns:
            Fulfillment
        """
        if not isinstance(data, dict):
            raise TypeError('reader must be a dict instance')
        self.threshold = data['threshold']

        for subfulfillments in data['subfulfillments']:
            weight = subfulfillments['weight']

            if subfulfillments['type'] == FULFILLMENT:
                self.add_subfulfillment(Fulfillment.from_dict(subfulfillments),
                                        weight)
            elif subfulfillments['type'] == CONDITION:
                self.add_subcondition(Condition.from_dict(subfulfillments),
                                      weight)
            else:
                raise TypeError(
                    'Subconditions must provide either subcondition or fulfillment.'
                )
    def parse_payload(self, reader, *args):
        """
        Parse a fulfillment payload.

        Read a fulfillment payload from a Reader and populate this object with that fulfillment.

        Args:
            reader (Reader): Source to read the fulfillment payload from.
        """
        if not isinstance(reader, Reader):
            raise TypeError('reader must be a Reader instance')
        self.threshold = reader.read_var_uint()

        condition_count = reader.read_var_uint()
        for i in range(condition_count):
            weight = reader.read_var_uint()
            fulfillment = reader.read_var_octet_string()
            condition = reader.read_var_octet_string()

            if len(fulfillment) and len(condition):
                raise TypeError('Subconditions may not provide both subcondition and fulfillment.')
            elif len(fulfillment):
                self.add_subfulfillment(Fulfillment.from_binary(fulfillment), weight)
            elif len(condition):
                self.add_subcondition(Condition.from_binary(condition), weight)
            else:
                raise TypeError('Subconditions must provide either subcondition or fulfillment.')
示例#13
0
 def subcondition(self, subcondition):
     if isinstance(subcondition, str):
         subcondition = Condition.from_uri(subcondition)
     elif not isinstance(subcondition,  Condition):
         raise Exception(
             'Subconditions must be URIs or objects of type Condition')
     self._subcondition = subcondition
示例#14
0
    def condition(self):
        """
        Generate condition corresponding to this fulfillment.

        An important property of crypto-conditions is that the condition can always
        be derived from the fulfillment. This makes it very easy to post
        fulfillments to a system without having to specify which condition the
        relate to. The system can keep an index of conditions and look up any
        matching events related to that condition.

        Return:
            Condition: Condition corresponding to this fulfillment.
        """
        condition = Condition()
        condition.type_id = self.type_id
        condition.hash = self.generate_hash()
        condition.cost = self.calculate_cost()
        condition.subtypes = self.subtypes
        return condition
示例#15
0
    def add_subcondition_uri(self, subcondition_uri):
        """
        Add a subcondition (unfulfilled).

        This will automatically parse the URI and call addSubcondition.

        Args:
            subcondition_uri (str): Subcondition URI.
        """
        if not isinstance(subcondition_uri, str):
            raise TypeError('Subcondition must be provided as a URI string, was {}'.format(subcondition_uri))
        self.add_subcondition(Condition.from_uri(subcondition_uri))
    def add_subcondition_uri(self, subcondition_uri):
        """
        Add a subcondition (unfulfilled).

        This will automatically parse the URI and call addSubcondition.

        Args:
            subcondition_uri (str): Subcondition URI.
        """
        if not isinstance(subcondition_uri, str):
            raise TypeError('Subcondition must be provided as a URI string')
        self.add_subcondition(Condition.from_uri(subcondition_uri))
示例#17
0
 def parse_asn1_dict_payload(self, data):
     self.threshold = len(data['subfulfillments'])
     for subfulfillment in data['subfulfillments']:
         self.subconditions.append({
             'type': FULFILLMENT,
             'body': Fulfillment.from_asn1_dict(subfulfillment),
         })
     for subcondition in data['subconditions']:
         self.subconditions.append({
             'type': CONDITION,
             'body': Condition.from_asn1_dict(subcondition),
         })
示例#18
0
    def parse_dict(self, data):
        """
        Generate fulfillment payload from a dict

        Args:
            data (dict): description of the fulfillment

        Returns:
            Fulfillment
        """
        self.threshold = data['threshold']
        for subfulfillments in data.get('subfulfillments', ()):
            self.add_subfulfillment(Fulfillment.from_dict(subfulfillments))
        for subconditions in data.get('subconditions', ()):
            self.add_subcondition(Condition.from_dict(subfulfillments))
示例#19
0
def test_condition_to_asn1_json(basic_threshold):
    from cryptoconditions.condition import Condition
    from cryptoconditions.type_registry import TypeRegistry

    condition = Condition.from_uri(basic_threshold.condition_uri)
    condition_type = TypeRegistry.find_by_type_id(condition.type_id)

    assert condition.to_asn1_json() == {
        'type': condition_type['asn1_condition'],
        'value': {
            'cost': basic_threshold.cost,
            'fingerprint': condition.hash,
            'subtypes': '01011'
        }
    }
示例#20
0
    def parse_dict(self, data):
        """
        Generate fulfillment payload from a dict

        Args:
            data (dict): description of the fulfillment

        Returns:
            Fulfillment
        """
        self.threshold = data['threshold']
        for subfulfillments in data.get('subfulfillments', ()):
            self.add_subfulfillment(Fulfillment.from_dict(subfulfillments))
        for subconditions in data.get('subconditions', ()):
            self.add_subcondition(Condition.from_dict(subfulfillments))
示例#21
0
 def parse_asn1_dict_payload(self, data):
     self.threshold = len(data['subfulfillments'])
     for subfulfillment in data['subfulfillments']:
         self.subconditions.append({
             'type':
             FULFILLMENT,
             'body':
             Fulfillment.from_asn1_dict(subfulfillment),
         })
     for subcondition in data['subconditions']:
         self.subconditions.append({
             'type':
             CONDITION,
             'body':
             Condition.from_asn1_dict(subcondition),
         })
示例#22
0
    def add_subcondition(self, subcondition):
        """
        Add a subcondition (unfulfilled).

        This can be used to generate a new threshold condition from a set
        of subconditions or to provide a non-fulfilled subcondition when
        creating a threshold fulfillment.

        Args:
            subcondition (:class:`~cryptoconditions.condition.Condition` or :obj:`str`):
                Condition object or URI string representing a new
                subcondition to be added.

        """
        if isinstance(subcondition, str):
            subcondition = Condition.from_uri(subcondition)
        elif not isinstance(subcondition, Condition):
            raise TypeError('Subconditions must be URIs or objects of type Condition')
        self.subconditions.append({'type': CONDITION, 'body': subcondition})
示例#23
0
    def add_subcondition(self, subcondition):
        """
        Add a subcondition (unfulfilled).

        This can be used to generate a new threshold condition from a set
        of subconditions or to provide a non-fulfilled subcondition when
        creating a threshold fulfillment.

        Args:
            subcondition (:class:`~cryptoconditions.condition.Condition` or :obj:`str`):
                Condition object or URI string representing a new
                subcondition to be added.

        """
        if isinstance(subcondition, str):
            subcondition = Condition.from_uri(subcondition)
        elif not isinstance(subcondition, Condition):
            raise TypeError(
                'Subconditions must be URIs or objects of type Condition')
        self.subconditions.append({'type': CONDITION, 'body': subcondition})
    def add_subcondition(self, subcondition, weight=1):
        """
        Add a subcondition (unfulfilled).

        This can be used to generate a new threshold condition from a set of
        subconditions or to provide a non-fulfilled subcondition when creating a threshold fulfillment.

        Args:
            subcondition (Condition, str): Condition to add
            weight (int): Integer weight of the subcondition.
        """
        if isinstance(subcondition, str):
            subcondition = Condition.from_uri(subcondition)
        elif not isinstance(subcondition, Condition):
            raise TypeError('Subconditions must be URIs or objects of type Condition')
        if not isinstance(weight, int):
            raise ValueError('Invalid weight, not an integer: {}'.format(weight))
        self.subconditions.append(
            {
                'type': CONDITION,
                'body': subcondition,
                'weight': weight
            })
    def parse_json(self, json_data):
        """
        Generate fulfillment payload from a json

        Args:
            json_data: json description of the fulfillment

        Returns:
            Fulfillment
        """
        if not isinstance(json_data, dict):
            raise TypeError('reader must be a dict instance')
        self.threshold = json_data['threshold']

        for subfulfillments_json in json_data['subfulfillments']:
            weight = subfulfillments_json['weight']

            if subfulfillments_json['type'] == FULFILLMENT:
                self.add_subfulfillment(Fulfillment.from_json(subfulfillments_json), weight)
            elif subfulfillments_json['type'] == CONDITION:
                self.add_subcondition(Condition.from_json(subfulfillments_json), weight)
            else:
                raise TypeError('Subconditions must provide either subcondition or fulfillment.')
示例#26
0
    def add_subcondition(self, subcondition, weight=1):
        """
        Add a subcondition (unfulfilled).

        This can be used to generate a new threshold condition from a set of
        subconditions or to provide a non-fulfilled subcondition when creating a threshold fulfillment.

        Args:
            subcondition (Condition, str): Condition to add
            weight (int): Integer weight of the subcondition.
        """
        if isinstance(subcondition, str):
            subcondition = Condition.from_uri(subcondition)
        elif not isinstance(subcondition, Condition):
            raise TypeError('Subconditions must be URIs or objects of type Condition')
        if not isinstance(weight, int) or weight < 1:
            raise ValueError('Invalid weight: {}'.format(weight))
        self.subconditions.append(
            {
                'type': CONDITION,
                'body': subcondition,
                'weight': weight
            })
示例#27
0
    def condition(self):
        """
        Generate condition corresponding to this fulfillment.

        An important property of crypto-conditions is that the condition can always
        be derived from the fulfillment. This makes it very easy to post
        fulfillments to a system without having to specify which condition the
        relate to. The system can keep an index of conditions and look up any
        matching events related to that condition.

        Return:
            Condition: Condition corresponding to this fulfillment.
        """
        condition = Condition()
        condition.type_id = self.type_id
        condition.hash = self.generate_hash()
        condition.cost = self.calculate_cost()
        condition.subtypes = self.subtypes
        return condition
示例#28
0
def validate_condition(serialized_condition):
    condition = Condition.from_uri(serialized_condition)
    return condition.validate()
示例#29
0
def test_from_uri_parse_error_invalid_cost(uri):
    from cryptoconditions.condition import Condition
    from cryptoconditions.exceptions import ParsingError
    with raises(ParsingError) as exc_info:
        Condition.from_uri(uri)
    assert exc_info.value.args == ('No or invalid cost provided',)
示例#30
0
def test_condition_validate():
    from cryptoconditions.condition import Condition

    # lets set a known type_id so that the TypeRegistry can return the correct
    # condition type
    condition = Condition()
    condition.type_id = 0

    # subtypes can have at most 32 bits or else raise a value error
    condition.subtypes = range(Condition.MAX_SAFE_SUBTYPES + 1)
    with raises(ValueError):
        condition.validate()

    # raises a ValueError if there is unsuported subtype
    condition.subtypes = set(['magic'])
    with raises(ValueError):
        condition.validate()

    # raises a ValueError if the cost if higher than MAX_COST
    condition.subtypes = set()
    condition.cost = Condition.MAX_COST + 1
    with raises(ValueError):
        condition.validate()
示例#31
0
def validate_condition(serialized_condition):
    condition = Condition.from_uri(serialized_condition)
    return condition.validate()