refactor: set explicit boundaries btwn the AuthzServer communication failure, versus an invalid token response from the server
parent
62d83b9219
commit
518d10d4c0
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue