def create_role(new_role, state):
    role_container = role_state_pb2.RoleAttributesContainer()
    role = role_container.role_attributes.add()
    role.role_id = new_role.role_id
    role.name = new_role.name
    role.metadata = new_role.metadata

    entries_to_set = {
        addresser.make_role_attributes_address(
            new_role.role_id
        ): role_container.SerializeToString()
    }

    pubkeys_by_address = {}

    for admin in list(new_role.admins):
        admin_address = addresser.make_role_admins_address(
            role_id=new_role.role_id, user_id=admin
        )

        if admin_address in pubkeys_by_address:
            pubkeys_by_address[admin_address].append(admin)
        else:
            pubkeys_by_address[admin_address] = [admin]

    for owner in list(new_role.owners):
        owner_address = addresser.make_role_owners_address(
            role_id=new_role.role_id, user_id=owner
        )

        if owner_address in pubkeys_by_address:
            pubkeys_by_address[owner_address].append(owner)
        else:
            pubkeys_by_address[owner_address] = [owner]

    state_returns = state_accessor.get_state(
        state,
        [
            addresser.make_role_admins_address(role_id=new_role.role_id, user_id=a)
            for a in new_role.admins
        ]
        + [
            addresser.make_role_owners_address(role_id=new_role.role_id, user_id=o)
            for o in new_role.owners
        ],
    )

    for addr, pubkeys in pubkeys_by_address.items():
        try:
            state_entry = state_accessor.get_state_entry(state_returns, addr)
            container = role_state_pb2.RoleRelationshipContainer()
            container.ParseFromString(state_entry.data)
        except KeyError:
            container = role_state_pb2.RoleRelationshipContainer()

        message_accessor.add_role_rel_to_container(container, new_role.role_id, pubkeys)

        entries_to_set[addr] = container.SerializeToString()

        state_accessor.set_state(state, entries_to_set)
Ejemplo n.º 2
0
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 apply_confirm(header, payload, state):

    confirm_payload = role_transaction_pb2.ConfirmAddRoleAdmin()
    confirm_payload.ParseFromString(payload.content)

    role_admin_address = addresser.make_role_admins_address(
        role_id=confirm_payload.role_id, user_id=confirm_payload.user_id
    )

    txn_signer_admin_address = addresser.make_role_admins_address(
        role_id=confirm_payload.role_id, user_id=header.signer_public_key
    )

    state_entries = role_validator.get_state_entries(
        header=header,
        confirm=confirm_payload,
        txn_signer_rel_address=txn_signer_admin_address,
        state=state,
    )

    state_change.confirm_role_action(
        state_entries=state_entries,
        header=header,
        confirm=confirm_payload,
        role_rel_address=role_admin_address,
        state=state,
    )
Ejemplo n.º 4
0
def create_role(txn_key, batch_key, role_name, role_id, metadata, admins,
                owners):
    """Create a BatchList with a CreateRole transaction in it.

    Args:
        txn_key (Key): The transaction signer's key pair.
        batch_key (Key): The batch signer's key pair.
        role_name (str): The name of the Role.
        role_id (str): A uuid that identifies this Role.
        metadata (str): Client supplied information that is not parsed.
        admins (list): A list of User ids of the Users who are admins of this
            Role.
        owners (list): A list of User ids of the Users who are owners of this
            Role.

    Returns:
        tuple
            BatchList, batch header_signature tuple
    """

    create_role_payload = role_transaction_pb2.CreateRole(role_id=role_id,
                                                          name=role_name,
                                                          metadata=metadata,
                                                          admins=admins,
                                                          owners=owners)

    inputs = [
        addresser.make_sysadmin_members_address(txn_key.public_key),
        addresser.make_role_attributes_address(role_id),
    ]
    inputs.extend([addresser.make_user_address(u) for u in admins])
    inputs.extend([addresser.make_user_address(u) for u in owners])
    inputs.extend([
        addresser.make_role_admins_address(role_id=role_id, user_id=a)
        for a in admins
    ])
    inputs.extend([
        addresser.make_role_owners_address(role_id=role_id, user_id=o)
        for o in owners
    ])

    outputs = [addresser.make_role_attributes_address(role_id)]
    outputs.extend([
        addresser.make_role_admins_address(role_id=role_id, user_id=a)
        for a in admins
    ])
    outputs.extend([
        addresser.make_role_owners_address(role_id=role_id, user_id=o)
        for o in owners
    ])

    rbac_payload = rbac_payload_pb2.RBACPayload(
        content=create_role_payload.SerializeToString(),
        message_type=rbac_payload_pb2.RBACPayload.CREATE_ROLE,
    )

    return make_header_and_batch(rbac_payload, inputs, outputs, txn_key,
                                 batch_key)
