#![cfg(feature = "hyper")]
use std::sync::Arc;
use authentic::credential::UsernamePasswordCredential;
use authentic::hyper::BasicAuthentication;
use authentic::{AuthenticationProtocol, AuthenticationStep, WithAuthentication};
use http::StatusCode;
use hyper::Client;
use hyper_tls::HttpsConnector;
#[::tokio::test]
async fn test_basic_authentication(
) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
let https = HttpsConnector::new();
let client = Client::builder().build::<_, ::hyper::Body>(https);
let credential = Arc::new(UsernamePasswordCredential::new("username", "password"));
let mut authentication = BasicAuthentication::new(credential);
while let Some(auth_step) = authentication.step()? {
match auth_step {
AuthenticationStep::Request(request) => {
let auth_response = client.request(request).await;
authentication.respond(auth_response);
}
AuthenticationStep::WaitFor(duration) => {
::tokio::time::sleep(duration).await;
}
}
}
let request = ::hyper::Request::get("https://httpbin.org/basic-auth/username/password")
.with_authentication(&authentication)?
.body(::hyper::Body::empty())?;
dbg!(&request);
let response = client.request(request).await?;
dbg!(&response);
assert!(authentication.has_completed(&response)?);
assert_eq!(response.status(), StatusCode::OK);
Ok(())
}
#[::tokio::test]
async fn test_basic_authentication_loop(
) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
let https = HttpsConnector::new();
let client = Client::builder().build::<_, ::hyper::Body>(https);
let credential = Arc::new(UsernamePasswordCredential::new("username", "password"));
let mut authentication = BasicAuthentication::new(credential);
let mut status_codes = Vec::new();
let _response = loop {
while let Some(auth_step) = authentication.step()? {
match auth_step {
AuthenticationStep::Request(request) => {
let auth_response = client.request(request).await;
authentication.respond(auth_response);
}
AuthenticationStep::WaitFor(duration) => {
::tokio::time::sleep(duration).await;
}
}
}
let request = ::hyper::Request::get("https://httpbin.org/basic-auth/username/password")
.with_authentication(&authentication)?
.body(::hyper::Body::empty())?;
dbg!(&request);
let response = client.request(request).await?;
dbg!(&response);
status_codes.push(response.status());
if authentication.has_completed(&response)? {
break response;
}
};
assert_eq!(status_codes, [StatusCode::OK]);
Ok(())
}
#[cfg(feature = "loop")]
#[::tokio::test]
async fn test_basic_challenge() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
let https = HttpsConnector::new();
let client = Client::builder().build::<_, ::hyper::Body>(https);
let mut realm_credentials = std::collections::HashMap::new();
realm_credentials.insert(
"Fake Realm".into(),
Arc::new(UsernamePasswordCredential::new("username", "password")),
);
let credential = Arc::new(authentic::credential::HttpRealmCredentials::new(
realm_credentials,
));
let mut authentication = authentic::hyper::HttpAuthentication::new(credential);
let mut status_codes = Vec::new();
let _response = loop {
while let Some(auth_step) = authentication.step()? {
match auth_step {
AuthenticationStep::Request(request) => {
let auth_response = client.request(request).await;
authentication.respond(auth_response);
}
AuthenticationStep::WaitFor(duration) => {
::tokio::time::sleep(duration).await;
}
}
}
let request = ::hyper::Request::get("https://httpbin.org/basic-auth/username/password")
.with_authentication(&authentication)?
.body(::hyper::Body::empty())?;
dbg!(&request);
let response = client.request(request).await?;
dbg!(&response);
status_codes.push(response.status());
if authentication.has_completed(&response)? {
break response;
}
};
assert_eq!(status_codes, [StatusCode::UNAUTHORIZED, StatusCode::OK]);
Ok(())
}