Esempio n. 1
0
def _lock_asset(payload, signer, timestamp, state):
    """ Prevents an asset from being touched by locking it.

    To lock an asset, an rfid must be provided by the agent who last
    held it.  Locking sets the locked field in history to true, and 
    prevents further touchpoints being added to state without unlocking.
    """

    _verify_agent(state, signer)
    rfid = payload.rfid

    if not rfid:
        raise InvalidTransaction(
            'RFID needed to lock asset.')

    # Get the asset history.

    history_address = addressing.make_history_address(rfid)
    history_container = _get_container(state, history_address)

    try:
        history = next(
            entry
            for entry in history_container.entries
            if entry.rfid == rfid
        )
    except StopIteration:
        raise InvalidTransaction(
            'History could not be found. Asset likely doesn\'t exist.')

    touchpoint_index = history.curr_touchpoint_index
    touchpoint_address = addressing.make_touchpoint_address(rfid, touchpoint_index)
    touchpoint_container = _get_container(state, touchpoint_address)

    try:
        touchpoint = touchpoint_container.entries[0]
    except:
        raise InvalidTransaction('Unable to get needed touchpoint.')

    last_reporter = history.reporter_list[touchpoint.reporter_index]

    if not last_reporter.public_key == signer:
        raise InvalidTransaction('Not authorized to lock this asset.')

    history.locked = True

    _set_container(state, history_address, history_container)
Esempio n. 2
0
def _unlock_asset(payload, signer, timestamp, state):
    """ Unlocks an asset to allow new touchpoints being created

    An agent needs the authorization to unlock an asset.  The credentials 
    lie with the last reported holder of the object. 
    """
   
    _verify_agent(state, signer)
    rfid = payload.rfid

    if not rfid:
        raise InvalidTransaction(
            'RFID needed to lock asset.')

    # Get the asset history.

    history_address = addressing.make_history_address(rfid)
    history_container = _get_container(state, history_address)

    try:
        history = next(
            entry
            for entry in history_container.entries
            if entry.rfid == rfid
        )
    except StopIteration:
        raise InvalidTransaction(
            'History could not be found. Asset likely doesn\'t exist.')

    touchpoint_index = history.curr_touchpoint_index
    touchpoint_address = addressing.make_touchpoint_address(rfid, touchpoint_index)
    touchpoint_container = _get_container(state, touchpoint_address)

    try:
        touchpoint = touchpoint_container.entries[0]
    except:
        raise InvalidTransaction('Unable to get needed touchpoint.')

    last_reporter = history.reporter_list[touchpoint.reporter_index]

    if not last_reporter.public_key == signer:
        raise InvalidTransaction('Not authorized to unlock this asset.')

    history.locked = False

    _set_container(state, history_address, history_container)
