def propose_add_role_tasks(txn_key, batch_key, proposal_id, role_id, task_id,
                           reason, metadata):
    propose_payload = role_transaction_pb2.ProposeAddRoleTask(
        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_owners_address(role_id, txn_key.public_key),
        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_payload.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.PROPOSE_ADD_ROLE_TASKS)

    return make_header_and_batch(rbac_payload, inputs, outputs, txn_key,
                                 batch_key)
def confirm_add_role_members(txn_key, batch_key, proposal_id, role_id, user_id,
                             reason):

    confirm_payload = role_transaction_pb2.ConfirmAddRoleMember(
        proposal_id=proposal_id,
        role_id=role_id,
        user_id=user_id,
        reason=reason)

    inputs = [
        addresser.make_proposal_address(role_id, user_id),
        addresser.make_role_owners_address(role_id, txn_key.public_key)
    ]

    outputs = [
        addresser.make_proposal_address(role_id, user_id),
        addresser.make_role_members_address(role_id, user_id)
    ]

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

    return make_header_and_batch(rbac_payload, inputs, outputs, txn_key,
                                 batch_key)
예제 #3
0
def reject_remove_task_owners(txn_key,
                              batch_key,
                              proposal_id,
                              task_id,
                              user_id,
                              reason):
    reject = task_transaction_pb2.RejectRemoveTaskOwner(
        proposal_id=proposal_id,
        task_id=task_id,
        user_id=user_id,
        reason=reason)

    inputs = [addresser.make_proposal_address(task_id, user_id),
              addresser.make_task_admins_address(task_id, txn_key.public_key)]

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

    rbac_payload = rbac_payload_pb2.RBACPayload(
        content=reject.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.REJECT_REMOVE_TASK_OWNERS)

    return make_header_and_batch(
        rbac_payload,
        inputs,
        outputs,
        txn_key,
        batch_key)
예제 #4
0
def propose_add_task_admins(txn_key,
                            batch_key,
                            proposal_id,
                            task_id,
                            user_id,
                            reason,
                            metadata):
    propose_payload = task_transaction_pb2.ProposeAddTaskAdmin(
        proposal_id=proposal_id,
        task_id=task_id,
        user_id=user_id,
        reason=reason,
        metadata=metadata)

    inputs = [addresser.make_user_address(user_id),
              addresser.make_task_admins_address(
                  task_id=task_id,
                  user_id=user_id),
              addresser.make_proposal_address(task_id, user_id),
              addresser.make_task_attributes_address(task_id)]

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

    rbac_payload = rbac_payload_pb2.RBACPayload(
        content=propose_payload.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.PROPOSE_ADD_TASK_ADMINS)

    return make_header_and_batch(
        rbac_payload,
        inputs,
        outputs,
        txn_key,
        batch_key)
예제 #5
0
def propose_remove_task_owners(txn_key,
                               batch_key,
                               proposal_id,
                               task_id,
                               user_id,
                               reason,
                               metadata):
    propose = task_transaction_pb2.ProposeRemoveTaskOwner(
        proposal_id=proposal_id,
        task_id=task_id,
        user_id=user_id,
        reason=reason,
        metadata=metadata)

    inputs = [addresser.make_user_address(user_id),
              addresser.make_task_owners_address(
                  task_id=task_id,
                  user_id=user_id),
              addresser.make_proposal_address(task_id, user_id),
              addresser.make_task_attributes_address(task_id)]

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

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

    return make_header_and_batch(
        rbac_payload,
        inputs,
        outputs,
        txn_key,
        batch_key)
예제 #6
0
def confirm_add_task_owners(txn_key,
                            batch_key,
                            proposal_id,
                            task_id,
                            user_id,
                            reason):
    confirm = task_transaction_pb2.ConfirmAddTaskOwner(
        proposal_id=proposal_id,
        task_id=task_id,
        user_id=user_id,
        reason=reason)

    inputs = [addresser.make_proposal_address(task_id, user_id),
              addresser.make_task_admins_address(task_id, txn_key.public_key)]

    outputs = [addresser.make_proposal_address(task_id, user_id),
               addresser.make_task_owners_address(task_id, user_id)]

    rbac_payload = rbac_payload_pb2.RBACPayload(
        content=confirm.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.CONFIRM_ADD_TASK_OWNERS)

    return make_header_and_batch(
        rbac_payload,
        inputs,
        outputs,
        txn_key,
        batch_key)
