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)
def propose_add_role_members(txn_key, batch_key, proposal_id, role_id, user_id, reason, metadata): propose_payload = role_transaction_pb2.ProposeAddRoleMember( proposal_id=proposal_id, role_id=role_id, user_id=user_id, reason=reason) inputs = [ addresser.make_role_members_address(role_id, user_id), addresser.make_role_attributes_address(role_id=role_id), addresser.make_user_address(user_id=user_id), addresser.make_proposal_address(role_id, user_id), ] outputs = [addresser.make_proposal_address(role_id, user_id)] rbac_payload = rbac_payload_pb2.RBACPayload( content=propose_payload.SerializeToString(), message_type=rbac_payload_pb2.RBACPayload.PROPOSE_ADD_ROLE_MEMBERS, ) 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)
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 propose_remove_role_admins( txn_key, batch_key, proposal_id, role_id, user_id, reason, metadata ): propose = role_transaction_pb2.ProposeRemoveRoleAdmin( 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.SerializeToString(), message_type=rbac_payload_pb2.RBACPayload.PROPOSE_REMOVE_ROLE_ADMINS, ) return make_header_and_batch(rbac_payload, inputs, outputs, txn_key, batch_key)
def confirm_add_task_admins(txn_key, batch_key, proposal_id, task_id, user_id, reason): confirm_payload = task_transaction_pb2.ConfirmAddTaskAdmin( 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), addresser.make_task_admins_address(task_id, user_id), ] rbac_payload = rbac_payload_pb2.RBACPayload( content=confirm_payload.SerializeToString(), message_type=rbac_payload_pb2.RBACPayload.CONFIRM_ADD_TASK_ADMINS, ) return make_header_and_batch(rbac_payload, inputs, outputs, txn_key, batch_key)
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)
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)
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 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) """ task_id = propose.task_id user_id = propose.user_id user_address = addresser.make_user_address(user_id) task_address = addresser.make_task_attributes_address(task_id) proposal_address = addresser.make_proposal_address(object_id=task_id, related_id=user_id) state_entries = state_accessor.get_state( state, [user_address, task_address, proposal_address, rel_address]) user_validator.validate_identifier_is_user(state_entries, identifier=user_id, address=user_address) user_entry = state_accessor.get_state_entry(state_entries, user_address) user = message_accessor.get_user_from_container( message_accessor.get_user_container(user_entry), user_id) validate_identifier_is_task(state_entries, identifier=task_id, address=task_address) try: task_rel_entry = state_accessor.get_state_entry( state_entries, rel_address) task_rel_container = message_accessor.get_task_rel_container( task_rel_entry) if (header.signer_public_key not in [ user.user_id, user.manager_id ]) and (not message_accessor.is_in_task_rel_container( task_rel_container, task_id, user_id)): raise InvalidTransaction( "Txn signer {} is not the user or the user's " "manager {} nor the task owner / admin".format( header.signer_public_key, [user.user_id, user.manager_id])) if message_accessor.is_in_task_rel_container(task_rel_container, task_id, user_id): raise InvalidTransaction("User {} is already in the Task {} " "relationship".format(user_id, task_id)) except KeyError: # The task rel container doesn't exist so no task relationship exists pass return state_entries
def apply_propose_remove(header, payload, state): proposal_payload = role_transaction_pb2.ProposeRemoveRoleMember() proposal_payload.ParseFromString(payload.content) role_owners_address = addresser.make_role_owners_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 = role_validator.validate_role_rel_proposal( header, proposal_payload, role_owners_address, state, True) if not proposal_validator.has_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_OWNERS, ): raise InvalidTransaction( "There is already an open proposal for REMOVE_ROLE_OWNERS " "with role id {} and user id {}".format(proposal_payload.role_id, proposal_payload.user_id)) state_change.propose_role_action( state_entries=state_entries, header=header, payload=proposal_payload, address=proposal_address, proposal_type=proposal_state_pb2.Proposal.REMOVE_ROLE_OWNERS, state=state, )
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 = role_validator.validate_role_rel_proposal( header, role_admins_payload, role_admins_address, state) if not proposal_validator.has_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)) state_change.propose_role_action( state_entries=state_entries, header=header, payload=role_admins_payload, address=proposal_address, proposal_type=proposal_state_pb2.Proposal.ADD_ROLE_ADMINS, state=state, )
def propose_manager_change(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 = state_accessor.get_state_entry(proposal_state_entries, proposal_address) proposal_container = message_accessor.get_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_public_key proposal.status = proposal_state_pb2.Proposal.OPEN proposal.open_reason = user_proposal.reason proposal.metadata = user_proposal.metadata state_accessor.set_state( state, {proposal_address: proposal_container.SerializeToString()})
def record_decision(state, header, confirm, isApproval): """ Record decisions made and who made it in the proposal object """ on_behalf_id = confirm.on_behalf_id proposal_address = addresser.make_proposal_address( object_id=confirm.role_id, related_id=confirm.user_id) state_entries = state_accessor.get_state(state, [proposal_address]) proposal_entry = state_accessor.get_state_entry(state_entries, proposal_address) proposal_container = message_accessor.get_prop_container(proposal_entry) proposal = message_accessor.get_prop_from_container( proposal_container, proposal_id=confirm.proposal_id) if isApproval: record = proposal.approvals.add() record.approver = header.signer_public_key record.on_behalf = on_behalf_id else: record = proposal.rejections.add() record.rejector = header.signer_public_key record.on_behalf = on_behalf_id LOGGER.info( "recording decision from {}, on behalf of {} for proposal {}".format( # pylint: disable=logging-format-interpolation header.signer_public_key, confirm.on_behalf_id, confirm.proposal_id)) state_accessor.set_state( state, {proposal_address: proposal_container.SerializeToString()})
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 = state_accessor.get_state( state, [txn_signer_rel_address, proposal_address] ) if not proposal_validator.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 = state_accessor.get_state_entry(state_entries, txn_signer_rel_address) task_owners_container = message_accessor.get_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 message_accessor.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 hierarchical_decide(header, confirm, state, txn_signer_rel_address, isApproval): proposal_address = addresser.make_proposal_address( object_id=confirm.role_id, related_id=confirm.user_id) state_entries = state_accessor.get_state( state, [txn_signer_rel_address, proposal_address]) if not proposal_validator.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)) # verify on_behalf user has the permission to perform the action role_validator.verify_user_with_role_permission_on_proposal( proposal_address, confirm.on_behalf_id, confirm.role_id, txn_signer_rel_address, state, ) # verify current user is in the manager hierachy of on_behalf user if not state_accessor.is_hierarchical_manager_of_user( state, header, confirm.on_behalf_id): raise InvalidTransaction( "Signer {} is not a higher manager of {}. Signer cannot " "make decision on behalf of {}".format(header.signer_public_key, confirm.on_behalf_id, confirm.on_behalf_id)) state_change.record_decision(state, header, confirm, isApproval)
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 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.", )
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 = state_accessor.get_state( state, [txn_signer_rel_address, proposal_address] ) else: state_entries = state_accessor.get_state( state, [txn_signer_rel_address, task_rel_address, proposal_address] ) if not proposal_validator.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 = state_accessor.get_state_entry(state_entries, txn_signer_rel_address) task_rel_container = message_accessor.get_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 message_accessor.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 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)
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_add_task_owners(txn_key, batch_key, proposal_id, task_id, user_id, reason): reject = task_transaction_pb2.RejectAddTaskOwner( 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_ADD_TASK_OWNERS, ) return make_header_and_batch(rbac_payload, inputs, outputs, txn_key, batch_key)
def confirm_task_action(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 = state_accessor.get_state_entry(state_entries, proposal_address) proposal_container = message_accessor.get_prop_container(proposal_entry) proposal = message_accessor.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 = state_accessor.get_state_entry( state_entries, task_rel_address) task_rel_container = message_accessor.get_task_rel_container( task_rel_entry) except KeyError: task_rel_container = task_state_pb2.TaskRelationshipContainer() try: task_rel = message_accessor.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() state_accessor.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)
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)
def reject_remove_task_admins( txn_key, batch_key, proposal_id, task_id, user_id, reason ): reject_payload = task_transaction_pb2.RejectRemoveTaskAdmin( 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_REMOVE_TASK_ADMINS, ) return make_header_and_batch(rbac_payload, inputs, outputs, txn_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 apply_propose_remove(header, payload, state): """Apply the ProposeRemoveTaskAdmins transaction. Args: header (TransactionHeader): The protobuf TransactionHeader. payload (RBACPayload): The protobuf RBACPayload. state (Context): The class that handles state gets and sets. Raises InvalidTransaction: - The transaction is invalid. """ propose_payload = task_transaction_pb2.ProposeRemoveTaskAdmin() propose_payload.ParseFromString(payload.content) task_admins_address = addresser.make_task_admins_address( task_id=propose_payload.task_id, user_id=propose_payload.user_id ) proposal_address = addresser.make_proposal_address( propose_payload.task_id, propose_payload.user_id ) state_entries = task_validator.validate_task_rel_del_proposal( header=header, propose=propose_payload, rel_address=task_admins_address, state=state, ) if not proposal_validator.has_no_open_proposal( state_entries=state_entries, object_id=propose_payload.task_id, related_id=propose_payload.user_id, proposal_address=proposal_address, proposal_type=proposal_state_pb2.Proposal.REMOVE_TASK_ADMINS, ): raise InvalidTransaction( "There is already an open proposal for REMOVE_TASK_ADMINS " "with task id {} and user id {}".format( propose_payload.task_id, propose_payload.user_id ) ) state_change.propose_task_action( state_entries=state_entries, header=header, payload=propose_payload, address=proposal_address, proposal_type=proposal_state_pb2.Proposal.REMOVE_TASK_ADMINS, state=state, )