예제 #1
0
 def test_key_signing(self):
     """Test that you can sign with a key"""
     signer_keypair = Key()
     message = generate_random_string(50)
     factory = CryptoFactory(sawtooth_signing.create_context("secp256k1"))
     signer = factory.new_signer(
         Secp256k1PrivateKey.from_hex(signer_keypair.private_key))
     signature = signer.sign(bytes(message, "utf8"))
     self.assertTrue(SIGNATURE_PATTERN.match(signature))
     return signature, message, signer_keypair.public_key
예제 #2
0
 def get_test_inputs(self, message_type=RBACPayload.CREATE_USER):
     if message_type == RBACPayload.CREATE_USER:
         signer = Key()
         message = user_transaction_pb2.CreateUser(name="foobar")
         message.user_id = signer.public_key
         inputs = [make_user_address(signer.public_key)]
         outputs = inputs
         return message, message_type, inputs, outputs, signer
     else:
         raise Exception(
             "get_test_payload doesn't yet support {}".format(message_type))
 def test_key_class_random_keys(self):
     value1 = Key()
     value2 = Key()
     self.assertTrue(isinstance(value1, Key))
     self.assertTrue(isinstance(value2, Key))
     self.assertNotEqual(value1, value2)
     self.assertIsInstance(value1.public_key, str)
     self.assertIsInstance(value2.public_key, str)
     self.assertIsInstance(value1.private_key, str)
     self.assertIsInstance(value2.private_key, str)
     self.assertEqual(len(value1.public_key), PUBLIC_KEY_LENGTH * 2)
     self.assertEqual(len(value2.public_key), PUBLIC_KEY_LENGTH * 2)
     self.assertEqual(len(value1.private_key), PRIVATE_KEY_LENGTH * 2)
     self.assertEqual(len(value2.private_key), PRIVATE_KEY_LENGTH * 2)
     self.assertTrue(PUBLIC_KEY_PATTERN.match(value1.public_key))
     self.assertTrue(PUBLIC_KEY_PATTERN.match(value2.public_key))
     self.assertTrue(PRIVATE_KEY_PATTERN.match(value1.private_key))
     self.assertTrue(PRIVATE_KEY_PATTERN.match(value2.private_key))
     self.assertNotEqual(value1.public_key, value2.public_key)
     self.assertNotEqual(value1.private_key, value2.private_key)
예제 #4
0
def unmake(batch_object,
           signer_public_key=None,
           batcher_public_key=BATCHER_KEY_PAIR.public_key):
    """ Will unmake a batch_request, batch_list, batch, transaction
        or payload, and return a list of the included messages.
        Validation of signatures will occur if public keys are provided.
        Only used for testing purposes.
    """
    if isinstance(
            batch_object,
        (client_batch_submit_pb2.ClientBatchSubmitRequest,
         batch_pb2.BatchList),
    ):
        return list(
            itertools.chain(*[
                unmake(
                    batch_object=batch,
                    signer_public_key=signer_public_key,
                    batcher_public_key=batcher_public_key,
                ) for batch in batch_object.batches
            ]))
    if isinstance(batch_object, batch_pb2.Batch):
        batch_header = batch_pb2.BatchHeader()
        batch_header.ParseFromString(batch_object.header)
        if batcher_public_key:
            # pylint: disable=no-member
            assert batch_header.signer_public_key == batcher_public_key
            batcher_keypair = Key(public_key=batcher_public_key)
            assert batcher_keypair.verify(
                signature=batch_object.header_signature,
                message=batch_object.header)
        transactions = list(batch_object.transactions)
        return [
            unmake_item(batch_object=transaction,
                        signer_public_key=signer_public_key)
            for transaction in transactions
        ]
    return [
        unmake_item(batch_object=batch_object,
                    signer_public_key=signer_public_key)
    ]
