Exemple #1
0
async def fetch_info_by_username(request):
    username = request.json.get("id")
    conn = request.app.config.DB_CONN
    result = (
        await r.table("auth")
        .get_all(username, index="username")
        .limit(1)
        .coerce_to("array")
        .run(conn)
    )
    if result:
        return result[0]
    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]
    user_key = Key()
    encrypted_private_key = encrypt_private_key(
        request.app.config.AES_KEY, user_key.public_key, user_key.private_key_bytes
    )
    auth_entry = {
        "user_id": result.get("user_id"),
        "username": result.get("username"),
        "email": result.get("email"),
        "encrypted_private_key": encrypted_private_key,
    }
    insert_result = await r.table("auth").insert(auth_entry).run(conn)
    # TODO: execute USER_ADD_KEY message
    return auth_entry
Exemple #2
0
 def test_encrypt_private_key(self):
     """Test that we can encrypt an AES key using a keypair"""
     aes_key = self.test_generate_aes_key()
     user_key = Key()
     next_id = user_key.public_key
     encrypted = encrypt_private_key(aes_key=aes_key,
                                     next_id=next_id,
                                     private_key=user_key.private_key)
     return encrypted, aes_key, user_key, next_id
 def test_encrypt_private_key(self):
     self.assertTrue(callable(encrypt_private_key))
     aes_key = self.test_generate_aes_key()
     user_key = Key()
     user_id = user_key.public_key
     encrypted = encrypt_private_key(aes_key=aes_key,
                                     user_id=user_id,
                                     private_key=user_key.private_key)
     return encrypted, aes_key, user_key, user_id
Exemple #4
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)
Exemple #5
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
Exemple #6
0
async def create_new_user(request):
    required_fields = ["name", "username", "password"]
    utils.validate_fields(required_fields, request.json)

    # Generate keys
    private_key = Secp256k1PrivateKey.new_random()
    txn_key = Key(private_key.as_hex())
    encrypted_private_key = encrypt_private_key(
        request.app.config.AES_KEY, txn_key.public_key, private_key.as_bytes()
    )

    # Build create user transaction
    batch_list = create_user(
        txn_key,
        request.app.config.BATCHER_KEY_PAIR,
        request.json.get("name"),
        request.json.get("username"),
        txn_key.public_key,
        request.json.get("metadata"),
        request.json.get("manager"),
    )

    # Submit transaction and wait for complete
    await utils.send(
        request.app.config.VAL_CONN, batch_list[0], 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_key.public_key,
        "hashed_password": hashed_password,
        "encrypted_private_key": encrypted_private_key,
        "user_name": request.json.get("username"),
        "email": request.json.get("email"),
    }
    await auth_query.create_auth_entry(request.app.config.DB_CONN, auth_entry)

    # Send back success response
    return create_user_response(request, txn_key.public_key)
Exemple #7
0
async def create_new_user(request):
    """Create a new user."""
    required_fields = ["name", "username", "password", "email"]
    utils.validate_fields(required_fields, request.json)
    username_created = request.json.get("username")
    conn = await db_utils.create_connection(
        request.app.config.DB_HOST,
        request.app.config.DB_PORT,
        request.app.config.DB_NAME,
    )
    # Check if username already exists
    if await users_query.fetch_username_match_count(conn,
                                                    username_created) > 0:
        # Throw Error response to Next_UI
        raise ApiBadRequest(
            "Username already exists. Please give a different Username.")
    conn.close()

    # Generate keys
    key_pair = Key()
    next_id = str(uuid4())
    encrypted_private_key = encrypt_private_key(AES_KEY, key_pair.public_key,
                                                key_pair.private_key_bytes)

    # Build create user transaction
    batch_list = User().batch_list(
        signer_keypair=key_pair,
        signer_user_id=next_id,
        next_id=next_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=key_pair.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 = {
        "next_id": next_id,
        "hashed_password": hashed_password,
        "encrypted_private_key": encrypted_private_key,
        "username": request.json.get("username"),
        "email": request.json.get("email"),
    }

    mapping_data = {
        "next_id": next_id,
        "provider_id": None,
        "remote_id": None,
        "public_key": key_pair.public_key,
        "encrypted_key": encrypted_private_key,
        "active": True,
    }

    # Insert to user_mapping and close
    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)
    await users_query.create_user_map_entry(conn, mapping_data)
    conn.close()

    # Send back success response
    return create_user_response(request, next_id)