Ejemplo n.º 5
0
def confirm_add_role_owners(txn_key, batch_key, proposal_id, role_id, user_id,
                            reason):

    confirm_payload = role_transaction_pb2.ConfirmAddRoleOwner(
        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_admins_address(role_id, txn_key.public_key),
    ]

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

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

    return make_header_and_batch(rbac_payload, inputs, outputs, txn_key,
                                 batch_key)
 def check_admin(self, role_id, user_id):
     container = role_state_pb2.RoleRelationshipContainer()
     address = addresser.make_role_admins_address(role_id=role_id, user_id=user_id)
     container.ParseFromString(self.client.get_address(address=address))
     items = list(container.relationships)
     if len(items) == 0:
         return False
     elif len(items) > 1:
         LOGGER.warning(
             "role %s admins container for user %s at address %s has more than one record",
             role_id,
             user_id,
             address,
         )
     item = items[0]
     identifiers = list(item.identifiers)
     if len(identifiers) == 0:
         LOGGER.warning(
             "role %s admins container for user %s at address %s has no identifiers",
             role_id,
             user_id,
             address,
         )
         return False
     if len(identifiers) > 1:
         LOGGER.warning(
             "role %s admins container for user %s at address %s has more than one identifier",
             role_id,
             user_id,
             address,
         )
     return bool(user_id in item.identifiers)
Ejemplo n.º 7
0
    def test_generated_role_admin_addr(self):
        """Tests the role admin address creation function as well as the
        address_is function.
        """

        role_id = uuid4().hex
        admin_id = uuid4().hex
        address = addresser.make_role_admins_address(role_id, admin_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_ADMINS,
            "The address created must be a Role Attributes address.",
        )
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)
Ejemplo n.º 9
0
    def test_determine_role_admin_addr(self):
        """Tests that a specific role_id and admin_id generates the
        expected role admin address, and thus is probably deterministic.
        """

        role_id = "99968acb8f1a48b3a4bc21e2cd252e67"
        admin_id = "966ab67317234df489adb4bc1f517b88"
        expected_address = "9f444809326a1713a905b26359fc8d\
a2817c1a5f67de6f464701f0c10042da345d28f7"

        address = addresser.make_role_admins_address(role_id, admin_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_ADMINS,
            "The address created must be a Role Attributes address.",
        )
Ejemplo n.º 10
0
def apply_propose_remove(header, payload, state):
    role_admins_payload = role_transaction_pb2.ProposeRemoveRoleAdmin()
    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, True)

    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.REMOVE_ROLE_ADMINS,
    ):
        raise InvalidTransaction(
            "There is already an open proposal for REMOVE_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.REMOVE_ROLE_ADMINS,
        state=state,
    )
Ejemplo n.º 11
0
def hierarchical_decide(header, payload, state, isApproval):
    confirm = role_transaction_pb2.ConfirmAddRoleAdmin()
    confirm.ParseFromString(payload.content)

    txn_signer_admin_address = addresser.make_role_admins_address(
        role_id=confirm.role_id, user_id=confirm.on_behalf_id)

    role_operation.hierarchical_decide(header, confirm, state,
                                       txn_signer_admin_address, isApproval)