예제 #5
0
    def get_test_inputs(self, message_type=RBACPayload.CREATE_USER):
        """Returns test data inputs for testing batcher functions"""
        if message_type == RBACPayload.CREATE_USER:
            signer = Key()
            message = user_transaction_pb2.CreateUser(name="foobar")
            message.user_id = signer.public_key
            inputs = [addresser.user.address(message.user_id)]
            outputs = inputs
            return message, message_type, inputs, outputs, signer

        raise Exception("batcher test doesn't support message_type: {}".format(
            message_type))
예제 #6
0
 def test_make_addresses(self):
     """Test making addresses without manager"""
     self.assertTrue(callable(self.rbac.user.make_addresses))
     name = self.test.user.name()
     keypair = Key()
     message = self.rbac.user.make(user_id=keypair.public_key, name=name)
     inputs, outputs = self.rbac.user.make_addresses(message=message)
     user_address = self.rbac.user.address(object_id=message.user_id)
     self.assertIsInstance(inputs, list)
     self.assertIn(user_address, inputs)
     self.assertEqual(len(inputs), 1)
     self.assertEqual(inputs, outputs)
예제 #7
0
 def test_make(self):
     """Test getting a test data user with keys"""
     self.assertTrue(callable(self.rbac.user.make))
     name = self.test.user.name()
     keypair = Key()
     message = self.rbac.user.make(user_id=keypair.public_key, name=name)
     self.assertIsInstance(message,
                           protobuf.user_transaction_pb2.CreateUser)
     self.assertIsInstance(message.user_id, str)
     self.assertIsInstance(message.name, str)
     self.assertEqual(message.user_id, keypair.public_key)
     self.assertEqual(message.name, name)
예제 #8
0
 def test_key_signature_validation(self):
     signature, message, pubkey = self.test_key_signing()
     public_key = Secp256k1PublicKey.from_hex(pubkey)
     context = sawtooth_signing.create_context("secp256k1")
     self.assertTrue(
         context.verify(signature, bytes(message, "utf8"), public_key))
     self.assertFalse(
         context.verify(signature, bytes(message + "foo", "utf8"),
                        public_key))
     other = Secp256k1PublicKey.from_hex(Key().public_key)
     self.assertFalse(
         context.verify(signature, bytes(message, "utf8"), other))
예제 #9
0
async def get_transactor_key(request):
    """Get transactor key out of request."""
    id_dict = deserialize_api_key(request.app.config.SECRET_KEY,
                                  extract_request_token(request))
    next_id = id_dict.get("id")

    auth_data = await get_auth_by_next_id(next_id)
    encrypted_private_key = auth_data.get("encrypted_private_key")
    private_key = decrypt_private_key(request.app.config.AES_KEY, next_id,
                                      encrypted_private_key)
    hex_private_key = binascii.hexlify(private_key)
    return Key(hex_private_key), next_id
