Beispiel #1
0
def validate_role_task(header, confirm, txn_signer_rel_address, state):

    proposal_address = addresser.make_proposal_address(
        object_id=confirm.role_id, related_id=confirm.task_id)

    state_entries = get_state(state,
                              [txn_signer_rel_address, proposal_address])

    if not proposal_exists_and_open(state_entries, proposal_address,
                                    confirm.proposal_id):
        raise InvalidTransaction("The proposal {} does not exist or "
                                 "is not open".format(confirm.proposal_id))
    try:
        entry = get_state_entry(state_entries, txn_signer_rel_address)
        task_owners_container = return_task_rel_container(entry)
    except KeyError:
        raise InvalidTransaction(
            "Signer {} is not a task owner for task {}".format(
                header.signer_public_key, confirm.task_id))

    if not is_in_task_rel_container(task_owners_container, confirm.task_id,
                                    header.signer_public_key):
        raise InvalidTransaction(
            "Signer {} is not a task owner for task {} no bytes in "
            "state".format(header.signer_public_key, confirm.task_id))
    return state_entries
def validate_task_rel_proposal(header, propose, rel_address, state):
    """Validates that the User exists, the Task exists, and the User is not
    in the Task's relationship specified by rel_address.

    Args:
        header (TransactionHeader): The transaction header.
        propose (ProposeAddTask_____): The Task relationship proposal.
        rel_address (str): The Task relationship address produced by the Task
            and the User.
        state (sawtooth_sdk.Context): The way to communicate to the validator
            the state gets and sets.

    Returns:
        (dict of addresses)
    """

    user_address = addresser.make_user_address(propose.user_id)
    task_address = addresser.make_task_attributes_address(propose.task_id)
    proposal_address = addresser.make_proposal_address(
        object_id=propose.task_id,
        related_id=propose.user_id)

    state_entries = get_state(state, [user_address,
                                      task_address,
                                      proposal_address,
                                      rel_address])
    validate_identifier_is_user(state_entries,
                                identifier=propose.user_id,
                                address=user_address)
    user_entry = get_state_entry(state_entries, user_address)
    user = get_user_from_container(
        return_user_container(user_entry),
        propose.user_id)

    if header.signer_public_key not in [user.user_id, user.manager_id]:
        raise InvalidTransaction(
            "Txn signer {} is not the user or the user's "
            "manager {}".format(header.signer_public_key,
                                [user.user_id, user.manager_id]))

    validate_identifier_is_task(state_entries,
                                identifier=propose.task_id,
                                address=task_address)

    try:
        task_admins_entry = get_state_entry(state_entries, rel_address)
        task_rel_container = return_task_rel_container(task_admins_entry)
        if is_in_task_rel_container(
                task_rel_container,
                propose.task_id,
                propose.user_id):
            raise InvalidTransaction(
                "User {} is already in the Role {} "
                "relationship".format(propose.user_id,
                                      propose.task_id))
    except KeyError:
        # The task rel container doesn't exist so no task relationship exists
        pass

    return state_entries
def validate_task_rel_del_proposal(header, propose, rel_address, state):
    """Validates that the User exists, the Task exists, and the User is in
    the Tasks's relationship specified by the rel_address.

    Args:
        header (TransactionHeader): The transaction header.
        propose (ProposeRemoveTask____): The Task Remove relationship proposal
        rel_address (str): The task relationship address.
        state (Context:: The way to communicate to the validator State gets
            and sets.

    Returns:
        (list of StateEntry)
    """

    user_address = addresser.make_user_address(propose.user_id)
    task_address = addresser.make_task_attributes_address(propose.task_id)

    proposal_address = addresser.make_proposal_address(
        object_id=propose.task_id, related_id=propose.user_id)

    state_entries = get_state(
        state, [user_address, task_address, proposal_address, rel_address])

    validate_identifier_is_user(state_entries,
                                identifier=propose.user_id,
                                address=user_address)

    user_entry = get_state_entry(state_entries, user_address)

    user = get_user_from_container(return_user_container(user_entry),
                                   propose.user_id)

    if header.signer_pubkey not in [user.user_id, user.manager_id]:
        raise InvalidTransaction(
            "Txn signer {} is not the user {} or the user's manager {}".format(
                header.signer_pubkey, user.user_id, user.manager_id))

    validate_identifier_is_task(state_entries,
                                identifier=propose.task_id,
                                address=task_address)

    try:
        task_rel_entry = get_state_entry(state_entries, rel_address)
        task_rel_container = return_task_rel_container(task_rel_entry)
        if not is_in_task_rel_container(task_rel_container, propose.task_id,
                                        propose.user_id):
            raise InvalidTransaction("User {} isn't in the Task {} "
                                     "relationship".format(
                                         propose.user_id, propose.task_id))
    except KeyError:
        raise InvalidTransaction(
            "User {} isn't in the Task {} relationship, "
            "since there isn't a container at the address".format(
                propose.user_id, propose.task_id))

    return state_entries