Ejemplo n.º 12
0
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 create(self, signer_keypair, role, do_batch=True, do_send=True, do_get=False):
        if not isinstance(signer_keypair, Key):
            raise TypeError("Expected signer_keypair to be a Key")
        if not isinstance(role, role_transaction_pb2.CreateRole):
            raise TypeError(
                "Expected role to be a role_transaction_pb2.CreateRole, use make first"
            )

        inputs = [
            addresser.make_sysadmin_members_address(signer_keypair.public_key),
            addresser.make_role_attributes_address(role.role_id),
        ]
        inputs.extend([addresser.make_user_address(u) for u in role.admins])
        inputs.extend([addresser.make_user_address(u) for u in role.owners])
        inputs.extend(
            [
                addresser.make_role_admins_address(role_id=role.role_id, user_id=a)
                for a in role.admins
            ]
        )
        inputs.extend(
            [
                addresser.make_role_owners_address(role_id=role.role_id, user_id=o)
                for o in role.owners
            ]
        )

        transaction = self.batch.make_transaction(
            message=role,
            message_type=RBACPayload.CREATE_ROLE,
            inputs=inputs,
            outputs=inputs,
            signer_keypair=signer_keypair,
        )

        if not do_batch:
            return transaction

        batch = self.batch.make_batch(transaction=transaction)
        if not do_send:
            return batch

        batch_list = self.batch.batch_to_list(batch)
        status = self.client.send_batches_get_status(batch_list=batch_list)
        if not do_get:
            return status

        return self.get(role_id=role.role_id)
Ejemplo n.º 14
0
def apply_reject(header, payload, state):
    reject_payload = role_transaction_pb2.RejectAddRoleOwner()
    reject_payload.ParseFromString(payload.content)

    txn_signer_admins_address = addresser.make_role_admins_address(
        role_id=reject_payload.role_id, user_id=header.signer_public_key
    )

    state_entries = state_accessor.get_state_entries(
        header=header,
        confirm=reject_payload,
        txn_signer_rel_address=txn_signer_admins_address,
        state=state,
    )

    state_change.reject_role_action(
        state_entries, header, reject=reject_payload, state=state
    )
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_remove_role_owners(
    txn_key, batch_key, proposal_id, role_id, user_id, reason
):
    reject_payload = role_transaction_pb2.RejectRemoveRoleOwner(
        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_admins_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_OWNERS,
    )

    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 make_addresses(self, message, signer_public_key=None):
        """Makes the approporiate inputs & output addresses for the message type"""
        if isinstance(message, role_transaction_pb2.CreateRole):
            inputs = [
                # addresser.make_sysadmin_members_address(signer_public_key),
                addresser.make_role_attributes_address(message.role_id)
            ]
            inputs.extend([addresser.make_user_address(u) for u in message.admins])
            inputs.extend([addresser.make_user_address(u) for u in message.owners])
            inputs.extend(
                [
                    addresser.make_role_admins_address(
                        role_id=message.role_id, user_id=a
                    )
                    for a in message.admins
                ]
            )
            inputs.extend(
                [
                    addresser.make_role_owners_address(
                        role_id=message.role_id, user_id=o
                    )
                    for o in message.owners
                ]
            )
            outputs = inputs

        elif isinstance(message, role_transaction_pb2.ProposeAddRoleMember):
            relationship_address = addresser.make_role_members_address(
                role_id=message.role_id, user_id=message.user_id
            )
        elif isinstance(message, role_transaction_pb2.ProposeAddRoleOwner):
            relationship_address = addresser.make_role_owners_address(
                role_id=message.role_id, user_id=message.user_id
            )
        elif isinstance(message, role_transaction_pb2.ProposeAddRoleAdmin):
            relationship_address = addresser.make_role_admins_address(
                role_id=message.role_id, user_id=message.user_id
            )
        else:
            raise TypeError(
                "RoleManager.make_addresses doesn't support message type {}".format(
                    type(message)
                )
            )

        if (
            isinstance(message, role_transaction_pb2.ProposeAddRoleMember)
            or isinstance(message, role_transaction_pb2.ProposeAddRoleOwner)
            or isinstance(message, role_transaction_pb2.ProposeAddRoleAdmin)
        ):

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

            role_address = addresser.make_role_attributes_address(
                role_id=message.role_id
            )
            user_address = addresser.make_user_address(user_id=message.user_id)

            inputs = [
                relationship_address,
                role_address,
                user_address,
                proposal_address,
            ]
            outputs = [proposal_address]

        return inputs, outputs
    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.",
        )