예제 #7
0
def reject_add_task_admins(txn_key,
                           batch_key,
                           proposal_id,
                           task_id,
                           user_id,
                           reason):
    reject_payload = task_transaction_pb2.RejectAddTaskAdmin(
        proposal_id=proposal_id,
        task_id=task_id,
        user_id=user_id,
        reason=reason)

    inputs = [addresser.make_task_admins_address(task_id, txn_key.public_key),
              addresser.make_proposal_address(task_id, user_id)]

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

    rbac_payload = rbac_payload_pb2.RBACPayload(
        content=reject_payload.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.REJECT_ADD_TASK_ADMINS)

    return make_header_and_batch(
        rbac_payload,
        inputs,
        outputs,
        txn_key,
        batch_key)
def confirm_remove_role_admins(txn_key, batch_key, proposal_id, role_id,
                               user_id, reason):

    confirm_add_payload = role_transaction_pb2.ConfirmRemoveRoleAdmin(
        proposal_id=proposal_id,
        role_id=role_id,
        user_id=user_id,
        reason=reason)

    inputs = [
        addresser.make_role_admins_address(role_id=role_id,
                                           user_id=txn_key.public_key)
    ]
    inputs.append(addresser.make_proposal_address(role_id, user_id))

    outputs = [
        addresser.make_proposal_address(role_id, user_id),
        addresser.make_role_admins_address(role_id, user_id)
    ]

    rbac_payload = rbac_payload_pb2.RBACPayload(
        content=confirm_add_payload.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.CONFIRM_REMOVE_ROLE_ADMINS)

    return make_header_and_batch(rbac_payload, inputs, outputs, txn_key,
                                 batch_key)
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)
예제 #10
0
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
예제 #11
0
def apply_propose(header, payload, state):
    role_admins_payload = role_transaction_pb2.ProposeAddRoleAdmin()
    role_admins_payload.ParseFromString(payload.content)

    role_admins_address = addresser.make_role_admins_address(
        role_id=role_admins_payload.role_id,
        user_id=role_admins_payload.user_id)

    proposal_address = addresser.make_proposal_address(
        object_id=role_admins_payload.role_id,
        related_id=role_admins_payload.user_id)

    state_entries = validate_role_rel_proposal(header, role_admins_payload,
                                               role_admins_address, state)

    if not no_open_proposal(
            state_entries=state_entries,
            object_id=role_admins_payload.role_id,
            related_id=role_admins_payload.user_id,
            proposal_address=proposal_address,
            proposal_type=proposal_state_pb2.Proposal.ADD_ROLE_ADMINS):
        raise InvalidTransaction(
            "There is already an open proposal for ADD_ROLE_ADMINS "
            "with role id {} and user id {}".format(
                role_admins_payload.role_id, role_admins_payload.user_id))

    handle_propose_state_set(
        state_entries=state_entries,
        header=header,
        payload=role_admins_payload,
        address=proposal_address,
        proposal_type=proposal_state_pb2.Proposal.ADD_ROLE_ADMINS,
        state=state)
예제 #12
0
    def test_gen_proposal_addr(self):
        """Tests the proposal address creation function as well as the
        address_is function.
        """

        object_id = uuid4().hex
        related_id = uuid4().hex
        address = addresser.make_proposal_address(object_id, related_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.PROPOSALS,
            "The address created must be a Proposal address.")
def apply_propose_remove(header, payload, state):
    proposal_payload = role_transaction_pb2.ProposeRemoveRoleMember()
    proposal_payload.ParseFromString(payload.content)

    role_members_address = addresser.make_role_members_address(
        role_id=proposal_payload.role_id, user_id=proposal_payload.user_id)

    proposal_address = addresser.make_proposal_address(
        object_id=proposal_payload.role_id,
        related_id=proposal_payload.user_id)

    state_entries = validate_role_rel_proposal(header, proposal_payload,
                                               role_members_address, state,
                                               True)

    if not no_open_proposal(
            state_entries=state_entries,
            object_id=proposal_payload.role_id,
            related_id=proposal_payload.user_id,
            proposal_address=proposal_address,
            proposal_type=proposal_state_pb2.Proposal.REMOVE_ROLE_MEMBERS):
        raise InvalidTransaction(
            "There is already an open proposal for REMOVE_ROLE_MEMBERS "
            "with role id {} and user id {}".format(proposal_payload.role_id,
                                                    proposal_payload.user_id))

    handle_propose_state_set(
        state_entries=state_entries,
        header=header,
        payload=proposal_payload,
        address=proposal_address,
        proposal_type=proposal_state_pb2.Proposal.REMOVE_ROLE_MEMBERS,
        state=state)
