alien-bindings 3.3.8

Alien direct in-process resource bindings
Documentation
use super::*;

#[tokio::test]
async fn generated_manager_adapter_decodes_cloud_lease_and_structured_error() {
    let response = Arc::new(StdRwLock::new((
        StatusCode::OK,
        json!({
            "service": "s3",
            "binding": { "bucketName": "customer-bucket" },
            "clientConfig": {
                "accountId": "123456789012",
                "region": "us-east-1",
                "credentials": {
                    "type": "sessionCredentials",
                    "accessKeyId": "AKIAEXAMPLE",
                    "secretAccessKey": "secret",
                    "sessionToken": "session",
                    "expiresAt": at(3600).to_rfc3339(),
                },
            },
            "expiresAt": at(3600).to_rfc3339(),
        }),
    )));
    let requests = Arc::new(StdMutex::new(Vec::new()));
    let manager_url = spawn_generated_contract_server(GeneratedContractState {
        response: response.clone(),
        requests: requests.clone(),
    })
    .await;
    let adapter = GeneratedManagerBindingResolver;
    let manager_url = reqwest::Url::parse(&manager_url).expect("valid manager URL");
    let manager = DiscoveredManager {
        url: manager_url,
        http: authenticated_http_client(GENERATED_MANAGER_TOKEN, "generated manager fixture")
            .expect("build generated contract client"),
        refresh_at: at(300),
        generation: 0,
    };

    let lease = adapter
        .resolve(&manager, DEPLOYMENT_ID, "files")
        .await
        .expect("generated client should decode an S3 lease");
    let ResolvedRemoteBinding::S3 {
        binding,
        client_config,
        expires_at,
    } = lease
    else {
        panic!("generated client returned the wrong lease variant for S3");
    };
    assert_eq!(
        binding.bucket_name,
        alien_core::BindingValue::Value("customer-bucket".to_string())
    );
    assert_eq!(client_config.account_id, "123456789012");
    assert_eq!(client_config.region, "us-east-1");
    assert!(client_config.service_overrides.is_none());
    let alien_core::AwsCredentials::SessionCredentials {
        access_key_id,
        secret_access_key,
        session_token,
        expires_at: credential_expires_at,
    } = client_config.credentials
    else {
        panic!("generated client returned a non-session AWS credential");
    };
    assert_eq!(access_key_id, "AKIAEXAMPLE");
    assert_eq!(secret_access_key, "secret");
    assert_eq!(session_token, "session");
    assert_eq!(credential_expires_at, at(3600).to_rfc3339());
    assert_eq!(expires_at, at(3600));
    assert_eq!(
        requests
            .lock()
            .expect("generated contract requests lock")
            .as_slice(),
        &[RecordedRequest {
            method: "POST".to_string(),
            path: "/v1/bindings/resolve".to_string(),
            authorization: Some(format!("Bearer {GENERATED_MANAGER_TOKEN}")),
            body: Some(json!({
                "deploymentId": DEPLOYMENT_ID,
                "resourceId": "files",
            })),
        }]
    );

    *response.write().expect("generated contract response lock") = (
        StatusCode::OK,
        json!({
            "service": "blob",
            "binding": {
                "accountName": "customeraccount",
                "containerName": "customer-container",
            },
            "clientConfig": {
                "subscriptionId": "subscription-id",
                "tenantId": "tenant-id",
                "region": "eastus",
                "credentials": {
                    "type": "accessToken",
                    "token": "azure-storage-token",
                },
            },
            "expiresAt": at(3600).to_rfc3339(),
        }),
    );
    let lease = adapter
        .resolve(&manager, DEPLOYMENT_ID, "files")
        .await
        .expect("generated client should decode a Blob lease");
    let ResolvedRemoteBinding::Blob {
        binding,
        client_config,
        expires_at,
    } = lease
    else {
        panic!("generated client returned the wrong lease variant for Blob");
    };
    assert_eq!(
        binding.account_name,
        alien_core::BindingValue::Value("customeraccount".to_string())
    );
    assert_eq!(
        binding.container_name,
        alien_core::BindingValue::Value("customer-container".to_string())
    );
    assert_eq!(client_config.subscription_id, "subscription-id");
    assert_eq!(client_config.tenant_id, "tenant-id");
    assert_eq!(client_config.region.as_deref(), Some("eastus"));
    assert!(client_config.service_overrides.is_none());
    let alien_core::AzureCredentials::AccessToken { token } = client_config.credentials else {
        panic!("generated client returned the wrong Azure credential type");
    };
    assert_eq!(token, "azure-storage-token");
    assert_eq!(expires_at, at(3600));

    *response.write().expect("generated contract response lock") = (
        StatusCode::OK,
        json!({
            "service": "gcs",
            "binding": { "bucketName": "customer-bucket" },
            "clientConfig": {
                "projectId": "customer-project",
                "projectNumber": "123456789",
                "region": "us-central1",
                "credentials": {
                    "type": "accessToken",
                    "token": "gcp-access-token",
                },
            },
            "expiresAt": at(3600).to_rfc3339(),
        }),
    );
    let lease = adapter
        .resolve(&manager, DEPLOYMENT_ID, "files")
        .await
        .expect("generated client should decode a GCS lease");
    let ResolvedRemoteBinding::Gcs {
        binding,
        client_config,
        expires_at,
    } = lease
    else {
        panic!("generated client returned the wrong lease variant for GCS");
    };
    assert_eq!(
        binding.bucket_name,
        alien_core::BindingValue::Value("customer-bucket".to_string())
    );
    assert_eq!(client_config.project_id, "customer-project");
    assert_eq!(client_config.project_number.as_deref(), Some("123456789"));
    assert_eq!(client_config.region, "us-central1");
    assert!(client_config.service_overrides.is_none());
    let alien_core::GcpCredentials::AccessToken { token } = client_config.credentials else {
        panic!("generated client returned the wrong GCP credential type");
    };
    assert_eq!(token, "gcp-access-token");
    assert_eq!(expires_at, at(3600));

    *response.write().expect("generated contract response lock") = (
        StatusCode::OK,
        json!({
            "service": "s3",
            "binding": { "bucketName": "customer-bucket" },
            "clientConfig": {
                "accountId": "123456789012",
                "region": "us-east-1",
                "credentials": {
                    "type": "sessionCredentials",
                    "accessKeyId": "SENTINEL_ACCESS_KEY",
                    "secretAccessKey": "SENTINEL_SECRET_KEY",
                    "sessionToken": "SENTINEL_SESSION_TOKEN",
                    "expiresAt": at(3600).to_rfc3339(),
                },
            },
            "expiresAt": "not-a-timestamp",
        }),
    );
    let error = match adapter.resolve(&manager, DEPLOYMENT_ID, "files").await {
        Ok(_) => panic!("an invalid lease expiry must fail typed conversion"),
        Err(error) => error,
    };
    let error_debug = format!("{error:?}");
    for secret in [
        "SENTINEL_ACCESS_KEY",
        "SENTINEL_SECRET_KEY",
        "SENTINEL_SESSION_TOKEN",
    ] {
        assert!(
            !error_debug.contains(secret),
            "typed conversion errors must not retain response credentials"
        );
    }

    *response.write().expect("generated contract response lock") = (
        StatusCode::FORBIDDEN,
        json!({
            "code": "FORBIDDEN",
            "message": "Remote access was revoked",
            "retryable": false,
            "internal": false,
            "httpStatusCode": 403,
        }),
    );
    let error = match adapter.resolve(&manager, DEPLOYMENT_ID, "files").await {
        Ok(_) => panic!("generated client should preserve a structured manager error"),
        Err(error) => error,
    };
    assert_eq!(error.code, "FORBIDDEN");
    assert_eq!(error.message, "Remote access was revoked");
    assert!(!error.retryable);
    assert_eq!(error.http_status_code, Some(403));
}