예제 #10
0
 def test_key_class_random_keys(self):
     """Test the key class generates different keys each time initialized"""
     value1 = Key()
     value2 = Key()
     self.assertTrue(isinstance(value1, Key))
     self.assertTrue(isinstance(value2, Key))
     self.assertNotEqual(value1, value2)
     self.assertIsInstance(value1.public_key, str)
     self.assertIsInstance(value2.public_key, str)
     self.assertIsInstance(value1.private_key, str)
     self.assertIsInstance(value2.private_key, str)
     self.assertEqual(len(value1.public_key), PUBLIC_KEY_LENGTH * 2)
     self.assertEqual(len(value2.public_key), PUBLIC_KEY_LENGTH * 2)
     self.assertEqual(len(value1.private_key), PRIVATE_KEY_LENGTH * 2)
     self.assertEqual(len(value2.private_key), PRIVATE_KEY_LENGTH * 2)
     self.assertTrue(PUBLIC_KEY_PATTERN.match(value1.public_key))
     self.assertTrue(PUBLIC_KEY_PATTERN.match(value2.public_key))
     self.assertTrue(PRIVATE_KEY_PATTERN.match(value1.private_key))
     self.assertTrue(PRIVATE_KEY_PATTERN.match(value2.private_key))
     self.assertNotEqual(value1.public_key, value2.public_key)
     self.assertNotEqual(value1.private_key, value2.private_key)
    def test_unit_with_other_signer(self):
        """Test with signer is neither user nor manager"""
        user_key = Key()
        user_id = user_key.public_key
        manager_key = Key()
        manager_id = manager_key.public_key
        other_key = Key()
        name = self.test.user.name()

        message = protobuf.user_transaction_pb2.CreateUser(
            user_id=user_id, name=name, metadata=None, manager_id=manager_id)

        self.rbac.user.make_payload(message=message, signer_keypair=user_key)
        self.rbac.user.make_payload(message=message,
                                    signer_keypair=manager_key)

        with self.assertRaises(ValueError):
            self.rbac.user.make_payload(message=message,
                                        signer_keypair=other_key)
        with self.assertRaises(ValueError):
            self.rbac.user.create(signer_keypair=other_key, message=message)
    def test_with_manager_not_in_state(self):
        """Test creating a user with manager not in state"""
        user_key = Key()
        user_id = user_key.public_key
        manager_key = Key()
        manager_id = manager_key.public_key
        name = self.test.user.name()

        message = protobuf.user_transaction_pb2.CreateUser(
            user_id=user_id, name=name, metadata=None, manager_id=manager_id)
        inputs, outputs = self.rbac.user.make_addresses(
            message=message, signer_keypair=user_key)
        payload = self.rbac.user.batch.make_payload(
            message=message,
            message_type=self.rbac.user.message_type,
            inputs=inputs,
            outputs=outputs,
        )
        _, status = self.rbac.user.send(signer_keypair=user_key,
                                        payload=payload)
        self.assertStatusInvalid(status)
예제 #13
0
async def get_transactor_key(request):
    id_dict = deserialize_api_key(request.app.config.SECRET_KEY,
                                  extract_request_token(request))
    user_id = id_dict.get("id")

    auth_data = await auth_query.fetch_info_by_user_id(
        request.app.config.DB_CONN, user_id)
    encrypted_private_key = auth_data.get("encrypted_private_key")
    private_key = decrypt_private_key(request.app.config.AES_KEY, user_id,
                                      encrypted_private_key)
    hex_private_key = binascii.hexlify(private_key)
    return Key(hex_private_key), user_id
예제 #14
0
    def assertValidTransactionHeader(self, header, signature, payload,
                                     signer_public_key):
        """Check a transaction header is valid given a payload"""
        if isinstance(header, bytes):
            decoded = transaction_pb2.TransactionHeader()
            decoded.ParseFromString(header)
            header = decoded

        self.assertIsInstance(header, transaction_pb2.TransactionHeader)
        self.assertEqual(header.family_name, addresser.family.name)
        self.assertEqual(header.family_version, addresser.family.version)
        self.assertIsInstance(header.nonce, str)
        self.assertEqual(len(header.nonce), 32)
        self.assertEqual(header.signer_public_key, signer_public_key)
        self.assertEqual(header.payload_sha512,
                         sha512(payload.SerializeToString()).hexdigest())
        signer = Key(public_key=signer_public_key)
        self.assertTrue(
            signer.verify(signature=signature,
                          message=header.SerializeToString()))
        other_key = Key()
        self.assertFalse(
            other_key.verify(signature=signature,
                             message=header.SerializeToString()))

        self.assertEqual(header.inputs, payload.inputs)
        self.assertEqual(header.outputs, payload.outputs)
예제 #15
0
    def assertValidBatch(self, batch, payload, signer_public_key,
                         batcher_public_key):
        """Check a batch is valid given a payload"""
        self.assertIsInstance(batch, batch_pb2.Batch)
        batch_header = batch_pb2.BatchHeader()
        batch_header.ParseFromString(batch.header)
        self.assertIsInstance(batch_header, batch_pb2.BatchHeader)
        self.assertEqual(batch_header.signer_public_key, batcher_public_key)
        batcher_keypair = Key(public_key=batcher_public_key)
        self.assertTrue(
            batcher_keypair.verify(
                signature=batch.header_signature,
                message=batch_header.SerializeToString(),
            ))
        other_key = Key()
        self.assertFalse(
            other_key.verify(
                signature=batch.header_signature,
                message=batch_header.SerializeToString(),
            ))

        transactions = list(batch.transactions)
        self.assertEqual(len(transactions), 1)

        self.assertValidTransaction(
            transaction=transactions[0],
            payload=payload,
            signer_public_key=signer_public_key,
        )
