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 validate_manager_state(create_user, state): manager_entries = state_accessor.get_state( state, [addresser.user.address(create_user.manager_id)]) if not manager_entries: raise InvalidTransaction("User id {} listed as manager is not " "in state.".format(create_user.manager_id)) state_entry = state_accessor.get_state_entry( manager_entries, addresser.user.address(create_user.manager_id)) manager_container = message_accessor.get_user_container(state_entry) if not message_accessor.is_in_user_container(manager_container, create_user.manager_id): raise InvalidTransaction( "user id {} listed as manager is not within the User container " "in state".format(create_user.manager_id))
def validate_user_state(create_user, state): user_entries = state_accessor.get_state( state, [addresser.user.address(create_user.user_id)]) if user_entries: # this is necessary for state collisions. try: user_container = message_accessor.get_user_container( user_entries[0]) _get_index_in_container(user_container, create_user.user_id) raise InvalidTransaction( "User with user_id {} already exists.".format( create_user.user_id)) except KeyError: # The user does not exist yet in state and so the transaction # is valid. pass
def confirm_manager_change(container, proposal, closer, reason, address, user_id, new_manager_id, state): proposal.status = proposal_state_pb2.Proposal.CONFIRMED proposal.closer = closer proposal.close_reason = reason state_accessor.set_state(state, {address: container.SerializeToString()}) user_address = addresser.make_user_address(user_id) state_entries = state_accessor.get_state(state, [user_address]) state_entry = state_accessor.get_state_entry(state_entries=state_entries, address=user_address) user_container = message_accessor.get_user_container(state_entry) user = message_accessor.get_user_from_container(user_container, user_id) user.manager_id = new_manager_id state_accessor.set_state( state, {user_address: user_container.SerializeToString()})
def _validate_state_and_return_user(header, user_proposal, state): """Validate that 1. There is no other open proposal for the manager change 2. The user is a User 3. the manager is a User 4. The manager is the signer of the transaction. Args: header (TransactionHeader): The transaction header. user_proposal (ProposeUpdateUserManager): The transaction that makes the proposal to update the user's manager. state (Context): The way to set and get values from state. """ prop_state_entries = _validate_unique_proposal(user_proposal, state) user_address = addresser.make_user_address(user_id=user_proposal.user_id) user_state_entries = state_accessor.get_state(state, [user_address]) user_validator.validate_identifier_is_user( state_entries=user_state_entries, identifier=user_proposal.user_id, address=user_address, ) manager_address = addresser.make_user_address( user_id=user_proposal.new_manager_id) manager_state_entries = state_accessor.get_state(state, [manager_address]) user_validator.validate_identifier_is_user( state_entries=manager_state_entries, identifier=user_proposal.new_manager_id, address=manager_address, ) user_state_entry = state_accessor.get_state_entry(user_state_entries, user_address) user_container = message_accessor.get_user_container(user_state_entry) _validate_manager_is_signer(header, user_container, user_proposal.user_id) return prop_state_entries
def validate_identifier_is_user(state_entries, identifier, address): """Validate that the identifier references a User or raise an InvalidTransaction if that user does not exist. Args: state_entries (list): List of StateEntry as returned from a state get. identifier (str): The identifier of the User. address (str): The address used to get the user container. Raises: InvalidTransaction: No user with that identifier exists. """ try: container = message_accessor.get_user_container( state_accessor.get_state_entry(state_entries, address)) if not message_accessor.is_in_user_container(container, identifier): raise InvalidTransaction("{} is not a user".format(identifier)) except KeyError: raise InvalidTransaction("{} is not a user".format(identifier))
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: (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 = state_accessor.get_state( state, [user_address, task_address, proposal_address, rel_address]) user_validator.validate_identifier_is_user(state_entries, identifier=propose.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), propose.user_id) validate_identifier_is_task(state_entries, identifier=propose.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, propose.task_id, propose.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 not message_accessor.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 get_user_from_id(state, user_id): user_address = addresser.make_user_address(user_id) state_entries = get_state(state, [user_address]) user_entry = get_state_entry(state_entries, user_address) return message_accessor.get_user_from_container( message_accessor.get_user_container(user_entry), user_id)
def validate_role_rel_proposal(header, propose, rel_address, state, is_remove=False): """Validates that the User exists, the Role exists, and the User is not in the Role's relationship specified by rel_address. Args: header (TransactionHeader): The transaction header. propose (ProposeAddRole_____): The role relationship proposal. rel_address (str): The Role relationship address produced by the Role 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) role_address = addresser.make_role_attributes_address(propose.role_id) proposal_address = addresser.make_proposal_address( object_id=propose.role_id, related_id=propose.user_id ) state_entries = state_accessor.get_state( state, [user_address, role_address, proposal_address, rel_address] ) user_validator.validate_identifier_is_user( state_entries, identifier=propose.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), 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_role( state_entries, identifier=propose.role_id, address=role_address ) try: role_admins_entry = state_accessor.get_state_entry(state_entries, rel_address) role_rel_container = message_accessor.get_role_rel_container(role_admins_entry) if (header.signer_public_key not in [user.user_id, user.manager_id]) and ( not message_accessor.is_in_role_rel_container( role_rel_container, propose.role_id, propose.user_id ) ): raise InvalidTransaction( "Txn signer {} is not the user or the user's " "manager {} nor the group owner / admin".format( header.signer_public_key, [user.user_id, user.manager_id] ) ) if (not is_remove) and message_accessor.is_in_role_rel_container( role_rel_container, propose.role_id, propose.user_id ): raise InvalidTransaction( "User {} is already in the Role {} " "relationship".format(propose.user_id, propose.role_id) ) except KeyError: # The role rel container doesn't exist so no role relationship exists pass return state_entries