Skip to content

Commit

Permalink
Pushed Authorization Request support (#12)
Browse files Browse the repository at this point in the history
* Pushed authorization changes

* Suggestions

* Suggestions

* Suggestions

* Suggestions

* Lint suggestions
  • Loading branch information
Juliano1612 authored Dec 21, 2023
1 parent 8e4bd58 commit 12e8999
Show file tree
Hide file tree
Showing 8 changed files with 378 additions and 2 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ url = { version = "2.3.1", features = ["serde"] }
openidconnect = "3.3.1"
oauth2 = "4.4.2"
async-signature = "0.3.0"
rand = "0.8.5"
time = { version = "0.3.29", features = ["serde"] }
thiserror = "1.0.49"
base64 = "0.21.4"
serde_urlencoded = "0.7.1"

[dev-dependencies]
assert-json-diff = "2.0.2"
did-jwk = "0.1.0"
tokio = { version = "1.25.0", features = ["macros"] }
1 change: 1 addition & 0 deletions src/authorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ mod test {
IssuerUrl::new("https://server.example.com".into()).unwrap(),
CredentialUrl::new("https://server.example.com/credential".into()).unwrap(),
AuthUrl::new("https://server.example.com/authorize".into()).unwrap(),
None,
TokenUrl::new("https://server.example.com/token".into()).unwrap(),
RedirectUrl::new("https://client.example.org/cb".into()).unwrap(),
);
Expand Down
38 changes: 37 additions & 1 deletion src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,17 @@ use crate::{
IssuerMetadataDisplay,
},
profiles::{AuthorizationDetaislProfile, Profile},
pushed_authorization::PushedAuthorizationRequest,
token,
types::{BatchCredentialUrl, DeferredCredentialUrl},
types::{BatchCredentialUrl, DeferredCredentialUrl, ParUrl},
};

#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Pushed authorization request is not supported")]
ParUnsupported(),
}

pub struct Client<C, JT, JE, JA>
where
C: Profile,
Expand All @@ -46,6 +53,7 @@ where
>,
issuer: IssuerUrl,
credential_endpoint: CredentialUrl,
par_auth_url: Option<ParUrl>,
batch_credential_endpoint: Option<BatchCredentialUrl>,
deferred_credential_endpoint: Option<DeferredCredentialUrl>,
credential_response_encryption_alg_values_supported: Option<Vec<JA>>,
Expand All @@ -68,6 +76,7 @@ where
issuer: IssuerUrl,
credential_endpoint: CredentialUrl,
auth_url: AuthUrl,
par_auth_url: Option<ParUrl>,
token_url: TokenUrl,
redirect_uri: RedirectUrl,
) -> Self {
Expand All @@ -77,6 +86,7 @@ where
inner,
issuer,
credential_endpoint,
par_auth_url,
batch_credential_endpoint: None,
deferred_credential_endpoint: None,
credential_response_encryption_alg_values_supported: None,
Expand Down Expand Up @@ -113,6 +123,9 @@ where
issuer_metadata.credential_issuer().clone(),
issuer_metadata.credential_endpoint().clone(),
authorization_metadata.authorization_endpoint().clone(),
authorization_metadata
.pushed_authorization_endpoint()
.clone(),
authorization_metadata.token_endpoint().clone(),
redirect_uri,
)
Expand All @@ -135,6 +148,29 @@ where
.set_display(issuer_metadata.display().cloned())
}

pub fn pushed_authorization_request<S, AD>(
&self,
state_fn: S,
) -> Result<PushedAuthorizationRequest<AD>, Error>
where
S: FnOnce() -> CsrfToken,
AD: AuthorizationDetaislProfile,
{
if self.par_auth_url.is_none() {
return Err(Error::ParUnsupported());
}
let inner = self.inner.authorize_url(state_fn);
Ok(PushedAuthorizationRequest::new(
inner,
self.par_auth_url.clone().unwrap(),
self.inner.auth_url().clone(),
vec![],
None,
None,
None,
))
}

pub fn authorize_url<S, AD>(&self, state_fn: S) -> AuthorizationRequest<AD>
where
S: FnOnce() -> CsrfToken,
Expand Down
1 change: 1 addition & 0 deletions src/http_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use oauth2::{
};

pub const MIME_TYPE_JSON: &str = "application/json";
pub const MIME_TYPE_FORM_URLENCODED: &str = "application/x-www-form-urlencoded";

pub const BEARER: &str = "Bearer";

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod http_utils;
pub mod metadata;
pub mod profiles;
pub mod proof_of_possession;
pub mod pushed_authorization;
pub mod token;
mod types;

Expand Down
30 changes: 29 additions & 1 deletion src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::{
proof_of_possession::KeyProofType,
};

pub use crate::types::{BatchCredentialUrl, CredentialUrl, DeferredCredentialUrl};
pub use crate::types::{BatchCredentialUrl, CredentialUrl, DeferredCredentialUrl, ParUrl};

const METADATA_URL_SUFFIX: &str = ".well-known/openid-credential-issuer";
const AUTHORIZATION_METADATA_URL_SUFFIX: &str = ".well-known/oauth-authorization-server";
Expand Down Expand Up @@ -279,7 +279,28 @@ pub struct CredentialMetadataDisplayLogo {
pub struct AdditionalOAuthMetadata {
#[serde(rename = "pre-authorized_grant_anonymous_access_supported")]
pre_authorized_grant_anonymous_access_supported: Option<bool>,
pushed_authorization_request_endpoint: Option<ParUrl>,
require_pushed_authorization_requests: Option<bool>,
}

impl AdditionalOAuthMetadata {
pub fn set_pushed_authorization_request_endpoint(
mut self,
pushed_authorization_request_endpoint: Option<ParUrl>,
) -> Self {
self.pushed_authorization_request_endpoint = pushed_authorization_request_endpoint;
self
}

pub fn set_require_pushed_authorization_requests(
mut self,
require_pushed_authorization_requests: Option<bool>,
) -> Self {
self.require_pushed_authorization_requests = require_pushed_authorization_requests;
self
}
}

impl AdditionalProviderMetadata for AdditionalOAuthMetadata {}

#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
Expand Down Expand Up @@ -434,6 +455,13 @@ impl AuthorizationMetadata {
self.0.authorization_endpoint()
}

pub fn pushed_authorization_endpoint(&self) -> Option<ParUrl> {
self.0
.additional_metadata()
.clone()
.pushed_authorization_request_endpoint
}

pub fn token_endpoint(&self) -> &TokenUrl {
// TODO find better way to avoid unwrap
self.0.token_endpoint().unwrap()
Expand Down
Loading

0 comments on commit 12e8999

Please sign in to comment.