예제 #16
0
async def create_new_user(request):
    required_fields = ["name", "username", "password", "email"]
    utils.validate_fields(required_fields, request.json)

    # Generate keys
    txn_key = Key()
    txn_user_id = rbac.user.unique_id()
    encrypted_private_key = encrypt_private_key(request.app.config.AES_KEY,
                                                txn_key.public_key,
                                                txn_key.private_key_bytes)

    # Build create user transaction
    batch_list = rbac.user.batch_list(
        signer_keypair=txn_key,
        signer_user_id=txn_user_id,
        user_id=txn_user_id,
        name=request.json.get("name"),
        username=request.json.get("username"),
        email=request.json.get("email"),
        metadata=request.json.get("metadata"),
        manager=request.json.get("manager"),
        key=txn_key.public_key,
    )

    # Submit transaction and wait for complete
    await utils.send(request.app.config.VAL_CONN, batch_list,
                     request.app.config.TIMEOUT)

    # Save new user in auth table
    hashed_password = hashlib.sha256(
        request.json.get("password").encode("utf-8")).hexdigest()

    auth_entry = {
        "user_id": txn_user_id,
        "hashed_password": hashed_password,
        "encrypted_private_key": encrypted_private_key,
        "username": request.json.get("username"),
        "email": request.json.get("email"),
    }

    conn = await db_utils.create_connection(
        request.app.config.DB_HOST,
        request.app.config.DB_PORT,
        request.app.config.DB_NAME,
    )

    await auth_query.create_auth_entry(conn, auth_entry)

    conn.close()

    # Send back success response
    return create_user_response(request, txn_user_id)
예제 #17
0
    def test_create(self):
        """Test creating a user on the blockchain"""
        self.assertTrue(callable(self.rbac.user.create))
        name = self.test.user.name()
        user_key = Key()
        user_id = user_key.public_key
        message = self.rbac.user.make(user_id=user_id, name=name)

        user, status = self.rbac.user.create(signer_keypair=user_key,
                                             message=message,
                                             object_id=user_id)
        self.assertStatusSuccess(status)
        self.assertEqualMessage(user, message)
 def get_testdata_inputs(self, message_type=RBACPayload.CREATE_USER):
     """Get test data inputs for a create user message"""
     if message_type == RBACPayload.CREATE_USER:
         signer = Key()
         message = user_transaction_pb2.CreateUser(name=self.get_testdata_name())
         message.user_id = signer.public_key
         inputs = [self.address(signer.public_key)]
         outputs = inputs
         return message, message_type, inputs, outputs, signer
     else:
         raise Exception(
             "get_testdata_payload doesn't yet support {}".format(message_type)
         )