Esempio n. 3
0
def _touch_asset(payload, signer, timestamp, state):
    """ Adds a touchpoint to the list of existing touchpoints for a given asset.

    The position in the tree is determined by the addressing method used.  LaceTP identifies an 
    asset with a 6 character hash of the transaction family, followed by a single character to 
    indicate an agent(2), asset(1) or history(0).  All touchpoints have this single character set
    to asset(1).  The final betweent this character and the final four is a random hash of 59 
    characters.  The final four characters indicate the touchpoint index.  The index can never be
    zero as that is reserved for the history.  The touchpoint can wrap around zero.
    """

    _verify_agent(state, signer)

    rfid = payload.rfid

    if not rfid:
        raise InvalidTransaction(
            'Asset must have rfid.')

    # Get the asset history.

    history_address = addressing.make_history_address(rfid)
    history_container = _get_container(state, history_address)

    try:
        history = next(
            entry
            for entry in history_container.entries
            if entry.rfid == rfid
        )
    except StopIteration:
        raise InvalidTransaction(
            'History could not be found. Asset likely doesn\'t exist.')

    # Check for a lock
    if history.locked:
        raise InvalidTransaction(
            'Asset is locked. You must unlock it or request that it be unlocked.')

    # Find the correct reporter index or loop out.
    reporter_count = INITIAL_REPORTER_INDEX
    reporter_index = -1     # reporter does not exist
    for reporter in history.reporter_list:
        if reporter.public_key == signer:
            reporter_index = reporter_count
        reporter_count += 1

    touchpoint = TouchPoint (
            longitude = payload.longitude,
            latitude  = payload.latitude,
            reporter_index = INITIAL_REPORTER_INDEX,
            timestamp = timestamp,
    )
   
    # Check if we need to create a new reporter list entry.
    if reporter_index == -1:    # then it wasn't found
        reporter = Reporter(
            public_key = signer,
            authorization_level = DEFAULT_AUTH_LEVEL,
        )

        history.reporter_list.extend([reporter])
        touchpoint.reporter_index = len(history.reporter_list) - 1
    else:
        touchpoint.reporter_index = reporter_index

    # Calculate index, considering that it may wrap around.
    if history.curr_touchpoint_index == MAX_TOUCH_POINT:
        history.has_wrapped = True
        history.curr_touchpoint_index = INITIAL_TOUCHPOINT_INDEX
    else:
        history.curr_touchpoint_index += 1

    address = addressing.make_touchpoint_address(rfid, history.curr_touchpoint_index)
  
    container = _get_container(state, address)

    if len(container.entries) > 0:
        del container.entries[:]
        container.entries.extend([touchpoint])
    else:
        container.entries.extend([touchpoint])

    _set_container(state, address, container)
    _set_container(state, history_address, history_container)
Esempio n. 4
0
def _create_asset(payload, signer, timestamp, state):
    """Creates a history and initial touchpoint for an asset. 

    The position in the tree is determined by the addressing method used.  LaceTP identifies an 
    asset with a 6 character hash of the transaction family, followed by a single character to 
    indicate an agent(2), asset(1) or history(0).  All touchpoints have this single character set
    to asset(1).  Between this character and the last four (59 chars) is a random hash of an rfid.  
    The final four characters indicate the touchpoint index.  The index can never be zero as that 
    is reserved for the history.  The touchpoint can wrap around zero.
    """

    _verify_agent(state, signer)

    rfid = payload.rfid


    asset_address = addressing.make_asset_address(rfid)
    asset_container = _get_container(state, asset_address)

    if any(asset.rfid == rfid for asset in asset_container.entries):
        raise InvalidTransaction(
                'Asset already exists')

    # Create the asset and extend the asset container.
    
    asset = Asset(
        rfid    = payload.rfid,
        size    = payload.size,
        sku     = payload.sku, 
    )

    asset_container.entries.extend([asset])

    # Create the history for the asset.

    history_address = addressing.make_history_address(rfid)
    history_container = _get_container(state, history_address)

    if any(history.rfid == rfid for history in history_container.entries):
        raise InvalidTransaction(
                'History already exists for asset that didn\'t...')

    history = History(
        rfid = rfid,
        curr_touchpoint_index = INITIAL_TOUCHPOINT_INDEX,
        has_wrapped = False,
    )
    
    history.reporter_list.extend([
        Reporter(
            public_key          = signer,
            authorization_level = DEFAULT_AUTH_LEVEL, # Default for now.
        )
    ])
    
    # Extend the history container
    history_container.entries.extend([history])

    # Create the initial touchpoint

    touchpoint_address = addressing.make_touchpoint_address(rfid, INITIAL_TOUCHPOINT_INDEX)
    touchpoint_container = _get_container(state, touchpoint_address)

    touchpoint = TouchPoint(
        longitude = payload.longitude,
        latitude = payload.latitude,
        timestamp = timestamp,
        reporter_index = INITIAL_REPORTER_INDEX,
    )

    # Extend touchpoint container.
    touchpoint_container.entries.extend([touchpoint])

    # Set the state for the asset and its history.
    _set_container(state, asset_address, asset_container)
    _set_container(state, history_address, history_container)
    _set_container(state, touchpoint_address, touchpoint_container)