예제 #14
0
def handle_state_set(proposal_state_entries, header, user_proposal, state):
    proposal_address = addresser.make_proposal_address(
        user_proposal.user_id, user_proposal.new_manager_id)
    try:

        state_entry = get_state_entry(proposal_state_entries, proposal_address)
        proposal_container = return_prop_container(state_entry)

    except KeyError:
        proposal_container = proposal_state_pb2.ProposalsContainer()

    proposal = proposal_container.proposals.add()
    proposal.proposal_id = user_proposal.proposal_id
    proposal.proposal_type = proposal_state_pb2.Proposal.UPDATE_USER_MANAGER
    proposal.object_id = user_proposal.user_id
    proposal.target_id = user_proposal.new_manager_id
    proposal.opener = header.signer_pubkey
    proposal.status = proposal_state_pb2.Proposal.OPEN
    proposal.open_reason = user_proposal.reason
    proposal.metadata = user_proposal.metadata

    set_state(state, [
        StateEntry(address=proposal_address,
                   data=proposal_container.SerializeToString())
    ])
예제 #15
0
def apply_user_reject(header, payload, state):
    reject_payload = user_transaction_pb2.RejectUpdateUserManager()
    reject_payload.ParseFromString(payload.content)

    proposal_address = addresser.make_proposal_address(
        object_id=reject_payload.user_id, related_id=reject_payload.manager_id)

    state_entries = get_state(state, [proposal_address])

    if not proposal_exists_and_open(state_entries=state_entries,
                                    proposal_address=proposal_address,
                                    proposal_id=reject_payload.proposal_id):
        raise InvalidTransaction("Proposal {} is not open or does not "
                                 "exist".format(reject_payload.proposal_id))

    entry = get_state_entry(state_entries, proposal_address)

    proposal_container = return_prop_container(entry)

    if not reject_payload.manager_id == header.signer_pubkey:
        raise InvalidTransaction("Proposal expected closer to be {} while txn "
                                 "signer was {}".format(
                                     reject_payload.manager_id,
                                     header.signer_pubkey))

    proposal = get_prop_from_container(proposal_container,
                                       reject_payload.proposal_id)

    handle_reject_state_set(container=proposal_container,
                            proposal=proposal,
                            closer=header.signer_pubkey,
                            reason=reject_payload.reason,
                            address=proposal_address,
                            state=state)
예제 #16
0
def apply_propose_remove(header, payload, state):
    propose = task_transaction_pb2.ProposeRemoveTaskOwner()
    propose.ParseFromString(payload.content)

    task_owners_address = addresser.make_task_owners_address(
        task_id=propose.task_id, user_id=propose.user_id)

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

    state_entries = validate_task_rel_del_proposal(
        header=header,
        propose=propose,
        rel_address=task_owners_address,
        state=state)

    if not no_open_proposal(
            state_entries=state_entries,
            object_id=propose.task_id,
            related_id=propose.user_id,
            proposal_address=proposal_address,
            proposal_type=proposal_state_pb2.Proposal.REMOVE_TASK_OWNERS):
        raise InvalidTransaction(
            "There is already an open proposal for REMOVE_TASK_OWNERS "
            "with task id {} and user id {}".format(propose.task_id,
                                                    propose.user_id))

    handle_propose_state_set(
        state_entries=state_entries,
        header=header,
        payload=propose,
        address=proposal_address,
        proposal_type=proposal_state_pb2.Proposal.REMOVE_TASK_OWNERS,
        state=state)
예제 #17
0
    def test_determine_proposal_addr(self):
        """Tests that a specific proposal_id generates the expected
        proposal address, and thus is probably deterministic.
        """

        object_id = 'cb048d507eec42a5845e20eed982d5d2'
        related_id = 'f1e916b663164211a9ac34516324681a'
        expected_address = '9f4448e3b874e90b2bcf58e65e0727\
91ea499543ee52fc9d0449fc1e41f77d4d4f926e'
        address = addresser.make_proposal_address(object_id, related_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.PROPOSALS,
            "The address created must be a Proposal address.")