def handle_confirm(state_entries, header, confirm, task_rel_address, state,
                   is_remove):
    """ Updates proposal and task relationship objects according to the
        task admin/owner transaction.

        Args:
            state_entries: List of states for the proposal, task relationship,
            and task admins object.
            header (TransactionHeader): The protobuf TransactionHeader.
            confirm (RBACPayload): The protobuf RBACPayload.
            task_rel_address (str): The task relationship address.
            state (Context): The class that handles state gets and sets.
            is_remove (boolean): Determines if task admin/owner is being removed or added.

    """
    proposal_address = addresser.make_proposal_address(
        object_id=confirm.task_id, related_id=confirm.user_id)

    proposal_entry = get_state_entry(state_entries, proposal_address)
    proposal_container = return_prop_container(proposal_entry)
    proposal = get_prop_from_container(proposal_container,
                                       proposal_id=confirm.proposal_id)

    proposal.status = proposal_state_pb2.Proposal.CONFIRMED
    proposal.closer = header.signer_public_key
    proposal.close_reason = confirm.reason

    address_values = {proposal_address: proposal_container.SerializeToString()}

    try:
        task_rel_entry = get_state_entry(state_entries, task_rel_address)
        task_rel_container = return_task_rel_container(task_rel_entry)
    except KeyError:
        task_rel_container = task_state_pb2.TaskRelationshipContainer()

    try:
        task_rel = get_task_rel_from_container(container=task_rel_container,
                                               task_id=confirm.task_id,
                                               identifier=confirm.user_id)
    except KeyError:
        task_rel = task_rel_container.relationships.add()
        task_rel.task_id = confirm.task_id

    if not is_remove:
        task_rel.identifiers.append(confirm.user_id)
    else:
        task_rel.identifiers.remove(confirm.user_id)

    address_values[task_rel_address] = task_rel_container.SerializeToString()

    set_state(state, address_values)
def validate_task_admin_or_owner(header, confirm, txn_signer_rel_address,
                                 task_rel_address, state, is_remove):
    """Validate a [ Confirm | Reject }_____Task[ Admin | Owner } transaction.

    Args:
        header (TransactionHeader): The transaction header protobuf class.:
        confirm: ConfirmAddTaskAdmin, RejectAddTaskAdmin, ...
        txn_signer_rel_address (str): The transaction signer address.
        task_rel_address (str): The task relationship address.
        state (Context): The class responsible for gets and sets of state.
        is_remove (boolean): Determines if task owner is being added or removed.

    Returns:
        (dict of addresses)

    Raises:
        InvalidTransaction
            - The transaction is invalid.
    """

    proposal_address = addresser.make_proposal_address(
        object_id=confirm.task_id, related_id=confirm.user_id)

    if not is_remove:
        state_entries = get_state(state,
                                  [txn_signer_rel_address, proposal_address])
    else:
        state_entries = get_state(
            state,
            [txn_signer_rel_address, task_rel_address, proposal_address])

    if not proposal_exists_and_open(state_entries, proposal_address,
                                    confirm.proposal_id):
        raise InvalidTransaction("The proposal {} does not exist or "
                                 "is not open".format(confirm.proposal_id))
    try:
        entry = get_state_entry(state_entries, txn_signer_rel_address)
        task_rel_container = return_task_rel_container(entry)
    except KeyError:
        raise InvalidTransaction(
            "Signer {} does not have the Task permissions "
            "to close the proposal".format(header.signer_public_key))
    if not is_in_task_rel_container(task_rel_container,
                                    task_id=confirm.task_id,
                                    identifier=header.signer_public_key):
        raise InvalidTransaction("Signer {} does not have the Task "
                                 "permissions to close the "
                                 "proposal".format(header.signer_public_key))

    return state_entries
def handle_confirm_add(state_entries,
                       header,
                       confirm,
                       task_rel_address,
                       state):
    proposal_address = addresser.make_proposal_address(
        object_id=confirm.task_id,
        related_id=confirm.user_id)

    proposal_entry = get_state_entry(state_entries, proposal_address)
    proposal_container = return_prop_container(proposal_entry)
    proposal = get_prop_from_container(
        proposal_container,
        proposal_id=confirm.proposal_id)

    proposal.status = proposal_state_pb2.Proposal.CONFIRMED
    proposal.closer = header.signer_public_key
    proposal.close_reason = confirm.reason

    address_values = {
        proposal_address: proposal_container.SerializeToString()
    }

    try:
        task_rel_entry = get_state_entry(state_entries, task_rel_address)
        task_rel_container = return_task_rel_container(task_rel_entry)
    except KeyError:
        task_rel_container = task_state_pb2.TaskRelationshipContainer()

    try:
        task_rel = get_task_rel_from_container(
            container=task_rel_container,
            task_id=confirm.task_id,
            identifier=confirm.user_id)
    except KeyError:
        task_rel = task_rel_container.relationships.add()
        task_rel.task_id = confirm.task_id

    task_rel.identifiers.append(confirm.user_id)

    address_values[task_rel_address] = task_rel_container.SerializeToString()

    set_state(state, address_values)
def validate_task_admin_or_owner(header, confirm, txn_signer_rel_address,
                                 state):
    """Validate a [ Confirm | Reject }_____Task[ Admin | Owner } transaction.

    Args:
        header (TransactionHeader): The transaction header protobuf class.:
        confirm: ConfirmAddTaskAdmin, RejectAddTaskAdmin, ...
        state (Context): The class responsible for gets and sets of state.

    Returns:
        (list of StateEntry)
    """

    proposal_address = addresser.make_proposal_address(
        object_id=confirm.task_id, related_id=confirm.user_id)

    state_entries = get_state(state,
                              [txn_signer_rel_address, proposal_address])

    if not proposal_exists_and_open(state_entries, proposal_address,
                                    confirm.proposal_id):
        raise InvalidTransaction("The proposal {} does not exist or "
                                 "is not open".format(confirm.proposal_id))
    try:
        entry = get_state_entry(state_entries, txn_signer_rel_address)
        task_rel_container = return_task_rel_container(entry)
    except KeyError:
        raise InvalidTransaction(
            "Signer {} does not have the Task permissions "
            "to close the proposal".format(header.signer_pubkey))
    if not is_in_task_rel_container(task_rel_container,
                                    task_id=confirm.task_id,
                                    identifier=header.signer_pubkey):
        raise InvalidTransaction("Signer {} does not have the Task "
                                 "permissions to close the "
                                 "proposal".format(header.signer_pubkey))

    return state_entries