use super::enum_validators::{
validate_oauth2_client_auth_method, validate_oauth2_grant_type,
validate_oauth2_request_encoding,
};
use super::one_of_validators::validate_auth_policy_one_of;
use super::{ValidationResult, ValidationRule};
use crate::models::authentication::{
AuthenticationPolicyDefinition, BasicAuthenticationSchemeDefinition,
BearerAuthenticationSchemeDefinition, DigestAuthenticationSchemeDefinition,
OAuth2AuthenticationClientDefinition, OAuth2AuthenticationEndpointsDefinition,
OAuth2AuthenticationRequestDefinition, OAuth2AuthenticationSchemeDefinition,
OpenIDConnectSchemeDefinition,
};
fn validate_credentials_auth(
scheme_name: &str,
use_: &Option<String>,
username: &Option<String>,
password: &Option<String>,
prefix: &str,
result: &mut ValidationResult,
) {
let has_use = use_.as_ref().is_some_and(|s| !s.is_empty());
let has_credentials = username.as_ref().is_some_and(|s| !s.is_empty())
|| password.as_ref().is_some_and(|s| !s.is_empty());
if has_use && has_credentials {
result.add_error(
&format!("{}.{}", prefix, scheme_name),
ValidationRule::MutualExclusion,
&format!(
"{} auth: 'use' and username/password are mutually exclusive",
scheme_name
),
);
}
}
pub fn validate_basic_auth(
basic: &BasicAuthenticationSchemeDefinition,
prefix: &str,
result: &mut ValidationResult,
) {
validate_credentials_auth(
"basic",
&basic.use_,
&basic.username,
&basic.password,
prefix,
result,
);
}
pub fn validate_bearer_auth(
bearer: &BearerAuthenticationSchemeDefinition,
prefix: &str,
result: &mut ValidationResult,
) {
let has_use = bearer.use_.as_ref().is_some_and(|s| !s.is_empty());
let has_token = bearer.token.as_ref().is_some_and(|s| !s.is_empty());
if has_use && has_token {
result.add_error(
&format!("{}.bearer", prefix),
ValidationRule::MutualExclusion,
"bearer auth: 'use' and token are mutually exclusive",
);
}
}
pub fn validate_digest_auth(
digest: &DigestAuthenticationSchemeDefinition,
prefix: &str,
result: &mut ValidationResult,
) {
validate_credentials_auth(
"digest",
&digest.use_,
&digest.username,
&digest.password,
prefix,
result,
);
}
#[allow(clippy::too_many_arguments)]
fn validate_oauth2_like_auth(
scheme_name: &str,
use_: &Option<String>,
authority: &Option<String>,
grant: &Option<String>,
client: &Option<OAuth2AuthenticationClientDefinition>,
endpoints: &Option<OAuth2AuthenticationEndpointsDefinition>,
scopes: &Option<Vec<String>>,
audiences: &Option<Vec<String>>,
issuers: &Option<Vec<String>>,
request: &Option<OAuth2AuthenticationRequestDefinition>,
prefix: &str,
result: &mut ValidationResult,
) {
let has_use = use_.as_ref().is_some_and(|s| !s.is_empty());
let has_properties = authority.as_ref().is_some_and(|s| !s.is_empty())
|| grant.as_ref().is_some_and(|s| !s.is_empty())
|| client.is_some()
|| endpoints.is_some()
|| scopes.is_some()
|| audiences.is_some()
|| issuers.is_some();
if has_use && has_properties {
result.add_error(
&format!("{}.{}", prefix, scheme_name),
ValidationRule::MutualExclusion,
&format!(
"{} auth: 'use' and inline properties are mutually exclusive",
scheme_name
),
);
}
if !has_use && !has_properties {
result.add_error(
&format!("{}.{}", prefix, scheme_name),
ValidationRule::Required,
&format!(
"{} auth: either 'use' or inline properties must be set",
scheme_name
),
);
}
if let Some(ref grant) = grant {
validate_oauth2_grant_type(grant, &format!("{}.{}", prefix, scheme_name), result);
}
if let Some(ref client) = client {
if let Some(ref auth_method) = client.authentication {
validate_oauth2_client_auth_method(
auth_method,
&format!("{}.{}", prefix, scheme_name),
result,
);
}
}
if let Some(ref request) = request {
validate_oauth2_request_encoding(
&request.encoding,
&format!("{}.{}", prefix, scheme_name),
result,
);
}
}
pub fn validate_oauth2_auth(
oauth2: &OAuth2AuthenticationSchemeDefinition,
prefix: &str,
result: &mut ValidationResult,
) {
validate_oauth2_like_auth(
"oauth2",
&oauth2.use_,
&oauth2.authority,
&oauth2.grant,
&oauth2.client,
&oauth2.endpoints,
&oauth2.scopes,
&oauth2.audiences,
&oauth2.issuers,
&oauth2.request,
prefix,
result,
);
}
pub fn validate_oidc_auth(
oidc: &OpenIDConnectSchemeDefinition,
prefix: &str,
result: &mut ValidationResult,
) {
validate_oauth2_like_auth(
"oidc",
&oidc.use_,
&oidc.authority,
&oidc.grant,
&oidc.client,
&None, &oidc.scopes,
&oidc.audiences,
&oidc.issuers,
&oidc.request,
prefix,
result,
);
}
pub fn validate_auth_policy(
policy: &AuthenticationPolicyDefinition,
prefix: &str,
result: &mut ValidationResult,
) {
validate_auth_policy_one_of(policy, prefix, result);
if let Some(ref basic) = policy.basic {
validate_basic_auth(basic, prefix, result);
}
if let Some(ref bearer) = policy.bearer {
validate_bearer_auth(bearer, prefix, result);
}
if let Some(ref digest) = policy.digest {
validate_digest_auth(digest, prefix, result);
}
if let Some(ref oauth2) = policy.oauth2 {
validate_oauth2_auth(oauth2, prefix, result);
}
if let Some(ref oidc) = policy.oidc {
validate_oidc_auth(oidc, prefix, result);
}
}