1use super::enum_validators::{
2 validate_oauth2_client_auth_method, validate_oauth2_grant_type,
3 validate_oauth2_request_encoding,
4};
5use super::one_of_validators::validate_auth_policy_one_of;
6use super::{ValidationResult, ValidationRule};
7use crate::models::authentication::{
8 AuthenticationPolicyDefinition, BasicAuthenticationSchemeDefinition,
9 BearerAuthenticationSchemeDefinition, DigestAuthenticationSchemeDefinition,
10 OAuth2AuthenticationClientDefinition, OAuth2AuthenticationEndpointsDefinition,
11 OAuth2AuthenticationRequestDefinition, OAuth2AuthenticationSchemeDefinition,
12 OpenIDConnectSchemeDefinition,
13};
14
15fn validate_credentials_auth(
18 scheme_name: &str,
19 use_: &Option<String>,
20 username: &Option<String>,
21 password: &Option<String>,
22 prefix: &str,
23 result: &mut ValidationResult,
24) {
25 let has_use = use_.as_ref().is_some_and(|s| !s.is_empty());
26 let has_credentials = username.as_ref().is_some_and(|s| !s.is_empty())
27 || password.as_ref().is_some_and(|s| !s.is_empty());
28 if has_use && has_credentials {
29 result.add_error(
30 &format!("{}.{}", prefix, scheme_name),
31 ValidationRule::MutualExclusion,
32 &format!(
33 "{} auth: 'use' and username/password are mutually exclusive",
34 scheme_name
35 ),
36 );
37 }
38}
39
40pub fn validate_basic_auth(
42 basic: &BasicAuthenticationSchemeDefinition,
43 prefix: &str,
44 result: &mut ValidationResult,
45) {
46 validate_credentials_auth(
47 "basic",
48 &basic.use_,
49 &basic.username,
50 &basic.password,
51 prefix,
52 result,
53 );
54}
55
56pub fn validate_bearer_auth(
59 bearer: &BearerAuthenticationSchemeDefinition,
60 prefix: &str,
61 result: &mut ValidationResult,
62) {
63 let has_use = bearer.use_.as_ref().is_some_and(|s| !s.is_empty());
64 let has_token = bearer.token.as_ref().is_some_and(|s| !s.is_empty());
65 if has_use && has_token {
66 result.add_error(
67 &format!("{}.bearer", prefix),
68 ValidationRule::MutualExclusion,
69 "bearer auth: 'use' and token are mutually exclusive",
70 );
71 }
72}
73
74pub fn validate_digest_auth(
76 digest: &DigestAuthenticationSchemeDefinition,
77 prefix: &str,
78 result: &mut ValidationResult,
79) {
80 validate_credentials_auth(
81 "digest",
82 &digest.use_,
83 &digest.username,
84 &digest.password,
85 prefix,
86 result,
87 );
88}
89
90#[allow(clippy::too_many_arguments)]
92fn validate_oauth2_like_auth(
93 scheme_name: &str,
94 use_: &Option<String>,
95 authority: &Option<String>,
96 grant: &Option<String>,
97 client: &Option<OAuth2AuthenticationClientDefinition>,
98 endpoints: &Option<OAuth2AuthenticationEndpointsDefinition>,
99 scopes: &Option<Vec<String>>,
100 audiences: &Option<Vec<String>>,
101 issuers: &Option<Vec<String>>,
102 request: &Option<OAuth2AuthenticationRequestDefinition>,
103 prefix: &str,
104 result: &mut ValidationResult,
105) {
106 let has_use = use_.as_ref().is_some_and(|s| !s.is_empty());
107 let has_properties = authority.as_ref().is_some_and(|s| !s.is_empty())
108 || grant.as_ref().is_some_and(|s| !s.is_empty())
109 || client.is_some()
110 || endpoints.is_some()
111 || scopes.is_some()
112 || audiences.is_some()
113 || issuers.is_some();
114
115 if has_use && has_properties {
116 result.add_error(
117 &format!("{}.{}", prefix, scheme_name),
118 ValidationRule::MutualExclusion,
119 &format!(
120 "{} auth: 'use' and inline properties are mutually exclusive",
121 scheme_name
122 ),
123 );
124 }
125 if !has_use && !has_properties {
126 result.add_error(
127 &format!("{}.{}", prefix, scheme_name),
128 ValidationRule::Required,
129 &format!(
130 "{} auth: either 'use' or inline properties must be set",
131 scheme_name
132 ),
133 );
134 }
135 if let Some(ref grant) = grant {
136 validate_oauth2_grant_type(grant, &format!("{}.{}", prefix, scheme_name), result);
137 }
138 if let Some(ref client) = client {
139 if let Some(ref auth_method) = client.authentication {
140 validate_oauth2_client_auth_method(
141 auth_method,
142 &format!("{}.{}", prefix, scheme_name),
143 result,
144 );
145 }
146 }
147 if let Some(ref request) = request {
148 validate_oauth2_request_encoding(
149 &request.encoding,
150 &format!("{}.{}", prefix, scheme_name),
151 result,
152 );
153 }
154}
155
156pub fn validate_oauth2_auth(
158 oauth2: &OAuth2AuthenticationSchemeDefinition,
159 prefix: &str,
160 result: &mut ValidationResult,
161) {
162 validate_oauth2_like_auth(
163 "oauth2",
164 &oauth2.use_,
165 &oauth2.authority,
166 &oauth2.grant,
167 &oauth2.client,
168 &oauth2.endpoints,
169 &oauth2.scopes,
170 &oauth2.audiences,
171 &oauth2.issuers,
172 &oauth2.request,
173 prefix,
174 result,
175 );
176}
177
178pub fn validate_oidc_auth(
180 oidc: &OpenIDConnectSchemeDefinition,
181 prefix: &str,
182 result: &mut ValidationResult,
183) {
184 validate_oauth2_like_auth(
185 "oidc",
186 &oidc.use_,
187 &oidc.authority,
188 &oidc.grant,
189 &oidc.client,
190 &None, &oidc.scopes,
192 &oidc.audiences,
193 &oidc.issuers,
194 &oidc.request,
195 prefix,
196 result,
197 );
198}
199
200pub fn validate_auth_policy(
202 policy: &AuthenticationPolicyDefinition,
203 prefix: &str,
204 result: &mut ValidationResult,
205) {
206 validate_auth_policy_one_of(policy, prefix, result);
208
209 if let Some(ref basic) = policy.basic {
210 validate_basic_auth(basic, prefix, result);
211 }
212 if let Some(ref bearer) = policy.bearer {
213 validate_bearer_auth(bearer, prefix, result);
214 }
215 if let Some(ref digest) = policy.digest {
216 validate_digest_auth(digest, prefix, result);
217 }
218 if let Some(ref oauth2) = policy.oauth2 {
219 validate_oauth2_auth(oauth2, prefix, result);
220 }
221 if let Some(ref oidc) = policy.oidc {
222 validate_oidc_auth(oidc, prefix, result);
223 }
224}