refactor: set explicit boundaries btwn the AuthzServer communication failure, versus an invalid token response from the server

pull/24376/head
wiedld 2023-05-04 12:07:44 -07:00
parent 62d83b9219
commit 518d10d4c0
2 changed files with 27 additions and 13 deletions

View File

@ -2,8 +2,9 @@ use async_trait::async_trait;
use super::{Error, Permission};
/// An authorizer is used to validate the associated with
/// an authorization token that has been extracted from a request.
/// An authorizer is used to validate a request
/// (+ associated permissions needed to fulfill the request)
/// with an authorization token that has been extracted from the request.
#[async_trait]
pub trait Authorizer: std::fmt::Debug + Send + Sync {
/// Determine the permissions associated with a request token.
@ -13,6 +14,7 @@ pub trait Authorizer: std::fmt::Debug + Send + Sync {
///
/// Implementations of this trait should only error if:
/// * there is a failure processing the token.
/// * the token is invalid.
/// * there is not any intersection of permissions.
async fn permissions(
&self,
@ -23,8 +25,12 @@ pub trait Authorizer: std::fmt::Debug + Send + Sync {
/// Make a test request that determines if end-to-end communication
/// with the service is working.
async fn probe(&self) -> Result<(), Error> {
self.permissions(Some(b"".to_vec()), &[]).await?;
Ok(())
match self.permissions(Some(b"".to_vec()), &[]).await {
// got response from authorizer server
Ok(_) | Err(Error::Forbidden) | Err(Error::InvalidToken) => Ok(()),
// other errors, including Error::Verification
Err(e) => Err(e),
}
}
}

View File

@ -53,10 +53,18 @@ impl Authorizer for IoxAuthorizer {
) -> Result<Vec<Permission>, Error> {
let authz_rpc_result = self
.request(token.ok_or(Error::NoToken)?, requested_perms)
.await?;
.await
.map_err(|status| Error::Verification {
msg: status.message().to_string(),
source: Box::new(status),
})?
.into_inner();
if !authz_rpc_result.valid {
return Err(Error::InvalidToken);
}
let intersected_perms: Vec<Permission> = authz_rpc_result
.into_inner()
.permissions
.into_iter()
.filter_map(|p| match p.try_into() {
@ -68,14 +76,10 @@ impl Authorizer for IoxAuthorizer {
})
.collect();
match (requested_perms, &intersected_perms[..]) {
// used in connection `Authorizer::probe()`
([], _) => Ok(vec![]),
// token does not have any of the requested_perms
(_, []) => Err(Error::Forbidden),
// if token has `any_of` the requested_perms => return ok
_ => Ok(intersected_perms),
if intersected_perms.is_empty() {
return Err(Error::Forbidden);
}
Ok(intersected_perms)
}
}
@ -91,6 +95,10 @@ pub enum Error {
source: Box<dyn std::error::Error + Send + Sync + 'static>,
},
/// Token is invalid.
#[snafu(display("invalid token"))]
InvalidToken,
/// The token's permissions do not allow the operation.
#[snafu(display("forbidden"))]
Forbidden,