Repository: influxdata/influxdb
File: influxdb3_server/src/http.rs (Rust)

Code before:
    #[test]
    fn test_basic_auth_token_valid() {
        let token_bytes =
            token_part_as_bytes(
                "PHVzZXJuYW1lPjphcGl2M19Ka2Fsdi1JUEtxSlIyUDdRVDBuMjhnRnBmMWlFd0stZVo3cTZoWHF5enJKdTBrRVBCLVZFODhlR1hUVHo5R0tod0ttMzgtNnFreWtLUGRoTmVkdVM5Zw==")
            .expect("base64 encoded string to be valid");
        let token_string = String::from_utf8_lossy(&token_bytes);
        assert_eq!(
            token_string,
            "apiv3_Jkalv-IPKqJR2P7QT0n28gFpf1iEwK-eZ7q6hXqyzrJu0kEPB-VE88eGXTTz9GKhwKm38-6qkykKPdhNeduS9g"
        );
    }

    #[test]
    fn test_basic_auth_token_invalid() {
        let invalid_token = token_part_as_bytes(
            "YXBpdjNfSmthbHYtSVBLcUpSMlA3UVQwbjI4Z0ZwZjFpRXdLLWVaN3E2aFhxeXpySnUwa0VQQi1WRTg4ZUdYVFR6OUdLaHdLbTM4LTZxa3lrS1BkaE5lZHVTOWc=",
        );
        assert!(matches!(
            invalid_token,
            Err(AuthenticationError::MalformedRequest)
        ));
    }

    #[test]
    fn test_basic_auth_token_allow_colon_in_username() {
        //  echo -n "foo:bar:$TOKEN" | base64 -w 0
        let token_bytes = token_part_as_bytes(
            "Zm9vOmJhcjphcGl2M19Ka2Fsdi1JUEtxSlIyUDdRVDBuMjhnRnBmMWlFd0stZVo3cTZoWHF5enJKdTBrRVBCLVZFODhlR1hUVHo5R0tod0ttMzgtNnFreWtLUGRoTmVkdVM5Zw=="
        ).expect("should be a valid base64 encoded string");
        let token_string = String::from_utf8_lossy(&token_bytes);
        assert_eq!(
            token_string,
            "apiv3_Jkalv-IPKqJR2P7QT0n28gFpf1iEwK-eZ7q6hXqyzrJu0kEPB-VE88eGXTTz9GKhwKm38-6qkykKPdhNeduS9g"
        );
    }

    fn make_record_stream(records: Option<usize>) -> SendableRecordBatchStream {
        match records {
            None => make_record_stream_with_sizes(vec![]),
            Some(num) => make_record_stream_with_sizes(vec![1; num]),
        }
    }

    fn make_record_stream_with_sizes(batch_sizes: Vec<usize>) -> SendableRecordBatchStream {
        let batch = record_batch!(("a", Int32, [1])).unwrap();
        let schema = batch.schema();

        // If there are no sizes, return empty stream
        if batch_sizes.is_empty() {
            let stream = futures::stream::iter(Vec::new());

Review comment (suggestion):
@jdstrand - this test should cover colon (`:`) being in username.

Code after:
            .expect("base64 encoded string to be valid");
        let token_string = String::from_utf8_lossy(&token_bytes);
        assert_eq!(
            token_string,
            "apiv3_Jkalv-IPKqJR2P7QT0n28gFpf1iEwK-eZ7q6hXqyzrJu0kEPB-VE88eGXTTz9GKhwKm38-6qkykKPdhNeduS9g"
        );
    }

    #[test]
    fn test_basic_auth_token_invalid() {
        let invalid_token = token_part_as_bytes(
            "YXBpdjNfSmthbHYtSVBLcUpSMlA3UVQwbjI4Z0ZwZjFpRXdLLWVaN3E2aFhxeXpySnUwa0VQQi1WRTg4ZUdYVFR6OUdLaHdLbTM4LTZxa3lrS1BkaE5lZHVTOWc=",
        );
        assert!(matches!(
            invalid_token,
            Err(AuthenticationError::MalformedRequest)
        ));
    }

    #[test]
    fn test_basic_auth_token_should_not_allow_colon_in_username() {
        //  echo -n "foo:bar:$TOKEN" | base64 -w 0
        let invalid_token = token_part_as_bytes(
            "Zm9vOmJhcjphcGl2M19Ka2Fsdi1JUEtxSlIyUDdRVDBuMjhnRnBmMWlFd0stZVo3cTZoWHF5enJKdTBrRVBCLVZFODhlR1hUVHo5R0tod0ttMzgtNnFreWtLUGRoTmVkdVM5Zw==",
        );
        assert!(matches!(
            invalid_token,
            Err(AuthenticationError::MalformedRequest)
        ));
    }

    fn make_record_stream(records: Option<usize>) -> SendableRecordBatchStream {
        match records {
            None => make_record_stream_with_sizes(vec![]),
            Some(num) => make_record_stream_with_sizes(vec![1; num]),
        }
    }

    fn make_record_stream_with_sizes(batch_sizes: Vec<usize>) -> SendableRecordBatchStream {
        let batch = record_batch!(("a", Int32, [1])).unwrap();
        let schema = batch.schema();

        // If there are no sizes, return empty stream
        if batch_sizes.is_empty() {
            let stream = futures::stream::iter(Vec::new());
            let adapter = RecordBatchStreamAdapter::new(schema, stream);
            return Box::pin(adapter);
        }

        let batches = batch_sizes
            .into_iter()