def propose_remove_role_tasks(
    txn_key, batch_key, proposal_id, role_id, task_id, reason, metadata
):
    propose = role_transaction_pb2.ProposeRemoveRoleTask(
        proposal_id=proposal_id,
        role_id=role_id,
        task_id=task_id,
        reason=reason,
        metadata=metadata,
    )

    inputs = [
        addresser.make_proposal_address(role_id, task_id),
        addresser.make_role_tasks_address(role_id, task_id),
        addresser.make_role_attributes_address(role_id),
        addresser.make_task_attributes_address(task_id),
    ]

    outputs = [addresser.make_proposal_address(role_id, task_id)]

    rbac_payload = rbac_payload_pb2.RBACPayload(
        content=propose.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.PROPOSE_REMOVE_ROLE_TASKS,
    )

    return make_header_and_batch(rbac_payload, inputs, outputs, txn_key, batch_key)
    def test_generated_role_task_addr(self):
        """Tests the role task address creation function as well as the
        address_is function.
        """

        role_id = uuid4().hex
        task_id = uuid4().hex
        address = addresser.make_role_tasks_address(role_id, task_id)

        self.assertEqual(len(address), addresser.ADDRESS_LENGTH,
                         "The address is 70 characters")

        self.assertTrue(addresser.is_address(address),
                        "The address is 70 character hexidecimal")

        self.assertTrue(addresser.namespace_ok(address),
                        "The address has correct namespace prefix")

        self.assertTrue(
            addresser.is_family_address(address),
            "The address is 70 character hexidecimal with family prefix",
        )

        self.assertEqual(
            addresser.address_is(address),
            AddressSpace.ROLES_TASKS,
            "The address created must be a Role Attributes address.",
        )
    def test_determine_role_task_addr(self):
        """Tests that a specific role_id and task_id generates the
        expected role task address, and thus is probably deterministic.
        """

        role_id = "99968acb8f1a48b3a4bc21e2cd252e67"
        task_id = "966ab67317234df489adb4bc1f517b88"
        expected_address = "9f444809326a1713a905b26359fc8d\
a2817c1a5f67de6f464701f0c10042da345d28c5"

        address = addresser.make_role_tasks_address(role_id, task_id)

        self.assertEqual(len(address), addresser.ADDRESS_LENGTH,
                         "The address is 70 characters")

        self.assertTrue(addresser.is_address(address),
                        "The address is 70 character hexidecimal")

        self.assertTrue(addresser.namespace_ok(address),
                        "The address has correct namespace prefix")

        self.assertTrue(
            addresser.is_family_address(address),
            "The address is 70 character hexidecimal with family prefix",
        )

        self.assertEqual(address, expected_address,
                         "The address is the one we expected it to be")

        self.assertEqual(
            addresser.address_is(address),
            AddressSpace.ROLES_TASKS,
            "The address created must be a Role Attributes address.",
        )
def apply_confirm(header, payload, state):
    confirm = role_transaction_pb2.ConfirmAddRoleTask()
    confirm.ParseFromString(payload.content)

    txn_signer_task_owner_address = addresser.make_task_owners_address(
        confirm.task_id, header.signer_public_key
    )

    role_rel_address = addresser.make_role_tasks_address(
        role_id=confirm.role_id, task_id=confirm.task_id
    )

    state_entries = role_validator.validate_role_task(
        header,
        confirm,
        txn_signer_rel_address=txn_signer_task_owner_address,
        state=state,
    )

    state_change.confirm_role_action(
        state_entries=state_entries,
        header=header,
        confirm=confirm,
        role_rel_address=role_rel_address,
        state=state,
        rel_type="task_id",
    )