예제 #19
0
def load_config(app):  # pylint: disable=too-many-branches
    # CLI Options will override config file options
    opts = parse_args(sys.argv[1:])

    app.config.HOST = opts.host
    app.config.PORT = opts.port
    app.config.VALIDATOR_HOST = opts.validator_host
    app.config.VALIDATOR_PORT = opts.validator_port
    app.config.TIMEOUT = int(opts.timeout)
    app.config.DB_HOST = opts.db_host
    app.config.DB_PORT = opts.db_port
    app.config.DB_NAME = opts.db_name
    app.config.CHATBOT_HOST = opts.chatbot_host
    app.config.CHATBOT_PORT = opts.chatbot_port
    app.config.CLIENT_HOST = opts.client_host
    app.config.CLIENT_PORT = opts.client_port
    app.config.DEBUG = bool(opts.debug)
    app.config.SECRET_KEY = opts.secret_key
    app.config.AES_KEY = opts.aes_key
    app.config.AIOHTTP_CONN_LIMIT = opts.aiohttp_conn_limit
    app.config.AIOHTTP_DNS_TTL = opts.aiohttp_dns_ttl

    if SECRET_KEY is DEFAULT_CONFIG["SECRET_KEY"]:
        LOGGER.warning(
            """
        ---------------------------------------------
        WARNING: The API secret key was not provided.
        Using an insecure default key. Consider adding
        the following to the environment (e.g. .env file):

        SECRET_KEY=%s
        ---------------------------------------------
        """,
            generate_secret_key(),
        )

    if AES_KEY is DEFAULT_CONFIG["AES_KEY"]:
        LOGGER.warning(
            """
        ---------------------------------------------
        WARNING: The AES secret key was not provided.
        Using an insecure default key. Consider adding
        the following to the environment (e.g. .env file):

        AES_KEY=%s
        ---------------------------------------------
        """,
            generate_aes_key(),
        )

    app.config.BATCHER_KEY_PAIR = Key()
예제 #20
0
def unmake_item(batch_object, signer_public_key=None):
    """ Will unmake_item a transaction or payload, and return a message.
        Validation of signatures will occur if public keys are provided.
        Only used for testing purposes.
    """
    if isinstance(batch_object, transaction_pb2.Transaction):
        header = transaction_pb2.TransactionHeader()
        header.ParseFromString(batch_object.header)
        # pylint: disable=no-member
        assert header.payload_sha512 == sha512(
            batch_object.payload).hexdigest()
        if signer_public_key:
            assert header.signer_public_key == signer_public_key
            signer = Key(public_key=signer_public_key)
            signer.verify(signature=batch_object.header_signature,
                          message=batch_object.header)
        payload = RBACPayload()
        payload.ParseFromString(batch_object.payload)
        batch_object = payload
    if isinstance(batch_object, RBACPayload):
        message, _ = unmake_payload(payload=batch_object)
        return message
    raise Exception("unmake doesn't handle type {}\n{}".format(
        type(batch_object), batch_object))
예제 #21
0
async def fetch_info_by_username(request):
    username = request.json.get("id")
    conn = await db_utils.create_connection(
        request.app.config.DB_HOST,
        request.app.config.DB_PORT,
        request.app.config.DB_NAME,
    )
    result = (await r.table("auth").get_all(
        username, index="username").limit(1).coerce_to("array").run(conn))
    if result:
        return result[0]

    # Auth record not found, check if the username exists
    result = (await r.table("users").get_all(
        username, index="username").limit(1).coerce_to("array").run(conn))
    if not result:
        raise ApiNotFound(
            "No user with username '{}' exists.".format(username))
    result = result[0]

    # Generate and store key and auth record first time a user logs in
    user_id = result.get("user_id")
    user_key = Key()

    batch_list = rbac.key.batch_list(
        signer_keypair=user_key,
        signer_user_id=user_id,
        user_id=user_id,
        key_id=user_key.public_key,
    )
    await utils.send(request.app.config.VAL_CONN, batch_list,
                     request.app.config.TIMEOUT)

    encrypted_private_key = encrypt_private_key(request.app.config.AES_KEY,
                                                user_key.public_key,
                                                user_key.private_key_bytes)
    auth_entry = {
        "user_id": user_id,
        "username": result.get("username"),
        "email": result.get("email"),
        "encrypted_private_key": encrypted_private_key,
    }
    await r.table("auth").insert(auth_entry).run(conn)

    conn.close()

    return auth_entry
예제 #22
0
async def non_admin_creation(request):
    """Creating non-admin users.

    Args:
        request:
            obj: a request object
    """
    try:
        txn_key, txn_user_id = await get_transactor_key(request)
        is_admin = await check_admin_status(txn_user_id)
        if not is_admin:
            raise ApiForbidden(
                "You do not have the authorization to create an account.")
        next_id = str(uuid4())
        key_pair = Key()
        return txn_key, txn_user_id, next_id, key_pair
    except BadSignature:
        raise ApiForbidden(
            "You do not have the authorization to create an account.")
