From 31f80998a8eef32c0ef2d309bee68ab88f453bab Mon Sep 17 00:00:00 2001 From: mrw1593 Date: Thu, 22 Jun 2023 20:36:06 -0400 Subject: Implement the password grant --- src/models/client.rs | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'src/models') diff --git a/src/models/client.rs b/src/models/client.rs index 90c5902..56b0ae6 100644 --- a/src/models/client.rs +++ b/src/models/client.rs @@ -36,6 +36,7 @@ pub struct Client { allowed_scopes: Box<[Box]>, default_scopes: Option]>>, redirect_uris: Box<[Url]>, + trusted: bool, } impl PartialEq for Client { @@ -54,24 +55,19 @@ impl Hash for Client { #[derive(Debug, Clone, Copy, Error)] #[error("Confidential clients must have a secret, but it was not provided")] -pub struct NoSecretError { - _phantom: PhantomData<()>, +pub enum CreateClientError { + #[error("Confidential clients must have a secret, but it was not provided")] + NoSecret, + #[error("Only confidential clients may be trusted")] + TrustedError, } -impl ResponseError for NoSecretError { +impl ResponseError for CreateClientError { fn status_code(&self) -> StatusCode { StatusCode::BAD_REQUEST } } -impl NoSecretError { - pub(crate) fn new() -> Self { - Self { - _phantom: PhantomData, - } - } -} - impl Client { pub fn new( id: Uuid, @@ -81,7 +77,8 @@ impl Client { allowed_scopes: Box<[Box]>, default_scopes: Option]>>, redirect_uris: &[Url], - ) -> Result> { + trusted: bool, + ) -> Result> { let secret = if let Some(secret) = secret { Some(PasswordHash::new(secret)?) } else { @@ -89,17 +86,22 @@ impl Client { }; if ty == ClientType::Confidential && secret.is_none() { - yeet!(NoSecretError::new().into()); + yeet!(CreateClientError::NoSecret.into()); + } + + if ty == ClientType::Public && trusted { + yeet!(CreateClientError::TrustedError.into()); } Ok(Self { id, alias: Box::from(alias), - ty: ClientType::Public, + ty, secret, allowed_scopes, default_scopes, redirect_uris: redirect_uris.into_iter().cloned().collect(), + trusted, }) } @@ -139,6 +141,10 @@ impl Client { self.default_scopes.clone().map(|s| s.join(" ")) } + pub fn is_trusted(&self) -> bool { + self.trusted + } + pub fn check_secret(&self, secret: &str) -> Option> { self.secret.as_ref().map(|s| s.check_password(secret)) } -- cgit v1.2.3