Example #5
0
def confirm_remove_role_tasks(txn_key, batch_key, proposal_id, role_id,
                              task_id, reason):

    confirm_payload = role_transaction_pb2.ConfirmRemoveRoleTask(
        proposal_id=proposal_id,
        role_id=role_id,
        task_id=task_id,
        reason=reason)

    inputs = [
        addresser.make_proposal_address(role_id, task_id),
        addresser.make_task_owners_address(task_id, txn_key.public_key),
    ]

    outputs = [
        addresser.make_proposal_address(role_id, task_id),
        addresser.make_role_tasks_address(role_id, task_id),
    ]

    rbac_payload = rbac_payload_pb2.RBACPayload(
        content=confirm_payload.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.CONFIRM_REMOVE_ROLE_TASKS,
    )

    return make_header_and_batch(rbac_payload, inputs, outputs, txn_key,
                                 batch_key)
    def test_role_addresses(self):
        """Tests the Role address creation functions as well as the
        address_is function.

        Notes:
            1. Create an address of a particular type:
                - Role Attributes
                - Role Members
                - Role Owners
                - Role Admins
                - Role Tasks
            2. Assert that address_is returns the correct address type.

        """

        role_address = addresser.make_role_attributes_address(role_id=uuid4().hex)

        self.assertEqual(len(role_address), 70, "The address is a well-formed address.")

        self.assertEqual(
            addresser.address_is(role_address),
            AddressSpace.ROLES_ATTRIBUTES,
            "The Role Attributes address created must "
            "be found to be a Role Attributes address.",
        )

        role_members_address = addresser.make_role_members_address(
            role_id=uuid4().hex, user_id=uuid4().hex
        )

        self.assertEqual(
            len(role_members_address), 70, "The address is a well-formed address."
        )

        self.assertEqual(
            addresser.address_is(role_members_address),
            AddressSpace.ROLES_MEMBERS,
            "The Role Members address created must be "
            "found to be a Role Members address.",
        )

        role_owners_address = addresser.make_role_owners_address(
            role_id=uuid4().hex, user_id=uuid4().hex
        )

        self.assertEqual(
            len(role_owners_address), 70, "The address is a well-formed address."
        )

        self.assertEqual(
            addresser.address_is(role_owners_address),
            AddressSpace.ROLES_OWNERS,
            "The Role Owners address created must be found to be "
            "a Role Members address.",
        )

        role_admins_address = addresser.make_role_admins_address(
            role_id=uuid4().hex, user_id=uuid4().hex
        )

        self.assertEqual(
            len(role_admins_address), 70, "The address is a well-formed address."
        )

        self.assertEqual(
            addresser.address_is(role_admins_address),
            AddressSpace.ROLES_ADMINS,
            "The Role Admins address created must be "
            "found to be a Role Admins address.",
        )

        role_tasks_address = addresser.make_role_tasks_address(
            role_id=uuid4().hex, task_id=uuid4().hex
        )

        self.assertEqual(
            len(role_tasks_address), 70, "The address is a well-formed address."
        )

        self.assertEqual(
            addresser.address_is(role_tasks_address),
            AddressSpace.ROLES_TASKS,
            "The Role Tasks address created must be "
            "found to be a Role Tasks address.",
        )
def validate_role_task_proposal(header, propose, state):
    """Applies state validation rules for ADDRoleTaskProposal.
        - The Role exists.
        - The Task exists.
        - The Transaction was signed by a Role Owner.
        - There is no open Proposal for the same change.
        - The task is not already part of the Role.

    Args:
        header (TransactionHeader): The propobuf transaction header.
        propose (ProposeAddRoleTask): The protobuf transaction.
        state (Context): A connection to the validator to ask about state.

    Returns:
        (list of StateEntry)

    """

    role_address = addresser.make_role_attributes_address(propose.role_id)

    task_address = addresser.make_task_attributes_address(propose.task_id)

    proposal_address = addresser.make_proposal_address(propose.role_id,
                                                       propose.task_id)

    txn_signer_role_owner_address = addresser.make_role_owners_address(
        role_id=propose.role_id, user_id=header.signer_public_key)

    role_tasks_address = addresser.make_role_tasks_address(
        propose.role_id, propose.task_id)

    state_entries = state_accessor.get_state(
        state=state,
        addresses=[
            role_address,
            task_address,
            proposal_address,
            role_tasks_address,
            txn_signer_role_owner_address,
        ],
    )

    role_validator.validate_identifier_is_role(state_entries=state_entries,
                                               address=role_address,
                                               identifier=propose.role_id)

    task_validator.validate_identifier_is_task(state_entries=state_entries,
                                               identifier=propose.task_id,
                                               address=task_address)
    try:
        role_task_entry = state_accessor.get_state_entry(
            state_entries, role_tasks_address)
        role_task_container = message_accessor.get_role_rel_container(
            role_task_entry)
        if message_accessor.is_in_role_rel_container(
                role_task_container,
                role_id=propose.role_id,
                identifier=propose.task_id):
            raise InvalidTransaction("Role {} already contains task {}".format(
                propose.role_id, propose.task_id))
    except KeyError:
        # The Task is not in the RoleTask state
        pass

    try:
        role_owner_entry = state_accessor.get_state_entry(
            state_entries, txn_signer_role_owner_address)
        role_owner_container = message_accessor.get_role_rel_container(
            role_owner_entry)

        if not message_accessor.is_in_role_rel_container(
                role_owner_container,
                role_id=propose.role_id,
                identifier=header.signer_public_key,
        ):
            raise InvalidTransaction(
                "Txn signer {} is not a role owner".format(
                    header.signer_public_key))
    except KeyError:
        raise InvalidTransaction("Txn signer {} is not a role owner.".format(
            header.signer_public_key))

    if not has_no_open_proposal(
            state_entries=state_entries,
            object_id=propose.role_id,
            related_id=propose.task_id,
            proposal_address=proposal_address,
            proposal_type=proposal_state_pb2.Proposal.ADD_ROLE_TASKS,
    ):
        raise InvalidTransaction(
            "There is already an open proposal to add task {} to "
            "role {}".format(propose.task_id, propose.role_id))
    return state_entries