/// Performs MONGODB-AWS authentication for a given stream.
Performs MONGODB-AWS authentication for a given stream.
Performs MONGODB - AWS authentication for a given stream .
pub(super) async fn authenticate_stream(
    conn: &mut Connection,
    credential: &Credential,
    server_api: Option<&ServerApi>,
    http_client: &HttpClient,
) -> Result<()> {
    let source = match credential.source.as_deref() {
        Some("$external") | None => "$external",
        Some(..) => {
            return Err(Error::authentication_error(
                "MONGODB-AWS",
                "auth source must be $external",
            ))
        }
    };
    let nonce = auth::generate_nonce_bytes();
    let client_first_payload = doc! {
        "r": Binary { subtype: BinarySubtype::Generic, bytes: nonce.clone().to_vec() },
        // `110` is ASCII for the character `n`, which is required by the spec to indicate that
        // channel binding is not supported.
        "p": 110i32,
    };
    let mut client_first_payload_bytes = Vec::new();
    client_first_payload.to_writer(&mut client_first_payload_bytes)?;
    let sasl_start = SaslStart::new(
        source.into(),
        AuthMechanism::MongoDbAws,
        client_first_payload_bytes,
        server_api.cloned(),
    );
    let client_first = sasl_start.into_command();
    let server_first_response = conn.send_command(client_first, None).await?;
    let server_first =
        ServerFirst::parse(server_first_response.auth_response_body("MONGODB-AWS")?)?;
    server_first.validate(&nonce)?;
    let aws_credential = AwsCredential::get(credential, http_client).await?;
    let date = Utc::now();
    let authorization_header = aws_credential.compute_authorization_header(
        date,
        &server_first.sts_host,
        &server_first.server_nonce,
    )?;
    let mut client_second_payload = doc! {
        "a": authorization_header,
        "d": date.format(AWS_LONG_DATE_FMT).to_string(),
    };
    if let Some(security_token) = aws_credential.session_token {
        client_second_payload.insert("t", security_token);
    }
    let mut client_second_payload_bytes = Vec::new();
    client_second_payload.to_writer(&mut client_second_payload_bytes)?;
    let sasl_continue = SaslContinue::new(
        source.into(),
        server_first.conversation_id.clone(),
        client_second_payload_bytes,
        server_api.cloned(),
    );
    let client_second = sasl_continue.into_command();
    let server_second_response = conn.send_command(client_second, None).await?;
    let server_second = SaslResponse::parse(
        "MONGODB-AWS",
        server_second_response.auth_response_body("MONGODB-AWS")?,
    )?;
    if server_second.conversation_id != server_first.conversation_id {
        return Err(Error::invalid_authentication_response("MONGODB-AWS"));
    }
    if !server_second.done {
        return Err(Error::invalid_authentication_response("MONGODB-AWS"));
    }
    Ok(())
}
pub ( super ) async fn authenticate_stream ( conn : & mut Connection , credential : & Credential , server_api : Option < & ServerApi > , http_client : & HttpClient , ) -> Result < ( ) > { let source = match credential . source . as_deref ( ) { Some ( " " ) | None => " " , Some ( .. ) => { return Err ( Error :: authentication_error ( " " , " " , ) ) } } ; let nonce = auth :: generate_nonce_bytes ( ) ; let client_first_payload = doc ! { " " Binary { subtype BinarySubtype Generic bytes nonce clone ( ) to_vec ( ) } // `110` is ASCII for the character `n`, which is required by the spec to indicate that // channel binding is not supported. " " 110i32 } ; let mut client_first_payload_bytes = Vec :: new ( ) ; client_first_payload . to_writer ( & mut client_first_payload_bytes ) ? ; let sasl_start = SaslStart :: new ( source . into ( ) , AuthMechanism :: MongoDbAws , client_first_payload_bytes , server_api . cloned ( ) , ) ; let client_first = sasl_start . into_command ( ) ; let server_first_response = conn . send_command ( client_first , None ) . await ? ; let server_first = ServerFirst :: parse ( server_first_response . auth_response_body ( " " ) ? ) ? ; server_first . validate ( & nonce ) ? ; let aws_credential = AwsCredential :: get ( credential , http_client ) . await ? ; let date = Utc :: now ( ) ; let authorization_header = aws_credential . compute_authorization_header ( date , & server_first . sts_host , & server_first . server_nonce , ) ? ; let mut client_second_payload = doc ! { " " authorization_header " " date format ( AWS_LONG_DATE_FMT ) to_string ( ) } ; if let Some ( security_token ) = aws_credential . session_token { client_second_payload . insert ( " " , security_token ) ; } let mut client_second_payload_bytes = Vec :: new ( ) ; client_second_payload . to_writer ( & mut client_second_payload_bytes ) ? ; let sasl_continue = SaslContinue :: new ( source . into ( ) , server_first . conversation_id . clone ( ) , client_second_payload_bytes , server_api . cloned ( ) , ) ; let client_second = sasl_continue . into_command ( ) ; let server_second_response = conn . send_command ( client_second , None ) . await ? ; let server_second = SaslResponse :: parse ( " " , server_second_response . auth_response_body ( " " ) ? , ) ? ; if server_second . conversation_id != server_first . conversation_id { return Err ( Error :: invalid_authentication_response ( " " ) ) ; } if ! server_second . done { return Err ( Error :: invalid_authentication_response ( " " ) ) ; } Ok ( ( ) ) }
Performs MONGODB-AWS authentication for a given stream.
Performs MONGODB - AWS authentication for a given stream .
conn
&mut Connection
credential
&Credential
server_api
Option<&ServerApi>
http_client
&HttpClient