Exemple #8
0
def add_transaction(inbound_entry):
    """ Adds transactional entries onto inbound_entry
    """
    try:
        set_metadata_flag = {}
        data = inbound_entry["data"]
        key_pair = Key()
        encrypted_private_key = encrypt_private_key(AES_KEY,
                                                    key_pair.public_key,
                                                    key_pair.private_key_bytes)
        inbound_entry["public_key"] = key_pair.public_key
        inbound_entry["private_key"] = encrypted_private_key
        set_metadata_flag["sync_direction"] = "INBOUND"
        data["metadata"] = set_metadata_flag
        data["provider_id"] = inbound_entry["provider_id"]

        if inbound_entry["data_type"] == "user":
            next_user = get_next_object("user_mapping", data["remote_id"],
                                        inbound_entry["provider_id"])
            # Generate Ids
            if next_user:
                next_id = next_user[0]["next_id"]
            else:
                next_id = str(uuid4())
            inbound_entry = add_sawtooth_prereqs(entry_id=next_id,
                                                 inbound_entry=inbound_entry,
                                                 data_type="user")

            message = User().imports.make(signer_keypair=key_pair,
                                          next_id=next_id,
                                          **data)
            batch = User().imports.batch(
                signer_keypair=key_pair,
                signer_user_id=key_pair.public_key,
                message=message,
            )
            inbound_entry["batch"] = batch.SerializeToString()
            add_metadata(inbound_entry, message)

        elif inbound_entry["data_type"] == "group":
            next_role = get_next_object("roles", data["remote_id"],
                                        inbound_entry["provider_id"])
            # Generate Ids
            if next_role:
                next_id = next_role[0]["role_id"]
            else:
                next_id = str(uuid4())

            inbound_entry = add_sawtooth_prereqs(entry_id=next_id,
                                                 inbound_entry=inbound_entry,
                                                 data_type="group")

            message = Role().imports.make(signer_keypair=key_pair,
                                          role_id=next_id,
                                          **data)
            batch = Role().imports.batch(
                signer_keypair=key_pair,
                signer_user_id=key_pair.public_key,
                message=message,
            )
            inbound_entry["batch"] = batch.SerializeToString()
            add_metadata(inbound_entry, message)

        elif inbound_entry["data_type"] == "user_deleted":
            LOGGER.info("User deletion detected in inbound_queue: %s",
                        data["remote_id"])

            # Find user to be deleted
            deleted_user = data["remote_id"]
            conn = connect_to_db()
            user_in_db = (r.table("users").filter({
                "remote_id": deleted_user
            }).coerce_to("array").run(conn))
            conn.close()

            # Process if the user exists
            if user_in_db:
                delete_user_transaction(inbound_entry, user_in_db, key_pair)

        elif inbound_entry["data_type"] == "group_deleted":
            LOGGER.info("Group deletion detected in inbound_queue: %s",
                        data["remote_id"])
            deleted_group = data["remote_id"]
            conn = connect_to_db()
            group_in_db = (r.table("roles").filter({
                "remote_id": deleted_group
            }).coerce_to("array").run(conn))
            if group_in_db:
                role_delete = DeleteRole()
                role_id = group_in_db[0]["role_id"]

                role_relationships = fetch_role_relationships(role_id=role_id,
                                                              conn=conn)
                if role_relationships:
                    data = {**data, **role_relationships}

                inbound_entry = add_sawtooth_prereqs(
                    entry_id=role_id,
                    inbound_entry=inbound_entry,
                    data_type="group")
                message = role_delete.make(signer_keypair=key_pair,
                                           role_id=role_id,
                                           **data)
                batch = role_delete.batch(
                    signer_keypair=key_pair,
                    signer_user_id=key_pair.public_key,
                    message=message,
                )
                inbound_entry["batch"] = batch.SerializeToString()
            conn.close()
    except Exception as err:  # pylint: disable=broad-except
        LOGGER.exception("Unable to create transaction for inbound data:\n%s",
                         inbound_entry)
        LOGGER.exception(err)