예제 #18
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_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
예제 #20
0
def propose_manager(txn_key, batch_key, proposal_id, user_id, new_manager_id,
                    reason, metadata):
    """Create a BatchList with a ProposeUpdateUserManager transaction
    in it.

    Args:
        txn_key (Key): The transaction signer public/private key pair
        batch_key (Key): The batch signer public/private key pair
        proposal_id (str): The id of the proposal supplied by the rest api.
        user_id (str): The User id of the user whose manager will be updated.
        new_manager_id (str): The new manager's id.
        reason (str): The reason for this update.
        metadata (str): Client supplied metadata.

    Returns:
        tuple
            BatchList, batch header_signature tuple
    """

    propose_update_payload = user_transaction_pb2.ProposeUpdateUserManager(
        proposal_id=proposal_id,
        user_id=user_id,
        new_manager_id=new_manager_id,
        reason=reason,
        metadata=metadata)

    inputs = [
        addresser.make_user_address(user_id=user_id),
        addresser.make_user_address(user_id=new_manager_id),
        addresser.make_proposal_address(object_id=user_id,
                                        related_id=new_manager_id)
    ]

    outputs = [
        addresser.make_proposal_address(object_id=user_id,
                                        related_id=new_manager_id)
    ]

    rbac_payload = rbac_payload_pb2.RBACPayload(
        content=propose_update_payload.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.PROPOSE_UPDATE_USER_MANAGER)

    return make_header_and_batch(rbac_payload, inputs, outputs, txn_key,
                                 batch_key)
예제 #21
0
def reject_manager(txn_key, batch_key, proposal_id, reason, user_id,
                   manager_id):
    """Create a BatchList with a RejectUpdateUserManager in it.

    Args:
        txn_key (Key): The public/private key pair for signing the txn.
        batch_key (Key): The public/private key pair for signing the batch.
        proposal_id (str): The identifier of the proposal.
        reason (str): The client supplied reason for rejecting the proposal.
        user_id (str): The user's public key.
        manager_id (str): The manager's public key.

    Returns:
        tuple
            BatchList, signature tuple
    """

    reject_update_payload = user_transaction_pb2.RejectUpdateUserManager(
        proposal_id=proposal_id,
        user_id=user_id,
        manager_id=manager_id,
        reason=reason)

    inputs = [
        addresser.make_proposal_address(object_id=user_id,
                                        related_id=manager_id)
    ]

    outputs = [
        addresser.make_proposal_address(object_id=user_id,
                                        related_id=manager_id)
    ]

    rbac_payload = rbac_payload_pb2.RBACPayload(
        content=reject_update_payload.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.REJECT_UPDATE_USER_MANAGER)

    return make_header_and_batch(rbac_payload=rbac_payload,
                                 inputs=inputs,
                                 outputs=outputs,
                                 txn_key=txn_key,
                                 batch_key=batch_key)
def reject_remove_role_members(txn_key, batch_key, proposal_id, role_id,
                               user_id, reason):
    reject_payload = role_transaction_pb2.RejectRemoveRoleMember(
        proposal_id=proposal_id,
        role_id=role_id,
        user_id=user_id,
        reason=reason)

    inputs = [
        addresser.make_proposal_address(role_id, user_id),
        addresser.make_role_owners_address(role_id, txn_key.public_key)
    ]

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

    rbac_payload = rbac_payload_pb2.RBACPayload(
        content=reject_payload.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.REJECT_REMOVE_ROLE_MEMBERS)

    return make_header_and_batch(rbac_payload, inputs, outputs, txn_key,
                                 batch_key)
def confirm_add_role_admins(txn_key, batch_key, proposal_id, role_id, user_id,
                            reason):
    """Creates a BatchList with a ConfirmAddRoleAdmin transaction in it.

    Args:
        txn_key (Key): The txn signer key pair.
        batch_key (Key): The batch signer key pair.
        proposal_id (str): The proposal's identifier.
        role_id (str): The role's identifier.
        user_id (str): The user's signer public key.
        reason (str): The client supplied reason to confirm.

    Returns:
        tuple
            BatchList, batch header_signature tuple
    """

    confirm_add_payload = role_transaction_pb2.ConfirmAddRoleAdmin(
        proposal_id=proposal_id,
        role_id=role_id,
        user_id=user_id,
        reason=reason)

    inputs = [
        addresser.make_role_admins_address(role_id=role_id,
                                           user_id=txn_key.public_key)
    ]
    inputs.append(addresser.make_proposal_address(role_id, user_id))

    outputs = [
        addresser.make_proposal_address(role_id, user_id),
        addresser.make_role_admins_address(role_id, user_id)
    ]

    rbac_payload = rbac_payload_pb2.RBACPayload(
        content=confirm_add_payload.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.CONFIRM_ADD_ROLE_ADMINS)

    return make_header_and_batch(rbac_payload, inputs, outputs, txn_key,
                                 batch_key)
