use crate::{
common::{
frontend::{OAuthError, OAuthValidationError},
model::{Client, CodeChallenge, Grant},
},
test::{
TestEnvironment, DEFAULT_AUTHORIZATION_CODE, DEFAULT_CLIENT_SECRET, DEFAULT_CODE_VERIFIER,
DEFAULT_REDIRECT_URI,
},
token::{RequestedGrantType, TokenRequest},
};
#[tokio::test]
async fn test_only_accept_code_challenge_if_originally_present() {
let mut test = TestEnvironment::new();
test.register_client(
Client { confidential: true, ..Default::default() },
DEFAULT_CLIENT_SECRET.to_string(),
);
test.register_grant(
DEFAULT_AUTHORIZATION_CODE.to_string(),
Grant { code_challenge: CodeChallenge::None, ..Default::default() },
);
let manager = test.build();
let request = TokenRequest {
grant_type: RequestedGrantType::AuthorizationCode {
code: DEFAULT_AUTHORIZATION_CODE.to_string(),
code_verifier: DEFAULT_CODE_VERIFIER.to_string(),
},
..Default::default()
};
let result = manager.validate_token_request(request).await;
assert!(result.is_err(), "result is not Err, result is {:?}", result);
assert_eq!(
OAuthError::ValidationFailed(OAuthValidationError::InvalidCodeVerifier),
result.unwrap_err()
);
}
#[tokio::test]
async fn test_client_credentials_only_allowed_by_confidential_clients() {
let mut test = TestEnvironment::new();
test.register_client(
Client {
client_id: "confidential_client".to_string(),
confidential: true,
..Default::default()
},
DEFAULT_CLIENT_SECRET.to_string(),
);
test.register_client(
Client {
client_id: "regular_client".to_string(),
confidential: false,
..Default::default()
},
DEFAULT_CLIENT_SECRET.to_string(),
);
let manager = test.build();
let confidential_request = TokenRequest {
client_id: "confidential_client".to_string(),
grant_type: RequestedGrantType::ClientCredentials,
..Default::default()
};
let regular_request = TokenRequest {
client_id: "regular_client".to_string(),
grant_type: RequestedGrantType::ClientCredentials,
..Default::default()
};
let confidential_result = manager.validate_token_request(confidential_request).await;
let regular_result = manager.validate_token_request(regular_request).await;
assert!(confidential_result.is_ok(), "result is not Ok, result is {:?}", confidential_result);
assert!(regular_result.is_err(), "result is not Err, result is {:?}", regular_result);
assert_eq!(
OAuthError::ValidationFailed(OAuthValidationError::ClientNotAllowedToUseGrantType {
requested: "client_credentials"
}),
regular_result.unwrap_err()
);
}
#[tokio::test]
async fn test_authorization_code_belongs_to_authorized_client() {
let mut test = TestEnvironment::new();
test.default_client();
test.register_client(
Client { client_id: "bad_client".to_string(), ..Default::default() },
DEFAULT_CLIENT_SECRET.to_string(),
);
test.default_grant();
let manager = test.build();
let request = TokenRequest { client_id: "bad_client".to_string(), ..Default::default() };
let result = manager.validate_token_request(request).await;
assert!(result.is_err(), "result is not Err, result is {:?}", result);
assert_eq!(
OAuthError::ValidationFailed(OAuthValidationError::AuthorizationCodeClientMismatch),
result.unwrap_err()
);
}
#[tokio::test]
async fn test_token_request_that_includes_redirect_uri_should_have_it_validated() {
let mut test = TestEnvironment::new();
test.default_client();
test.default_grant();
let manager = test.build();
let request = TokenRequest {
redirect_uri: Some("https://example.com/wrong_uri".to_string()),
..Default::default()
};
let result = manager.validate_token_request(request).await;
assert!(result.is_err(), "result is not Err, result is {:?}", result);
assert_eq!(
OAuthError::ValidationFailed(OAuthValidationError::UnknownRedirectUri),
result.unwrap_err()
);
}
#[tokio::test]
async fn test_token_request_that_includes_redirect_uri_should_be_the_same_as_the_original() {
let mut test = TestEnvironment::new();
test.register_client(
Client {
redirect_uris: vec![
DEFAULT_REDIRECT_URI.to_string(),
"https://example.com/another".to_string(),
],
..Default::default()
},
DEFAULT_CLIENT_SECRET.to_string(),
);
test.default_grant(); let manager = test.build();
let request = TokenRequest {
redirect_uri: Some("https://example.com/another".to_string()),
..Default::default()
};
let result = manager.validate_token_request(request).await;
assert!(result.is_err(), "result is not Err, result is {:?}", result);
assert_eq!(
OAuthError::ValidationFailed(OAuthValidationError::InvalidRedirectUri),
result.unwrap_err()
);
}