Exemple #9
0
async def create_new_user(request):
    """Create a new user. Must be an adminsitrator.

    Args:
        request:
            obj: incoming request object
    """
    log_request(request, True)
    # Validate that we have all fields
    required_fields = ["name", "username", "password", "email"]
    validate_fields(required_fields, request.json)
    # Check if username already exists
    conn = await create_connection()
    username = request.json.get("username")
    if await users_query.fetch_username_match_count(conn, username) > 0:
        # Throw Error response to Next_UI
        return await handle_errors(
            request, ApiTargetConflict("Username already exists."))
    conn.close()

    # Check to see if they are trying to create the NEXT admin
    env = Env()
    next_admin = {
        "name": env("NEXT_ADMIN_NAME"),
        "username": env("NEXT_ADMIN_USER"),
        "email": env("NEXT_ADMIN_EMAIL"),
        "password": env("NEXT_ADMIN_PASS"),
    }
    if request.json != next_admin:
        # Try to see if they are in NEXT
        if not env.int("ENABLE_NEXT_BASE_USE"):
            raise ApiDisabled("Not a valid action. Source not enabled.")
        txn_key, txn_user_id, next_id, key_pair = await non_admin_creation(
            request)
    else:
        txn_key, txn_user_id, next_id, key_pair = await next_admin_creation(
            request)
    if request.json.get("metadata") is None:
        set_metadata = {}
    else:
        set_metadata = request.json.get("metadata")
    set_metadata["sync_direction"] = "OUTBOUND"
    # Build create user transaction
    batch_list = User().batch_list(
        signer_keypair=txn_key,
        signer_user_id=txn_user_id,
        next_id=next_id,
        name=request.json.get("name"),
        username=request.json.get("username"),
        email=request.json.get("email"),
        metadata=set_metadata,
        manager_id=request.json.get("manager"),
        key=key_pair.public_key,
    )

    # Submit transaction and wait for complete
    sawtooth_response = await send(request.app.config.VAL_CONN, batch_list,
                                   request.app.config.TIMEOUT)
    if not sawtooth_response:
        return await handle_errors(
            request,
            ApiInternalError(
                "There was an error submitting the sawtooth transaction."),
        )

    # Save new user in auth table
    salt = hashlib.sha256(os.urandom(60)).hexdigest().encode("utf-8")
    password = request.json.get("password").encode("utf-8")
    hashed_password = hashlib.pbkdf2_hmac("sha256", password, salt,
                                          100000).hex()

    encrypted_private_key = encrypt_private_key(AES_KEY, key_pair.public_key,
                                                key_pair.private_key_bytes)
    auth_entry = {
        "next_id": next_id,
        "salt": salt,
        "hashed_password": hashed_password,
        "encrypted_private_key": encrypted_private_key,
        "username": request.json.get("username"),
        "email": request.json.get("email"),
    }

    mapping_data = {
        "next_id": next_id,
        "provider_id": "NEXT-created",
        "remote_id": None,
        "public_key": key_pair.public_key,
        "encrypted_key": encrypted_private_key,
        "active": True,
    }

    # Insert to user_mapping and close
    await auth_query.create_auth_entry(auth_entry)
    conn = await create_connection()
    await users_query.create_user_map_entry(conn, mapping_data)
    conn.close()

    # Send back success response
    return json({"data": {"user": {"id": next_id}}})
