mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 12:37:00 +01:00
OAuth2 scopes validation logging missing details (#2317)
* OAuth2 scopes validation logging missing details - Fixes #2316 * clippy was mad
This commit is contained in:
parent
545c04e74f
commit
2be287c1ff
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -37,3 +37,4 @@ pykanidm/site/
|
||||||
# oauth2 integration test things
|
# oauth2 integration test things
|
||||||
scripts/oauth_proxy/client.secret
|
scripts/oauth_proxy/client.secret
|
||||||
scripts/oauth_proxy/envfile
|
scripts/oauth_proxy/envfile
|
||||||
|
.envrc
|
||||||
|
|
|
@ -93,9 +93,9 @@ enum CredentialState {
|
||||||
// Disabled,
|
// Disabled,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<CUCredState> for CredentialState {
|
impl From<CredentialState> for CUCredState {
|
||||||
fn into(self) -> CUCredState {
|
fn from(val: CredentialState) -> CUCredState {
|
||||||
match self {
|
match val {
|
||||||
CredentialState::Modifiable => CUCredState::Modifiable,
|
CredentialState::Modifiable => CUCredState::Modifiable,
|
||||||
CredentialState::AccessDeny => CUCredState::AccessDeny,
|
CredentialState::AccessDeny => CUCredState::AccessDeny,
|
||||||
CredentialState::PolicyDeny => CUCredState::PolicyDeny,
|
CredentialState::PolicyDeny => CUCredState::PolicyDeny,
|
||||||
|
@ -242,9 +242,9 @@ pub enum CredentialUpdateSessionStatusWarnings {
|
||||||
Unsatisfiable,
|
Unsatisfiable,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<CURegWarning> for CredentialUpdateSessionStatusWarnings {
|
impl From<CredentialUpdateSessionStatusWarnings> for CURegWarning {
|
||||||
fn into(self) -> CURegWarning {
|
fn from(val: CredentialUpdateSessionStatusWarnings) -> CURegWarning {
|
||||||
match self {
|
match val {
|
||||||
CredentialUpdateSessionStatusWarnings::MfaRequired => CURegWarning::MfaRequired,
|
CredentialUpdateSessionStatusWarnings::MfaRequired => CURegWarning::MfaRequired,
|
||||||
CredentialUpdateSessionStatusWarnings::PasskeyRequired => CURegWarning::PasskeyRequired,
|
CredentialUpdateSessionStatusWarnings::PasskeyRequired => CURegWarning::PasskeyRequired,
|
||||||
CredentialUpdateSessionStatusWarnings::Unsatisfiable => CURegWarning::Unsatisfiable,
|
CredentialUpdateSessionStatusWarnings::Unsatisfiable => CURegWarning::Unsatisfiable,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
//! Oauth2 resource server configurations
|
//! Oauth2 resource server configurations
|
||||||
//!
|
//!
|
||||||
//! This contains the in memory and loaded set of active oauth2 resource server
|
//! This contains the in memory and loaded set of active OAuth2 resource server
|
||||||
//! integrations, which are then able to be used an accessed from the IDM layer
|
//! integrations, which are then able to be used an accessed from the IDM layer
|
||||||
//! for operations involving oauth2 authentication processing.
|
//! for operations involving OAuth2 authentication processing.
|
||||||
|
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
@ -319,8 +319,8 @@ impl<'a> Oauth2ResourceServersWriteTransaction<'a> {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|ent| {
|
.map(|ent| {
|
||||||
let uuid = ent.get_uuid();
|
let uuid = ent.get_uuid();
|
||||||
trace!(?uuid, "Checking oauth2 configuration");
|
trace!(?uuid, "Checking OAuth2 configuration");
|
||||||
// From each entry, attempt to make an oauth2 configuration.
|
// From each entry, attempt to make an OAuth2 configuration.
|
||||||
if !ent.attribute_equality(Attribute::Class, &EntryClass::OAuth2ResourceServer.into()) {
|
if !ent.attribute_equality(Attribute::Class, &EntryClass::OAuth2ResourceServer.into()) {
|
||||||
error!("Missing class oauth2_resource_server");
|
error!("Missing class oauth2_resource_server");
|
||||||
// Check we have oauth2_resource_server class
|
// Check we have oauth2_resource_server class
|
||||||
|
@ -345,7 +345,7 @@ impl<'a> Oauth2ResourceServersWriteTransaction<'a> {
|
||||||
} else if ent.attribute_equality(Attribute::Class, &EntryClass::OAuth2ResourceServerPublic.into()) {
|
} else if ent.attribute_equality(Attribute::Class, &EntryClass::OAuth2ResourceServerPublic.into()) {
|
||||||
OauthRSType::Public
|
OauthRSType::Public
|
||||||
} else {
|
} else {
|
||||||
error!("Missing class determining oauth2 rs type");
|
error!("Missing class determining OAuth2 rs type");
|
||||||
return Err(OperationError::InvalidEntryState);
|
return Err(OperationError::InvalidEntryState);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -502,7 +502,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
|
|
||||||
// Get the o2rs for the handle.
|
// Get the o2rs for the handle.
|
||||||
let o2rs = self.oauth2rs.inner.rs_set.get(&client_id).ok_or_else(|| {
|
let o2rs = self.oauth2rs.inner.rs_set.get(&client_id).ok_or_else(|| {
|
||||||
admin_warn!("Invalid oauth2 client_id");
|
admin_warn!("Invalid OAuth2 client_id");
|
||||||
Oauth2Error::AuthenticationRequired
|
Oauth2Error::AuthenticationRequired
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -510,7 +510,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
match &o2rs.type_ {
|
match &o2rs.type_ {
|
||||||
OauthRSType::Basic { authz_secret, .. } => {
|
OauthRSType::Basic { authz_secret, .. } => {
|
||||||
if authz_secret != &secret {
|
if authz_secret != &secret {
|
||||||
security_info!("Invalid oauth2 client_id secret");
|
security_info!("Invalid OAuth2 client_id secret, this can happen if your RS is public but you configured a 'basic' type.");
|
||||||
return Err(Oauth2Error::AuthenticationRequired);
|
return Err(Oauth2Error::AuthenticationRequired);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -576,7 +576,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
&modlist,
|
&modlist,
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
admin_error!("Failed to modify - revoke oauth2 session {:?}", e);
|
admin_error!("Failed to modify - revoke OAuth2 session {:?}", e);
|
||||||
Oauth2Error::ServerError(e)
|
Oauth2Error::ServerError(e)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -600,7 +600,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
_ => {
|
_ => {
|
||||||
// We at least need the client_id, else we can't proceed!
|
// We at least need the client_id, else we can't proceed!
|
||||||
security_info!(
|
security_info!(
|
||||||
"Invalid oauth2 authentication - no basic auth or missing client_id in access token request"
|
"Invalid OAuth2 authentication - no basic auth or missing client_id in access token request"
|
||||||
);
|
);
|
||||||
return Err(Oauth2Error::AuthenticationRequired);
|
return Err(Oauth2Error::AuthenticationRequired);
|
||||||
}
|
}
|
||||||
|
@ -615,7 +615,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
// lifetime here is safe since we are the sole accessor.
|
// lifetime here is safe since we are the sole accessor.
|
||||||
let o2rs: &Oauth2RS = unsafe {
|
let o2rs: &Oauth2RS = unsafe {
|
||||||
let s = self.oauth2rs.inner.rs_set.get(&client_id).ok_or_else(|| {
|
let s = self.oauth2rs.inner.rs_set.get(&client_id).ok_or_else(|| {
|
||||||
admin_warn!("Invalid oauth2 client_id");
|
admin_warn!("Invalid OAuth2 client_id");
|
||||||
Oauth2Error::AuthenticationRequired
|
Oauth2Error::AuthenticationRequired
|
||||||
})?;
|
})?;
|
||||||
&*(s as *const _)
|
&*(s as *const _)
|
||||||
|
@ -627,14 +627,14 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
match secret {
|
match secret {
|
||||||
Some(secret) => {
|
Some(secret) => {
|
||||||
if authz_secret != &secret {
|
if authz_secret != &secret {
|
||||||
security_info!("Invalid oauth2 client_id secret");
|
security_info!("Invalid OAuth2 client_id secret");
|
||||||
return Err(Oauth2Error::AuthenticationRequired);
|
return Err(Oauth2Error::AuthenticationRequired);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// We can only get here if we relied on the atr for the client_id and secret
|
// We can only get here if we relied on the atr for the client_id and secret
|
||||||
security_info!(
|
security_info!(
|
||||||
"Invalid oauth2 authentication - no secret in access token request"
|
"Invalid OAuth2 authentication - no secret in access token request - this can happen if you're expecting a public client and configured a basic one."
|
||||||
);
|
);
|
||||||
return Err(Oauth2Error::AuthenticationRequired);
|
return Err(Oauth2Error::AuthenticationRequired);
|
||||||
}
|
}
|
||||||
|
@ -712,7 +712,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
.rs_set
|
.rs_set
|
||||||
.get(&consent_req.client_id)
|
.get(&consent_req.client_id)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
admin_error!("Invalid consent request oauth2 client_id");
|
admin_error!("Invalid consent request OAuth2 client_id");
|
||||||
OperationError::InvalidRequestState
|
OperationError::InvalidRequestState
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -825,7 +825,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
|
|
||||||
// Validate the redirect_uri is the same as the original.
|
// Validate the redirect_uri is the same as the original.
|
||||||
if token_req_redirect_uri != &code_xchg.redirect_uri {
|
if token_req_redirect_uri != &code_xchg.redirect_uri {
|
||||||
security_info!("Invalid oauth2 redirect_uri (differs from original request uri)");
|
security_info!("Invalid OAuth2 redirect_uri (differs from original request uri)");
|
||||||
return Err(Oauth2Error::InvalidOrigin);
|
return Err(Oauth2Error::InvalidOrigin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,7 +834,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
if let Some(expiry) = code_xchg.uat.expiry {
|
if let Some(expiry) = code_xchg.uat.expiry {
|
||||||
if expiry <= odt_ct {
|
if expiry <= odt_ct {
|
||||||
security_info!(
|
security_info!(
|
||||||
"User Auth Token has expired before we could publish the oauth2 response"
|
"User Auth Token has expired before we could publish the OAuth2 response"
|
||||||
);
|
);
|
||||||
return Err(Oauth2Error::AccessDenied);
|
return Err(Oauth2Error::AccessDenied);
|
||||||
}
|
}
|
||||||
|
@ -906,7 +906,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the session is still valid. This call checks the parent session
|
// Check the session is still valid. This call checks the parent session
|
||||||
// and the oauth2 session.
|
// and the OAuth2 session.
|
||||||
let valid = self
|
let valid = self
|
||||||
.check_oauth2_account_uuid_valid(uuid, session_id, parent_session_id, iat, ct)
|
.check_oauth2_account_uuid_valid(uuid, session_id, parent_session_id, iat, ct)
|
||||||
.map_err(|_| admin_error!("Account is not valid"));
|
.map_err(|_| admin_error!("Account is not valid"));
|
||||||
|
@ -926,7 +926,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
security_info!(
|
security_info!(
|
||||||
?session_id,
|
?session_id,
|
||||||
"No oauth2 session found, unable to proceed with refresh"
|
"No OAuth2 session found, unable to proceed with refresh"
|
||||||
);
|
);
|
||||||
Oauth2Error::InvalidToken
|
Oauth2Error::InvalidToken
|
||||||
})?;
|
})?;
|
||||||
|
@ -953,7 +953,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
&modlist,
|
&modlist,
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
admin_error!("Failed to modify - revoke oauth2 session {:?}", e);
|
admin_error!("Failed to modify - revoke OAuth2 session {:?}", e);
|
||||||
Oauth2Error::ServerError(e)
|
Oauth2Error::ServerError(e)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -969,7 +969,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
debug!("oauth2 scopes requested, checked as valid.");
|
debug!("oauth2 scopes requested, checked as valid.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug!("No oauth2 scopes requested, this is valid.");
|
debug!("No OAuth2 scopes requested, this is valid.");
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
@ -1163,7 +1163,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
&modlist,
|
&modlist,
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
admin_error!("Failed to persist oauth2 session record {:?}", e);
|
admin_error!("Failed to persist OAuth2 session record {:?}", e);
|
||||||
Oauth2Error::ServerError(e)
|
Oauth2Error::ServerError(e)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -1190,7 +1190,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
|
|
||||||
// Get the o2rs for the handle.
|
// Get the o2rs for the handle.
|
||||||
let o2rs = self.oauth2rs.inner.rs_set.get(&client_id).ok_or_else(|| {
|
let o2rs = self.oauth2rs.inner.rs_set.get(&client_id).ok_or_else(|| {
|
||||||
admin_warn!("Invalid oauth2 client_id");
|
admin_warn!("Invalid OAuth2 client_id");
|
||||||
OperationError::InvalidSessionState
|
OperationError::InvalidSessionState
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -1198,7 +1198,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
match &o2rs.type_ {
|
match &o2rs.type_ {
|
||||||
OauthRSType::Basic { authz_secret, .. } => {
|
OauthRSType::Basic { authz_secret, .. } => {
|
||||||
if authz_secret != &secret {
|
if authz_secret != &secret {
|
||||||
security_info!("Invalid oauth2 client_id secret");
|
security_info!("Invalid OAuth2 client_id secret");
|
||||||
return Err(OperationError::InvalidSessionState);
|
return Err(OperationError::InvalidSessionState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1236,7 +1236,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
||||||
trace!(?auth_req);
|
trace!(?auth_req);
|
||||||
|
|
||||||
if auth_req.response_type != "code" {
|
if auth_req.response_type != "code" {
|
||||||
admin_warn!("Invalid oauth2 response_type (should be 'code')");
|
admin_warn!("Invalid OAuth2 response_type (should be 'code')");
|
||||||
return Err(Oauth2Error::UnsupportedResponseType);
|
return Err(Oauth2Error::UnsupportedResponseType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1258,7 +1258,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
||||||
.get(&auth_req.client_id)
|
.get(&auth_req.client_id)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
admin_warn!(
|
admin_warn!(
|
||||||
"Invalid oauth2 client_id ({}) Have you configured the oauth2 resource server?",
|
"Invalid OAuth2 client_id ({}) Have you configured the OAuth2 resource server?",
|
||||||
&auth_req.client_id
|
&auth_req.client_id
|
||||||
);
|
);
|
||||||
Oauth2Error::InvalidClientId
|
Oauth2Error::InvalidClientId
|
||||||
|
@ -1268,7 +1268,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
||||||
if auth_req.redirect_uri.origin() != o2rs.origin {
|
if auth_req.redirect_uri.origin() != o2rs.origin {
|
||||||
admin_warn!(
|
admin_warn!(
|
||||||
origin = ?o2rs.origin,
|
origin = ?o2rs.origin,
|
||||||
"Invalid oauth2 redirect_uri (must be related to origin {:?}) - got {:?}",
|
"Invalid OAuth2 redirect_uri (must be related to origin {:?}) - got {:?}",
|
||||||
o2rs.origin,
|
o2rs.origin,
|
||||||
auth_req.redirect_uri.origin()
|
auth_req.redirect_uri.origin()
|
||||||
);
|
);
|
||||||
|
@ -1278,7 +1278,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
||||||
if o2rs.origin_https && auth_req.redirect_uri.scheme() != "https" {
|
if o2rs.origin_https && auth_req.redirect_uri.scheme() != "https" {
|
||||||
admin_warn!(
|
admin_warn!(
|
||||||
origin = ?o2rs.origin,
|
origin = ?o2rs.origin,
|
||||||
"Invalid oauth2 redirect_uri (must be https for secure origin) - got {:?}", auth_req.redirect_uri.scheme()
|
"Invalid OAuth2 redirect_uri (must be https for secure origin) - got {:?}", auth_req.redirect_uri.scheme()
|
||||||
);
|
);
|
||||||
return Err(Oauth2Error::InvalidOrigin);
|
return Err(Oauth2Error::InvalidOrigin);
|
||||||
}
|
}
|
||||||
|
@ -1294,7 +1294,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
||||||
}
|
}
|
||||||
// CodeChallengeMethod must be S256
|
// CodeChallengeMethod must be S256
|
||||||
if pkce_request.code_challenge_method != CodeChallengeMethod::S256 {
|
if pkce_request.code_challenge_method != CodeChallengeMethod::S256 {
|
||||||
admin_warn!("Invalid oauth2 code_challenge_method (must be 'S256')");
|
admin_warn!("Invalid OAuth2 code_challenge_method (must be 'S256')");
|
||||||
return Err(Oauth2Error::InvalidRequest);
|
return Err(Oauth2Error::InvalidRequest);
|
||||||
}
|
}
|
||||||
Some(pkce_request.code_challenge.clone())
|
Some(pkce_request.code_challenge.clone())
|
||||||
|
@ -1330,7 +1330,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
||||||
// Deny anonymous access to oauth2
|
// Deny anonymous access to oauth2
|
||||||
if uat.uuid == UUID_ANONYMOUS {
|
if uat.uuid == UUID_ANONYMOUS {
|
||||||
admin_error!(
|
admin_error!(
|
||||||
"Invalid oauth2 request - refusing to allow user that authenticated with anonymous"
|
"Invalid OAuth2 request - refusing to allow user that authenticated with anonymous"
|
||||||
);
|
);
|
||||||
return Err(Oauth2Error::AccessDenied);
|
return Err(Oauth2Error::AccessDenied);
|
||||||
}
|
}
|
||||||
|
@ -1342,14 +1342,26 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
||||||
.map(str::to_string)
|
.map(str::to_string)
|
||||||
.collect();
|
.collect();
|
||||||
if req_scopes.is_empty() {
|
if req_scopes.is_empty() {
|
||||||
admin_error!("Invalid oauth2 request - must contain at least one requested scope");
|
admin_error!("Invalid OAuth2 request - must contain at least one requested scope");
|
||||||
return Err(Oauth2Error::InvalidRequest);
|
return Err(Oauth2Error::InvalidRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the scopes by our scope regex validation rules.
|
let failed_scopes = req_scopes
|
||||||
if !req_scopes.iter().all(|s| OAUTHSCOPE_RE.is_match(s)) {
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.filter(|s| !OAUTHSCOPE_RE.is_match(s))
|
||||||
|
.collect::<Vec<String>>();
|
||||||
|
if !failed_scopes.is_empty() {
|
||||||
|
let requested_scopes_string = req_scopes
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(",");
|
||||||
admin_error!(
|
admin_error!(
|
||||||
"Invalid oauth2 request - requested scopes failed to pass validation rules"
|
"Invalid OAuth2 request - requested scopes ({}) but ({}) failed to pass validation rules - all must match the regex {}",
|
||||||
|
requested_scopes_string,
|
||||||
|
failed_scopes.join(","),
|
||||||
|
OAUTHSCOPE_RE.as_str()
|
||||||
);
|
);
|
||||||
return Err(Oauth2Error::InvalidScope);
|
return Err(Oauth2Error::InvalidScope);
|
||||||
}
|
}
|
||||||
|
@ -1558,7 +1570,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
||||||
.rs_set
|
.rs_set
|
||||||
.get(&consent_req.client_id)
|
.get(&consent_req.client_id)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
admin_error!("Invalid consent request oauth2 client_id");
|
admin_error!("Invalid consent request OAuth2 client_id");
|
||||||
OperationError::InvalidRequestState
|
OperationError::InvalidRequestState
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -1577,7 +1589,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
||||||
|
|
||||||
// Get the o2rs for the handle.
|
// Get the o2rs for the handle.
|
||||||
let o2rs = self.oauth2rs.inner.rs_set.get(&client_id).ok_or_else(|| {
|
let o2rs = self.oauth2rs.inner.rs_set.get(&client_id).ok_or_else(|| {
|
||||||
admin_warn!("Invalid oauth2 client_id");
|
admin_warn!("Invalid OAuth2 client_id");
|
||||||
Oauth2Error::AuthenticationRequired
|
Oauth2Error::AuthenticationRequired
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -1585,7 +1597,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
||||||
match &o2rs.type_ {
|
match &o2rs.type_ {
|
||||||
OauthRSType::Basic { authz_secret, .. } => {
|
OauthRSType::Basic { authz_secret, .. } => {
|
||||||
if authz_secret != &secret {
|
if authz_secret != &secret {
|
||||||
security_info!("Invalid oauth2 client_id secret");
|
security_info!("Invalid OAuth2 client_id secret");
|
||||||
return Err(Oauth2Error::AuthenticationRequired);
|
return Err(Oauth2Error::AuthenticationRequired);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1628,7 +1640,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
||||||
return Ok(AccessTokenIntrospectResponse::inactive());
|
return Ok(AccessTokenIntrospectResponse::inactive());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is the user expired, or the oauth2 session invalid?
|
// Is the user expired, or the OAuth2 session invalid?
|
||||||
let valid = self
|
let valid = self
|
||||||
.check_oauth2_account_uuid_valid(uuid, session_id, parent_session_id, iat, ct)
|
.check_oauth2_account_uuid_valid(uuid, session_id, parent_session_id, iat, ct)
|
||||||
.map_err(|_| admin_error!("Account is not valid"));
|
.map_err(|_| admin_error!("Account is not valid"));
|
||||||
|
@ -1692,7 +1704,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
||||||
let o2rs: &Oauth2RS = unsafe {
|
let o2rs: &Oauth2RS = unsafe {
|
||||||
let s = self.oauth2rs.inner.rs_set.get(client_id).ok_or_else(|| {
|
let s = self.oauth2rs.inner.rs_set.get(client_id).ok_or_else(|| {
|
||||||
admin_warn!(
|
admin_warn!(
|
||||||
"Invalid oauth2 client_id (have you configured the oauth2 resource server?)"
|
"Invalid OAuth2 client_id (have you configured the OAuth2 resource server?)"
|
||||||
);
|
);
|
||||||
Oauth2Error::InvalidClientId
|
Oauth2Error::InvalidClientId
|
||||||
})?;
|
})?;
|
||||||
|
@ -1732,7 +1744,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
||||||
return Err(Oauth2Error::InvalidToken);
|
return Err(Oauth2Error::InvalidToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is the user expired, or the oauth2 session invalid?
|
// Is the user expired, or the OAuth2 session invalid?
|
||||||
let valid = self
|
let valid = self
|
||||||
.check_oauth2_account_uuid_valid(uuid, session_id, parent_session_id, iat, ct)
|
.check_oauth2_account_uuid_valid(uuid, session_id, parent_session_id, iat, ct)
|
||||||
.map_err(|_| admin_error!("Account is not valid"));
|
.map_err(|_| admin_error!("Account is not valid"));
|
||||||
|
@ -1790,7 +1802,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
||||||
) -> Result<OidcDiscoveryResponse, OperationError> {
|
) -> Result<OidcDiscoveryResponse, OperationError> {
|
||||||
let o2rs = self.oauth2rs.inner.rs_set.get(client_id).ok_or_else(|| {
|
let o2rs = self.oauth2rs.inner.rs_set.get(client_id).ok_or_else(|| {
|
||||||
admin_warn!(
|
admin_warn!(
|
||||||
"Invalid oauth2 client_id (have you configured the oauth2 resource server?)"
|
"Invalid OAuth2 client_id (have you configured the OAuth2 resource server?)"
|
||||||
);
|
);
|
||||||
OperationError::NoMatchingEntries
|
OperationError::NoMatchingEntries
|
||||||
})?;
|
})?;
|
||||||
|
@ -1811,7 +1823,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
||||||
JwsSigner::ES256 { .. } => vec![IdTokenSignAlg::ES256],
|
JwsSigner::ES256 { .. } => vec![IdTokenSignAlg::ES256],
|
||||||
JwsSigner::RS256 { .. } => vec![IdTokenSignAlg::RS256],
|
JwsSigner::RS256 { .. } => vec![IdTokenSignAlg::RS256],
|
||||||
JwsSigner::HS256 { .. } => {
|
JwsSigner::HS256 { .. } => {
|
||||||
admin_warn!("Invalid oauth2 configuration - HS256 is not supported!");
|
admin_warn!("Invalid OAuth2 configuration - HS256 is not supported!");
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1871,7 +1883,7 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
||||||
pub fn oauth2_openid_publickey(&self, client_id: &str) -> Result<JwkKeySet, OperationError> {
|
pub fn oauth2_openid_publickey(&self, client_id: &str) -> Result<JwkKeySet, OperationError> {
|
||||||
let o2rs = self.oauth2rs.inner.rs_set.get(client_id).ok_or_else(|| {
|
let o2rs = self.oauth2rs.inner.rs_set.get(client_id).ok_or_else(|| {
|
||||||
admin_warn!(
|
admin_warn!(
|
||||||
"Invalid oauth2 client_id (have you configured the oauth2 resource server?)"
|
"Invalid OAuth2 client_id (have you configured the OAuth2 resource server?)"
|
||||||
);
|
);
|
||||||
OperationError::NoMatchingEntries
|
OperationError::NoMatchingEntries
|
||||||
})?;
|
})?;
|
||||||
|
@ -2041,11 +2053,11 @@ mod tests {
|
||||||
|
|
||||||
$idms_prox_read
|
$idms_prox_read
|
||||||
.check_oauth2_authorisation($ident, $uat, &auth_req, $ct)
|
.check_oauth2_authorisation($ident, $uat, &auth_req, $ct)
|
||||||
.expect("Oauth2 authorisation failed")
|
.expect("OAuth2 authorisation failed")
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup an oauth2 instance.
|
// setup an OAuth2 instance.
|
||||||
async fn setup_oauth2_resource_server_basic(
|
async fn setup_oauth2_resource_server_basic(
|
||||||
idms: &IdmServer,
|
idms: &IdmServer,
|
||||||
ct: Duration,
|
ct: Duration,
|
||||||
|
@ -2124,7 +2136,7 @@ mod tests {
|
||||||
let entry = idms_prox_write
|
let entry = idms_prox_write
|
||||||
.qs_write
|
.qs_write
|
||||||
.internal_search_uuid(uuid)
|
.internal_search_uuid(uuid)
|
||||||
.expect("Failed to retrieve oauth2 resource entry ");
|
.expect("Failed to retrieve OAuth2 resource entry ");
|
||||||
let secret = entry
|
let secret = entry
|
||||||
.get_ava_single_secret(Attribute::OAuth2RsBasicSecret)
|
.get_ava_single_secret(Attribute::OAuth2RsBasicSecret)
|
||||||
.map(str::to_string)
|
.map(str::to_string)
|
||||||
|
@ -2379,7 +2391,7 @@ mod tests {
|
||||||
|
|
||||||
let permit_success = idms_prox_write
|
let permit_success = idms_prox_write
|
||||||
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
||||||
.expect("Failed to perform oauth2 permit");
|
.expect("Failed to perform OAuth2 permit");
|
||||||
|
|
||||||
// Check we are reflecting the CSRF properly.
|
// Check we are reflecting the CSRF properly.
|
||||||
assert!(permit_success.state == "123");
|
assert!(permit_success.state == "123");
|
||||||
|
@ -2399,7 +2411,7 @@ mod tests {
|
||||||
|
|
||||||
let token_response = idms_prox_write
|
let token_response = idms_prox_write
|
||||||
.check_oauth2_token_exchange(None, &token_req, ct)
|
.check_oauth2_token_exchange(None, &token_req, ct)
|
||||||
.expect("Failed to perform oauth2 token exchange");
|
.expect("Failed to perform OAuth2 token exchange");
|
||||||
|
|
||||||
// 🎉 We got a token! In the future we can then check introspection from this point.
|
// 🎉 We got a token! In the future we can then check introspection from this point.
|
||||||
assert!(token_response.token_type == "bearer");
|
assert!(token_response.token_type == "bearer");
|
||||||
|
@ -2445,7 +2457,7 @@ mod tests {
|
||||||
|
|
||||||
let permit_success = idms_prox_write
|
let permit_success = idms_prox_write
|
||||||
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
||||||
.expect("Failed to perform oauth2 permit");
|
.expect("Failed to perform OAuth2 permit");
|
||||||
|
|
||||||
// Check we are reflecting the CSRF properly.
|
// Check we are reflecting the CSRF properly.
|
||||||
assert!(permit_success.state == "123");
|
assert!(permit_success.state == "123");
|
||||||
|
@ -2465,7 +2477,7 @@ mod tests {
|
||||||
|
|
||||||
let token_response = idms_prox_write
|
let token_response = idms_prox_write
|
||||||
.check_oauth2_token_exchange(None, &token_req, ct)
|
.check_oauth2_token_exchange(None, &token_req, ct)
|
||||||
.expect("Failed to perform oauth2 token exchange");
|
.expect("Failed to perform OAuth2 token exchange");
|
||||||
|
|
||||||
// 🎉 We got a token! In the future we can then check introspection from this point.
|
// 🎉 We got a token! In the future we can then check introspection from this point.
|
||||||
assert!(token_response.token_type == "bearer");
|
assert!(token_response.token_type == "bearer");
|
||||||
|
@ -2478,7 +2490,7 @@ mod tests {
|
||||||
idms: &IdmServer,
|
idms: &IdmServer,
|
||||||
_idms_delayed: &mut IdmServerDelayed,
|
_idms_delayed: &mut IdmServerDelayed,
|
||||||
) {
|
) {
|
||||||
// Test invalid oauth2 authorisation states/requests.
|
// Test invalid OAuth2 authorisation states/requests.
|
||||||
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||||
let (_secret, uat, ident, _) =
|
let (_secret, uat, ident, _) =
|
||||||
setup_oauth2_resource_server_basic(idms, ct, true, false, false).await;
|
setup_oauth2_resource_server_basic(idms, ct, true, false, false).await;
|
||||||
|
@ -2642,7 +2654,7 @@ mod tests {
|
||||||
idms: &IdmServer,
|
idms: &IdmServer,
|
||||||
_idms_delayed: &mut IdmServerDelayed,
|
_idms_delayed: &mut IdmServerDelayed,
|
||||||
) {
|
) {
|
||||||
// Test invalid oauth2 authorisation states/requests.
|
// Test invalid OAuth2 authorisation states/requests.
|
||||||
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||||
let (_secret, uat, ident, _) =
|
let (_secret, uat, ident, _) =
|
||||||
setup_oauth2_resource_server_basic(idms, ct, true, false, false).await;
|
setup_oauth2_resource_server_basic(idms, ct, true, false, false).await;
|
||||||
|
@ -2775,7 +2787,7 @@ mod tests {
|
||||||
// == Manually submit the consent token to the permit for the permit_success
|
// == Manually submit the consent token to the permit for the permit_success
|
||||||
let permit_success = idms_prox_write
|
let permit_success = idms_prox_write
|
||||||
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
||||||
.expect("Failed to perform oauth2 permit");
|
.expect("Failed to perform OAuth2 permit");
|
||||||
|
|
||||||
// == Submit the token exchange code.
|
// == Submit the token exchange code.
|
||||||
|
|
||||||
|
@ -2939,7 +2951,7 @@ mod tests {
|
||||||
|
|
||||||
let permit_success = idms_prox_write
|
let permit_success = idms_prox_write
|
||||||
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
||||||
.expect("Failed to perform oauth2 permit");
|
.expect("Failed to perform OAuth2 permit");
|
||||||
|
|
||||||
let token_req: AccessTokenRequest = GrantTypeReq::AuthorizationCode {
|
let token_req: AccessTokenRequest = GrantTypeReq::AuthorizationCode {
|
||||||
code: permit_success.code,
|
code: permit_success.code,
|
||||||
|
@ -2949,7 +2961,7 @@ mod tests {
|
||||||
.into();
|
.into();
|
||||||
let oauth2_token = idms_prox_write
|
let oauth2_token = idms_prox_write
|
||||||
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
||||||
.expect("Unable to exchange for oauth2 token");
|
.expect("Unable to exchange for OAuth2 token");
|
||||||
|
|
||||||
assert!(idms_prox_write.commit().is_ok());
|
assert!(idms_prox_write.commit().is_ok());
|
||||||
|
|
||||||
|
@ -3035,7 +3047,7 @@ mod tests {
|
||||||
|
|
||||||
let permit_success = idms_prox_write
|
let permit_success = idms_prox_write
|
||||||
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
||||||
.expect("Failed to perform oauth2 permit");
|
.expect("Failed to perform OAuth2 permit");
|
||||||
|
|
||||||
// Assert that the consent was submitted
|
// Assert that the consent was submitted
|
||||||
let token_req: AccessTokenRequest = GrantTypeReq::AuthorizationCode {
|
let token_req: AccessTokenRequest = GrantTypeReq::AuthorizationCode {
|
||||||
|
@ -3046,7 +3058,7 @@ mod tests {
|
||||||
.into();
|
.into();
|
||||||
let oauth2_token = idms_prox_write
|
let oauth2_token = idms_prox_write
|
||||||
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
||||||
.expect("Unable to exchange for oauth2 token");
|
.expect("Unable to exchange for OAuth2 token");
|
||||||
|
|
||||||
assert!(idms_prox_write.commit().is_ok());
|
assert!(idms_prox_write.commit().is_ok());
|
||||||
|
|
||||||
|
@ -3202,7 +3214,7 @@ mod tests {
|
||||||
|
|
||||||
let permit_success = idms_prox_write
|
let permit_success = idms_prox_write
|
||||||
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
||||||
.expect("Failed to perform oauth2 permit");
|
.expect("Failed to perform OAuth2 permit");
|
||||||
|
|
||||||
let token_req: AccessTokenRequest = GrantTypeReq::AuthorizationCode {
|
let token_req: AccessTokenRequest = GrantTypeReq::AuthorizationCode {
|
||||||
code: permit_success.code,
|
code: permit_success.code,
|
||||||
|
@ -3213,7 +3225,7 @@ mod tests {
|
||||||
|
|
||||||
let oauth2_token = idms_prox_write
|
let oauth2_token = idms_prox_write
|
||||||
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
||||||
.expect("Unable to exchange for oauth2 token");
|
.expect("Unable to exchange for OAuth2 token");
|
||||||
|
|
||||||
let reflected_token = idms_prox_write
|
let reflected_token = idms_prox_write
|
||||||
.reflect_oauth2_token(client_authz.as_ref().unwrap(), &oauth2_token.access_token)
|
.reflect_oauth2_token(client_authz.as_ref().unwrap(), &oauth2_token.access_token)
|
||||||
|
@ -3318,7 +3330,7 @@ mod tests {
|
||||||
|
|
||||||
let reject_success = idms_prox_read
|
let reject_success = idms_prox_read
|
||||||
.check_oauth2_authorise_reject(&ident, &uat, &consent_token, ct)
|
.check_oauth2_authorise_reject(&ident, &uat, &consent_token, ct)
|
||||||
.expect("Failed to perform oauth2 reject");
|
.expect("Failed to perform OAuth2 reject");
|
||||||
|
|
||||||
assert!(reject_success == redirect_uri);
|
assert!(reject_success == redirect_uri);
|
||||||
|
|
||||||
|
@ -3532,7 +3544,7 @@ mod tests {
|
||||||
|
|
||||||
let permit_success = idms_prox_write
|
let permit_success = idms_prox_write
|
||||||
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
||||||
.expect("Failed to perform oauth2 permit");
|
.expect("Failed to perform OAuth2 permit");
|
||||||
|
|
||||||
// == Submit the token exchange code.
|
// == Submit the token exchange code.
|
||||||
let token_req: AccessTokenRequest = GrantTypeReq::AuthorizationCode {
|
let token_req: AccessTokenRequest = GrantTypeReq::AuthorizationCode {
|
||||||
|
@ -3545,7 +3557,7 @@ mod tests {
|
||||||
|
|
||||||
let token_response = idms_prox_write
|
let token_response = idms_prox_write
|
||||||
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
||||||
.expect("Failed to perform oauth2 token exchange");
|
.expect("Failed to perform OAuth2 token exchange");
|
||||||
|
|
||||||
// 🎉 We got a token!
|
// 🎉 We got a token!
|
||||||
assert!(token_response.token_type == "bearer");
|
assert!(token_response.token_type == "bearer");
|
||||||
|
@ -3643,7 +3655,7 @@ mod tests {
|
||||||
|
|
||||||
let token_response = idms_prox_write
|
let token_response = idms_prox_write
|
||||||
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
||||||
.expect("Unable to exchange for oauth2 token");
|
.expect("Unable to exchange for OAuth2 token");
|
||||||
|
|
||||||
let access_token = token_response.access_token;
|
let access_token = token_response.access_token;
|
||||||
|
|
||||||
|
@ -3712,7 +3724,7 @@ mod tests {
|
||||||
|
|
||||||
let permit_success = idms_prox_write
|
let permit_success = idms_prox_write
|
||||||
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
||||||
.expect("Failed to perform oauth2 permit");
|
.expect("Failed to perform OAuth2 permit");
|
||||||
|
|
||||||
// == Submit the token exchange code.
|
// == Submit the token exchange code.
|
||||||
let token_req: AccessTokenRequest = GrantTypeReq::AuthorizationCode {
|
let token_req: AccessTokenRequest = GrantTypeReq::AuthorizationCode {
|
||||||
|
@ -3725,7 +3737,7 @@ mod tests {
|
||||||
|
|
||||||
let token_response = idms_prox_write
|
let token_response = idms_prox_write
|
||||||
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
||||||
.expect("Failed to perform oauth2 token exchange");
|
.expect("Failed to perform OAuth2 token exchange");
|
||||||
|
|
||||||
let id_token = token_response.id_token.expect("No id_token in response!");
|
let id_token = token_response.id_token.expect("No id_token in response!");
|
||||||
let access_token = token_response.access_token;
|
let access_token = token_response.access_token;
|
||||||
|
@ -3798,7 +3810,7 @@ mod tests {
|
||||||
|
|
||||||
let permit_success = idms_prox_write
|
let permit_success = idms_prox_write
|
||||||
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
||||||
.expect("Failed to perform oauth2 permit");
|
.expect("Failed to perform OAuth2 permit");
|
||||||
|
|
||||||
// == Submit the token exchange code.
|
// == Submit the token exchange code.
|
||||||
let token_req: AccessTokenRequest = GrantTypeReq::AuthorizationCode {
|
let token_req: AccessTokenRequest = GrantTypeReq::AuthorizationCode {
|
||||||
|
@ -3811,7 +3823,7 @@ mod tests {
|
||||||
|
|
||||||
let token_response = idms_prox_write
|
let token_response = idms_prox_write
|
||||||
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
||||||
.expect("Failed to perform oauth2 token exchange");
|
.expect("Failed to perform OAuth2 token exchange");
|
||||||
|
|
||||||
let id_token = token_response.id_token.expect("No id_token in response!");
|
let id_token = token_response.id_token.expect("No id_token in response!");
|
||||||
let access_token = token_response.access_token;
|
let access_token = token_response.access_token;
|
||||||
|
@ -3959,7 +3971,7 @@ mod tests {
|
||||||
|
|
||||||
let permit_success = idms_prox_write
|
let permit_success = idms_prox_write
|
||||||
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
||||||
.expect("Failed to perform oauth2 permit");
|
.expect("Failed to perform OAuth2 permit");
|
||||||
|
|
||||||
// == Submit the token exchange code.
|
// == Submit the token exchange code.
|
||||||
let token_req = AccessTokenRequest {
|
let token_req = AccessTokenRequest {
|
||||||
|
@ -3975,7 +3987,7 @@ mod tests {
|
||||||
|
|
||||||
let token_response = idms_prox_write
|
let token_response = idms_prox_write
|
||||||
.check_oauth2_token_exchange(None, &token_req, ct)
|
.check_oauth2_token_exchange(None, &token_req, ct)
|
||||||
.expect("Failed to perform oauth2 token exchange");
|
.expect("Failed to perform OAuth2 token exchange");
|
||||||
|
|
||||||
// 🎉 We got a token!
|
// 🎉 We got a token!
|
||||||
assert!(token_response.token_type == "bearer");
|
assert!(token_response.token_type == "bearer");
|
||||||
|
@ -4032,7 +4044,7 @@ mod tests {
|
||||||
|
|
||||||
let _permit_success = idms_prox_write
|
let _permit_success = idms_prox_write
|
||||||
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
||||||
.expect("Failed to perform oauth2 permit");
|
.expect("Failed to perform OAuth2 permit");
|
||||||
|
|
||||||
assert!(idms_prox_write.commit().is_ok());
|
assert!(idms_prox_write.commit().is_ok());
|
||||||
|
|
||||||
|
@ -4064,7 +4076,7 @@ mod tests {
|
||||||
|
|
||||||
drop(idms_prox_read);
|
drop(idms_prox_read);
|
||||||
|
|
||||||
// Great! Now change the scopes on the oauth2 instance, this revokes the permit.
|
// Great! Now change the scopes on the OAuth2 instance, this revokes the permit.
|
||||||
let mut idms_prox_write = idms.proxy_write(ct).await;
|
let mut idms_prox_write = idms.proxy_write(ct).await;
|
||||||
|
|
||||||
let me_extend_scopes = ModifyEvent::new_internal_invalid(
|
let me_extend_scopes = ModifyEvent::new_internal_invalid(
|
||||||
|
@ -4130,7 +4142,7 @@ mod tests {
|
||||||
|
|
||||||
// Success! We had to consent again due to the change :)
|
// Success! We had to consent again due to the change :)
|
||||||
|
|
||||||
// Now change the supplemental scopes on the oauth2 instance, this revokes the permit.
|
// Now change the supplemental scopes on the OAuth2 instance, this revokes the permit.
|
||||||
let mut idms_prox_write = idms.proxy_write(ct).await;
|
let mut idms_prox_write = idms.proxy_write(ct).await;
|
||||||
|
|
||||||
let me_extend_scopes = ModifyEvent::new_internal_invalid(
|
let me_extend_scopes = ModifyEvent::new_internal_invalid(
|
||||||
|
@ -4231,7 +4243,7 @@ mod tests {
|
||||||
|
|
||||||
let _permit_success = idms_prox_write
|
let _permit_success = idms_prox_write
|
||||||
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
||||||
.expect("Failed to perform oauth2 permit");
|
.expect("Failed to perform OAuth2 permit");
|
||||||
|
|
||||||
let ident = idms_prox_write
|
let ident = idms_prox_write
|
||||||
.process_uat_to_identity(&uat, ct)
|
.process_uat_to_identity(&uat, ct)
|
||||||
|
@ -4318,7 +4330,7 @@ mod tests {
|
||||||
|
|
||||||
let consent_request = idms_prox_read
|
let consent_request = idms_prox_read
|
||||||
.check_oauth2_authorisation(&ident, &uat, &auth_req, ct)
|
.check_oauth2_authorisation(&ident, &uat, &auth_req, ct)
|
||||||
.expect("Failed to perform oauth2 authorisation request.");
|
.expect("Failed to perform OAuth2 authorisation request.");
|
||||||
|
|
||||||
// Should be in the consent phase;
|
// Should be in the consent phase;
|
||||||
let consent_token =
|
let consent_token =
|
||||||
|
@ -4334,7 +4346,7 @@ mod tests {
|
||||||
|
|
||||||
let permit_success = idms_prox_write
|
let permit_success = idms_prox_write
|
||||||
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
||||||
.expect("Failed to perform oauth2 permit");
|
.expect("Failed to perform OAuth2 permit");
|
||||||
|
|
||||||
// == Submit the token exchange code.
|
// == Submit the token exchange code.
|
||||||
// This exchange failed because we submitted a verifier when the code exchange
|
// This exchange failed because we submitted a verifier when the code exchange
|
||||||
|
@ -4427,7 +4439,7 @@ mod tests {
|
||||||
|
|
||||||
let permit_success = idms_prox_write
|
let permit_success = idms_prox_write
|
||||||
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
||||||
.expect("Failed to perform oauth2 permit");
|
.expect("Failed to perform OAuth2 permit");
|
||||||
|
|
||||||
// == Submit the token exchange code.
|
// == Submit the token exchange code.
|
||||||
// NOTE the url is http again
|
// NOTE the url is http again
|
||||||
|
@ -4488,7 +4500,7 @@ mod tests {
|
||||||
|
|
||||||
let permit_success = idms_prox_write
|
let permit_success = idms_prox_write
|
||||||
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
.check_oauth2_authorise_permit(&ident, &uat, &consent_token, ct)
|
||||||
.expect("Failed to perform oauth2 permit");
|
.expect("Failed to perform OAuth2 permit");
|
||||||
|
|
||||||
let token_req: AccessTokenRequest = GrantTypeReq::AuthorizationCode {
|
let token_req: AccessTokenRequest = GrantTypeReq::AuthorizationCode {
|
||||||
code: permit_success.code,
|
code: permit_success.code,
|
||||||
|
@ -4498,7 +4510,7 @@ mod tests {
|
||||||
.into();
|
.into();
|
||||||
let access_token_response_1 = idms_prox_write
|
let access_token_response_1 = idms_prox_write
|
||||||
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
||||||
.expect("Unable to exchange for oauth2 token");
|
.expect("Unable to exchange for OAuth2 token");
|
||||||
|
|
||||||
assert!(idms_prox_write.commit().is_ok());
|
assert!(idms_prox_write.commit().is_ok());
|
||||||
|
|
||||||
|
@ -4538,7 +4550,7 @@ mod tests {
|
||||||
|
|
||||||
let access_token_response_2 = idms_prox_write
|
let access_token_response_2 = idms_prox_write
|
||||||
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
||||||
.expect("Unable to exchange for oauth2 token");
|
.expect("Unable to exchange for OAuth2 token");
|
||||||
|
|
||||||
assert!(idms_prox_write.commit().is_ok());
|
assert!(idms_prox_write.commit().is_ok());
|
||||||
|
|
||||||
|
@ -4579,7 +4591,7 @@ mod tests {
|
||||||
|
|
||||||
let access_token_response_3 = idms_prox_write
|
let access_token_response_3 = idms_prox_write
|
||||||
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
||||||
.expect("Unable to exchange for oauth2 token");
|
.expect("Unable to exchange for OAuth2 token");
|
||||||
|
|
||||||
assert!(idms_prox_write.commit().is_ok());
|
assert!(idms_prox_write.commit().is_ok());
|
||||||
|
|
||||||
|
@ -4620,7 +4632,7 @@ mod tests {
|
||||||
assert!(idms_prox_write.commit().is_ok());
|
assert!(idms_prox_write.commit().is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
// refresh when oauth2 parent session exp / missing.
|
// refresh when OAuth2 parent session exp / missing.
|
||||||
#[idm_test]
|
#[idm_test]
|
||||||
async fn test_idm_oauth2_refresh_token_oauth2_session_expired(
|
async fn test_idm_oauth2_refresh_token_oauth2_session_expired(
|
||||||
idms: &IdmServer,
|
idms: &IdmServer,
|
||||||
|
@ -4633,7 +4645,7 @@ mod tests {
|
||||||
setup_refresh_token(idms, idms_delayed, ct).await;
|
setup_refresh_token(idms, idms_delayed, ct).await;
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// Revoke the oauth2 session
|
// Revoke the OAuth2 session
|
||||||
|
|
||||||
let mut idms_prox_write = idms.proxy_write(ct).await;
|
let mut idms_prox_write = idms.proxy_write(ct).await;
|
||||||
let revoke_request = TokenRevokeRequest {
|
let revoke_request = TokenRevokeRequest {
|
||||||
|
@ -4781,7 +4793,7 @@ mod tests {
|
||||||
|
|
||||||
let _access_token_response_2 = idms_prox_write
|
let _access_token_response_2 = idms_prox_write
|
||||||
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
||||||
.expect("Unable to exchange for oauth2 token");
|
.expect("Unable to exchange for OAuth2 token");
|
||||||
|
|
||||||
assert!(idms_prox_write.commit().is_ok());
|
assert!(idms_prox_write.commit().is_ok());
|
||||||
|
|
||||||
|
@ -4859,7 +4871,7 @@ mod tests {
|
||||||
|
|
||||||
let access_token_response_2 = idms_prox_write
|
let access_token_response_2 = idms_prox_write
|
||||||
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
||||||
.expect("Unable to exchange for oauth2 token");
|
.expect("Unable to exchange for OAuth2 token");
|
||||||
|
|
||||||
// DO NOT COMMIT HERE - this is what forces the session issued_at
|
// DO NOT COMMIT HERE - this is what forces the session issued_at
|
||||||
// time to stay at the original time!
|
// time to stay at the original time!
|
||||||
|
@ -4883,7 +4895,7 @@ mod tests {
|
||||||
|
|
||||||
let _access_token_response_3 = idms_prox_write
|
let _access_token_response_3 = idms_prox_write
|
||||||
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
.check_oauth2_token_exchange(client_authz.as_deref(), &token_req, ct)
|
||||||
.expect("Unable to exchange for oauth2 token");
|
.expect("Unable to exchange for OAuth2 token");
|
||||||
|
|
||||||
assert!(idms_prox_write.commit().is_ok());
|
assert!(idms_prox_write.commit().is_ok());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue