summaryrefslogtreecommitdiff
path: root/src/domain/specifications.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/domain/specifications.rs')
-rw-r--r--src/domain/specifications.rs40
1 files changed, 24 insertions, 16 deletions
diff --git a/src/domain/specifications.rs b/src/domain/specifications.rs
index 3237d1b..76aafcc 100644
--- a/src/domain/specifications.rs
+++ b/src/domain/specifications.rs
@@ -22,7 +22,7 @@ impl<T> Specification<T> for AndSpecification<T> {
fn is_satisfied_by(&self, candidate: &T) -> bool {
self.left.is_satisfied_by(candidate) && self.right.is_satisfied_by(candidate)
}
-
+
fn reason_for_failure(&self, candidate: &T) -> Option<String> {
if !self.left.is_satisfied_by(candidate) {
self.left.reason_for_failure(candidate)
@@ -40,7 +40,7 @@ impl Specification<OAuthClient> for ActiveClientSpecification {
fn is_satisfied_by(&self, client: &OAuthClient) -> bool {
client.is_active
}
-
+
fn reason_for_failure(&self, _client: &OAuthClient) -> Option<String> {
Some("Client is not active".to_string())
}
@@ -60,7 +60,7 @@ impl Specification<OAuthClient> for ValidRedirectUriSpecification {
fn is_satisfied_by(&self, client: &OAuthClient) -> bool {
client.redirect_uris.contains(&self.redirect_uri)
}
-
+
fn reason_for_failure(&self, _client: &OAuthClient) -> Option<String> {
Some(format!("Invalid redirect_uri: {}", self.redirect_uri))
}
@@ -78,15 +78,19 @@ impl SupportedScopesSpecification {
impl Specification<OAuthClient> for SupportedScopesSpecification {
fn is_satisfied_by(&self, client: &OAuthClient) -> bool {
- self.requested_scopes.iter().all(|scope| client.scopes.contains(scope))
+ self.requested_scopes
+ .iter()
+ .all(|scope| client.scopes.contains(scope))
}
-
+
fn reason_for_failure(&self, client: &OAuthClient) -> Option<String> {
- let unsupported: Vec<_> = self.requested_scopes.iter()
+ let unsupported: Vec<_> = self
+ .requested_scopes
+ .iter()
.filter(|scope| !client.scopes.contains(scope))
.cloned()
.collect();
-
+
if !unsupported.is_empty() {
Some(format!("Unsupported scopes: {}", unsupported.join(", ")))
} else {
@@ -101,7 +105,7 @@ impl Specification<AuthorizationCode> for UnusedAuthCodeSpecification {
fn is_satisfied_by(&self, code: &AuthorizationCode) -> bool {
!code.is_used
}
-
+
fn reason_for_failure(&self, _code: &AuthorizationCode) -> Option<String> {
Some("Authorization code has already been used".to_string())
}
@@ -112,7 +116,7 @@ impl Specification<AuthorizationCode> for ValidAuthCodeSpecification {
fn is_satisfied_by(&self, code: &AuthorizationCode) -> bool {
chrono::Utc::now() < code.expires_at
}
-
+
fn reason_for_failure(&self, _code: &AuthorizationCode) -> Option<String> {
Some("Authorization code has expired".to_string())
}
@@ -132,7 +136,7 @@ impl Specification<AuthorizationCode> for MatchingClientSpecification {
fn is_satisfied_by(&self, code: &AuthorizationCode) -> bool {
code.client_id == self.client_id
}
-
+
fn reason_for_failure(&self, _code: &AuthorizationCode) -> Option<String> {
Some("Client ID mismatch".to_string())
}
@@ -153,14 +157,18 @@ impl Specification<AuthorizationCode> for ValidPkceSpecification {
fn is_satisfied_by(&self, code: &AuthorizationCode) -> bool {
if let Some(challenge) = &code.code_challenge {
let method = code.code_challenge_method.as_deref().unwrap_or("plain");
- crate::oauth::pkce::verify_code_challenge(&self.code_verifier, challenge,
- &crate::oauth::pkce::CodeChallengeMethod::from_str(method).unwrap_or(crate::oauth::pkce::CodeChallengeMethod::Plain)
- ).is_ok()
+ crate::oauth::pkce::verify_code_challenge(
+ &self.code_verifier,
+ challenge,
+ &crate::oauth::pkce::CodeChallengeMethod::from_str(method)
+ .unwrap_or(crate::oauth::pkce::CodeChallengeMethod::Plain),
+ )
+ .is_ok()
} else {
true // No PKCE required
}
}
-
+
fn reason_for_failure(&self, _code: &AuthorizationCode) -> Option<String> {
Some("PKCE verification failed".to_string())
}
@@ -172,7 +180,7 @@ impl Specification<AccessToken> for ValidTokenSpecification {
fn is_satisfied_by(&self, token: &AccessToken) -> bool {
!token.is_revoked && chrono::Utc::now() < token.expires_at
}
-
+
fn reason_for_failure(&self, token: &AccessToken) -> Option<String> {
if token.is_revoked {
Some("Token has been revoked".to_string())
@@ -191,4 +199,4 @@ pub trait SpecificationExt<T>: Specification<T> + Sized + 'static {
}
}
-impl<T, S: Specification<T> + 'static> SpecificationExt<T> for S {} \ No newline at end of file
+impl<T, S: Specification<T> + 'static> SpecificationExt<T> for S {}