def propose_add_role_admins(txn_key, batch_key, proposal_id, role_id, user_id,
                            reason, metadata):
    """Create a BatchList with a ProposeAddRoleAdmins transaction in it.

    Args:
        txn_key (Key): The txn signer key pair.
        batch_key (Key): The batch signer key pair.
        role_id (str): The role's id.
        user_id (str): The user that is being proposed to be an admin.
        reason (str): The client supplied reason for the proposal.
        metadata (str): The client supplied metadata.

    Returns:
        tuple
            BatchList, batch header_signature tuple
    """

    propose_add_payload = role_transaction_pb2.ProposeAddRoleAdmin(
        proposal_id=proposal_id,
        role_id=role_id,
        user_id=user_id,
        reason=reason,
        metadata=metadata)

    inputs = [
        addresser.make_user_address(user_id=user_id),
        addresser.make_proposal_address(role_id, user_id),
        addresser.make_role_admins_address(role_id, user_id),
        addresser.make_role_attributes_address(role_id=role_id)
    ]

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

    rbac_payload = rbac_payload_pb2.RBACPayload(
        content=propose_add_payload.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.PROPOSE_ADD_ROLE_ADMINS)

    return make_header_and_batch(rbac_payload, inputs, outputs, txn_key,
                                 batch_key)
def reject_add_role_tasks(txn_key, batch_key, proposal_id, role_id, task_id,
                          reason):

    reject_payload = role_transaction_pb2.RejectAddRoleTask(
        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)]

    rbac_payload = rbac_payload_pb2.RBACPayload(
        content=reject_payload.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.REJECT_ADD_ROLE_TASKS)

    return make_header_and_batch(rbac_payload, inputs, outputs, txn_key,
                                 batch_key)
예제 #26
0
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 reject_add_role_admins(txn_key, batch_key, proposal_id, role_id, user_id,
                           reason):

    reject_add_payload = role_transaction_pb2.RejectAddRoleAdmin(
        proposal_id=proposal_id,
        role_id=role_id,
        user_id=user_id,
        reason=reason)

    inputs = [
        addresser.make_role_admins_address(role_id=role_id,
                                           user_id=txn_key.public_key)
    ]
    inputs.append(addresser.make_proposal_address(role_id, user_id))

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

    rbac_payload = rbac_payload_pb2.RBACPayload(
        content=reject_add_payload.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.REJECT_ADD_ROLE_ADMINS)

    return make_header_and_batch(rbac_payload, inputs, outputs, txn_key,
                                 batch_key)
예제 #28
0
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
예제 #29
0
def confirm_manager(txn_key, batch_key, proposal_id, user_id, manager_id,
                    reason):
    """Create a BatchList with a ConfirmUpdateUserManager transaction in it.

    Args:
        txn_key (Key): The transaction signer public/private key pair.
        batch_key (Key): The batch signer public/private key pair.
        proposal_id (str): The identifier of the proposal.
        reason (str): The client supplied reason for the confirmation.

    Returns:
        tuple
            BatchList, batch header_signature tuple
    """

    confirm_update_payload = user_transaction_pb2.ConfirmUpdateUserManager(
        proposal_id=proposal_id,
        user_id=user_id,
        manager_id=manager_id,
        reason=reason)

    inputs = [
        addresser.make_proposal_address(user_id, manager_id),
        addresser.make_user_address(user_id)
    ]

    outputs = [
        addresser.make_proposal_address(user_id, manager_id),
        addresser.make_user_address(user_id)
    ]

    rbac_payload = rbac_payload_pb2.RBACPayload(
        content=confirm_update_payload.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.CONFIRM_UPDATE_USER_MANAGER)

    return make_header_and_batch(rbac_payload, inputs, outputs, txn_key,
                                 batch_key)
예제 #30
0
def _validate_unique_proposal(header, user_proposal, state):
    proposal_address = addresser.make_proposal_address(
        object_id=user_proposal.user_id,
        related_id=user_proposal.new_manager_id)
    state_return = get_state(state, [proposal_address])
    if not no_open_proposal(
            state_return,
            proposal_address,
            user_proposal.user_id,
            user_proposal.new_manager_id,
            proposal_type=proposal_state_pb2.Proposal.UPDATE_USER_MANAGER):
        raise InvalidTransaction("There is already a ProposeUpdateUserManager "
                                 "proposal for this user and manager.")

    return state_return