예제 #23
0
async def next_admin_creation(request):
    """Creating the admin user.  Used exclusively for the creation of the NEXT admin

    Args:
        request:
            obj: a request object
    """
    try:
        txn_key, txn_user_id = await get_transactor_key(request)
        is_admin = await check_admin_status(txn_user_id)
        if not is_admin:
            raise ApiUnauthorized(
                "You do not have the authorization to create an account.")
    except ApiUnauthorized:
        txn_key = Key()
        txn_user_id = str(uuid4())
    key_pair = txn_key
    next_id = txn_user_id
    return txn_key, txn_user_id, next_id, key_pair
예제 #24
0
def load_config(app):
    """Load configuration (alphabetical)"""
    app.config.AES_KEY = get_config("AES_KEY")
    app.config.AIOHTTP_CONN_LIMIT = int(get_config("AIOHTTP_CONN_LIMIT"))
    app.config.AIOHTTP_DNS_TTL = int(get_config("AIOHTTP_DNS_TTL"))
    app.config.BATCHER_KEY_PAIR = Key()
    app.config.CHATBOT_HOST = get_config("CHATBOT_HOST")
    app.config.CHATBOT_PORT = get_config("CHATBOT_PORT")
    app.config.CLIENT_HOST = get_config("CLIENT_HOST")
    app.config.CLIENT_PORT = get_config("CLIENT_PORT")
    app.config.DB_HOST = get_config("DB_HOST")
    app.config.DB_NAME = get_config("DB_NAME")
    app.config.DB_PORT = get_config("DB_PORT")
    app.config.DEBUG = bool(get_config("DEBUG"))
    app.config.LOGGING_LEVEL = get_config("LOGGING_LEVEL")
    app.config.SECRET_KEY = get_config("SECRET_KEY")
    app.config.PORT = get_config("SERVER_PORT")
    app.config.TIMEOUT = int(get_config("TIMEOUT"))
    app.config.VALIDATOR = get_config("VALIDATOR")
예제 #25
0
 def make_with_key(
     self,
     name,
     user_id=None,
     user_name=None,
     email=None,
     metadata=None,
     manager_id=None,
 ):
     keypair = Key()
     if user_id is None:
         user_id = keypair.public_key
     user = self.make(
         user_id=user_id,
         name=name,
         user_name=user_name,
         email=email,
         metadata=metadata,
         manager_id=manager_id,
     )
     return user, keypair
    def test_unit_with_self_manager(self):
        """Test creating a user with self as manager"""
        user_key = Key()
        user_id = user_key.public_key
        name = self.test.user.name()
        with self.assertRaises(ValueError):
            message = self.rbac.user.make(user_id=user_id,
                                          name=name,
                                          metadata=None,
                                          manager_id=user_id)

        message = protobuf.user_transaction_pb2.CreateUser(user_id=user_id,
                                                           name=name,
                                                           metadata=None,
                                                           manager_id=user_id)
        with self.assertRaises(ValueError):
            payload = self.rbac.user.make_payload(message=message)

        with self.assertRaises(ValueError):
            payload = self.rbac.user.create(signer_keypair=user_key,
                                            message=message)