Exemple #10
0
async def create_new_user(request):
    """Create a new user."""
    env = Env()
    admin_role = {
        "name": env("NEXT_ADMIN_NAME"),
        "username": env("NEXT_ADMIN_USER"),
        "email": env("NEXT_ADMIN_EMAIL"),
        "password": env("NEXT_ADMIN_PASS"),
    }
    if request.json != admin_role:
        if not env.int("ENABLE_NEXT_BASE_USE"):
            raise ApiBadRequest("Not a valid action. Source not enabled")
    required_fields = ["name", "username", "password", "email"]
    utils.validate_fields(required_fields, request.json)
    username_created = request.json.get("username")
    conn = await create_connection()
    # Check if username already exists
    if await users_query.fetch_username_match_count(conn,
                                                    username_created) > 0:
        # Throw Error response to Next_UI
        raise ApiBadRequest(
            "Username already exists. Please give a different Username.")
    conn.close()

    # Generate keys
    key_pair = Key()
    next_id = str(uuid4())
    encrypted_private_key = encrypt_private_key(AES_KEY, key_pair.public_key,
                                                key_pair.private_key_bytes)
    if request.json.get("metadata") is None or request.json.get(
            "metadata") == {}:
        set_metadata = {}
    else:
        set_metadata = request.json.get("metadata")
    set_metadata["sync_direction"] = "OUTBOUND"

    # Build create user transaction
    batch_list = User().batch_list(
        signer_keypair=key_pair,
        signer_user_id=next_id,
        next_id=next_id,
        name=request.json.get("name"),
        username=request.json.get("username"),
        email=request.json.get("email"),
        metadata=set_metadata,
        manager_id=request.json.get("manager"),
        key=key_pair.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 = {
        "next_id": next_id,
        "hashed_password": hashed_password,
        "encrypted_private_key": encrypted_private_key,
        "username": request.json.get("username"),
        "email": request.json.get("email"),
    }

    mapping_data = {
        "next_id": next_id,
        "provider_id": None,
        "remote_id": None,
        "public_key": key_pair.public_key,
        "encrypted_key": encrypted_private_key,
        "active": True,
    }

    # Insert to user_mapping and close
    conn = await create_connection()
    await auth_query.create_auth_entry(auth_entry)
    await users_query.create_user_map_entry(conn, mapping_data)
    conn.close()

    # Send back success response
    return create_user_response(request, next_id)
def add_transaction(inbound_entry):
    """ Adds transactional entries onto inbound_entry
    """
    try:
        data = inbound_entry["data"]
        key_pair = Key()
        encrypted_private_key = encrypt_private_key(AES_KEY,
                                                    key_pair.public_key,
                                                    key_pair.private_key_bytes)
        inbound_entry["public_key"] = key_pair.public_key
        inbound_entry["private_key"] = encrypted_private_key

        if inbound_entry["data_type"] == "user":
            next_user = get_next_id("user_mapping", data["remote_id"],
                                    inbound_entry["provider_id"])
            # Generate Ids
            if next_user:
                next_id = next_user[0]["next_id"]
            else:
                next_id = str(uuid4())

            object_id = User().hash(next_id)
            address = User().address(object_id=object_id)

            inbound_entry["next_id"] = next_id
            inbound_entry["address"] = bytes_from_hex(address)
            inbound_entry["object_id"] = bytes_from_hex(object_id)
            inbound_entry["object_type"] = addresser.ObjectType.USER.value
            message = User().imports.make(signer_keypair=key_pair,
                                          next_id=next_id,
                                          **data)
            batch = User().imports.batch(
                signer_keypair=key_pair,
                signer_user_id=key_pair.public_key,
                message=message,
            )
            inbound_entry["batch"] = batch.SerializeToString()
            add_metadata(inbound_entry, message)

        elif inbound_entry["data_type"] == "group":
            next_id = str(uuid4())
            object_id = Role().hash(next_id)
            address = Role().address(object_id=object_id)

            inbound_entry["address"] = bytes_from_hex(address)
            inbound_entry["object_id"] = bytes_from_hex(object_id)
            inbound_entry["object_type"] = addresser.ObjectType.ROLE.value

            message = Role().imports.make(signer_keypair=key_pair,
                                          role_id=next_id,
                                          **data)
            batch = Role().imports.batch(
                signer_keypair=key_pair,
                signer_user_id=key_pair.public_key,
                message=message,
            )
            inbound_entry["batch"] = batch.SerializeToString()
            add_metadata(inbound_entry, message)

    except Exception as err:  # pylint: disable=broad-except
        LOGGER.exception("Unable to create transaction for inbound data:\n%s",
                         inbound_entry)
        LOGGER.exception(err)