예제 #27
0
def load_config(app):
    """Load configuration (alphabetical)"""
    host = get_config("HOST") + ":" + get_config("SERVER_PORT")
    app.config.AES_KEY = get_config("AES_KEY")
    app.config.AIOHTTP_CONN_LIMIT = int(get_config("AIOHTTP_CONN_LIMIT"))
    app.config.AIOHTTP_DNS_TTL = int(get_config("AIOHTTP_DNS_TTL"))
    app.config.API_CONTACT_EMAIL = "*****@*****.**"
    app.config.API_DESCRIPTION = "Available API endpoints for Sawtooth Next Directory."
    app.config.API_HOST = host
    app.config.API_LICENSE_NAME = "Apache License 2.0"
    app.config.API_LICENSE_URL = (
        "https://github.com/tmobile/sawtooth-next-directory/blob/develop/LICENSE"
    )
    app.config.API_PRODUCES_CONTENT_TYPES = ["application/json"]
    app.config.API_SCHEMES = ["http", "https"]
    app.config.API_TITLE = "Sawtooth Next Directory API"
    app.config.API_SECURITY = [{"authToken": []}]
    app.config.API_SECURITY_DEFINITIONS = {
        "authToken": {
            "type": "apiKey",
            "in": "header",
            "name": "Authorization",
            "description": "Paste your auth token.",
        }
    }
    app.config.BATCHER_KEY_PAIR = Key()
    app.config.CHATBOT_HOST = get_config("CHATBOT_HOST")
    app.config.CHATBOT_PORT = get_config("CHATBOT_PORT")
    app.config.CLIENT_HOST = get_config("CLIENT_HOST")
    app.config.CLIENT_PORT = get_config("CLIENT_PORT")
    app.config.DB_HOST = get_config("DB_HOST")
    app.config.DB_NAME = get_config("DB_NAME")
    app.config.DB_PORT = get_config("DB_PORT")
    app.config.DEBUG = bool(get_config("DEBUG"))
    app.config.LOGGING_LEVEL = get_config("LOGGING_LEVEL")
    app.config.SECRET_KEY = get_config("SECRET_KEY")
    app.config.PORT = int(get_config("SERVER_PORT"))
    app.config.TIMEOUT = int(get_config("TIMEOUT"))
    app.config.VALIDATOR = get_config("VALIDATOR")
    app.config.WORKERS = int(get_config("WORKERS"))
예제 #28
0
    def imports(self):
        """ Imports a test user
            Imported user has no key assignment
        """
        signer_keypair = Key()  # TODO: will need to change to a provider key

        message = self.imports_message()

        status = rbac.user.imports.new(
            signer_user_id=message.user_id,
            signer_keypair=signer_keypair,
            message=message,
        )

        assert len(status) == 1
        assert status[0]["status"] == "COMMITTED"

        user = rbac.user.get(object_id=message.user_id)

        assert user.user_id == message.user_id
        assert user.name == message.name
        return user
 def make_with_key(
     self,
     name,
     user_id=None,
     user_name=None,
     email=None,
     metadata=None,
     manager_id=None,
 ):
     """Makes a CreateUser message with a new keypair"""
     keypair = Key()
     if user_id is None:
         user_id = keypair.public_key
     message = self.make(
         user_id=user_id,
         name=name,
         user_name=user_name,
         email=email,
         metadata=metadata,
         manager_id=manager_id,
     )
     return message, keypair
    def assertValidTransactionHeader(
        self,
        header,
        signature,
        message,
        message_type,
        inputs,
        outputs,
        signer_public_key,
    ):
        if isinstance(header, bytes):
            decoded = transaction_pb2.TransactionHeader()
            decoded.ParseFromString(header)
            header = decoded

        payload = self.make_payload(message=message, message_type=message_type)

        self.assertIsInstance(header, transaction_pb2.TransactionHeader)
        self.assertEqual(header.family_name, addresser.FAMILY_NAME)
        self.assertEqual(header.family_version, addresser.FAMILY_VERSION)
        self.assertIsInstance(header.nonce, str)
        self.assertEqual(len(header.nonce), 32)
        self.assertEqual(header.signer_public_key, signer_public_key)
        self.assertEqual(
            header.payload_sha512, sha512(payload.SerializeToString()).hexdigest()
        )

        signer = Key(public_key=signer_public_key)
        self.assertTrue(
            signer.verify(signature=signature, message=header.SerializeToString())
        )
        other_key = Key()
        self.assertFalse(
            other_key.verify(signature=signature, message=header.SerializeToString())
        )

        self.assertEqual(header.inputs, inputs)
        self.assertEqual(header.outputs, outputs)
        self.assertValidInputs(
            inputs=header.inputs,
            outputs=header.outputs,
            message_type=message_type,
            message=message,
        )