authorized 0.1.1

Authorized struct's fields
Documentation

//! Authorized is a library helping you authorize behaviour on struct by defining allowed or denied
//! scopes.
//!
//! You can use this to only expose field's value to authorized scopes

#![warn(
    clippy::all,
    // clippy::restriction,
    clippy::pedantic,
    clippy::nursery,
    // clippy::cargo
)]
#![recursion_limit = "256"]


pub mod scope;

mod error;
mod result;
#[cfg(feature = "with_serde")]
mod serde;

pub mod prelude;

use scope::IntoScope;
use scope::Scope;

use error::*;
use result::*;

pub type UnAuthorizedFields<'a> = Vec<&'a str>;

pub trait Authorizable {
    type Authorized;

    fn filter_unauthorized_fields<'a>(&'a self, scope: &Scope) -> UnAuthorizedFields<'a>;
    fn authorize<'a>(
        &'a self,
        authorizer: &Scope,
    ) -> Result<AuthorizedResult<'a, Self::Authorized>, AuthorizedError>;
}


/// Authorizor exposed mthods to help you authorize structures which implement
/// [Authorizable](trait.Authorizable.html) trait.
pub struct Authorizor {}

impl Authorizor {
    /// Create an authorized version of the input structure validated by the scope implementing
    /// [`IntoScope`](scope/trait.IntoScope.html).
    ///
    /// It returns an [`AuthorizedResult`](struct.AuthorizedResult.html) which allow you to know
    /// which fields have been secured and if the whole structure is authorized or not.
    pub fn authorize<'a, A: Authorizable, T: IntoScope>(
        inner: &'a A,
        scope: &T,
    ) -> Result<AuthorizedResult<'a, A::Authorized>, AuthorizedError> {
        let scope: Scope = scope.into_scope()?;

        inner.authorize(&scope)
    }
}

pub trait Authorized {
    #[cfg(feature = "with_serde")]
    type Source: Authorizable + ::serde::ser::Serialize;
    #[cfg(not(feature = "with_serde"))]
    type Source: Authorizable;

    fn build_serialize_struct<E>(&self, unauthorized_fields: &[&str]) -> Result<Self::Source, E>;
}

// #[cfg(test)]
// mod tests {
//     use super::*;

//     #[test]
//     fn it_works() {
//         let based_user = MyUser {
//             name: "name".into(),
//             pass: "pass".into(),
//             email: "email".into(),
//         };

//         let user: AuthorizedResult<AuthorizedUser> = based_user
//             .authorize(&"user read:user".parse::<Scope>().unwrap())
//             .unwrap();

//         assert_eq!(user.status, AuthorizationStatus::Authorized);
//         assert_eq!(user.inner.name, Some("name".to_owned()));
//         assert_eq!(user.inner.pass, Some("pass".to_owned()));

//         let json = serde_json::to_string(&user).unwrap();
//         assert_eq!(
//             json,
//             serde_json::to_string(&json!({"name": "name"})).unwrap()
//         );

//         let user: AuthorizedResult<AuthorizedUser> = based_user
//             .authorize(&"guest".parse::<Scope>().unwrap())
//             .unwrap();

//         assert_eq!(user.status, AuthorizationStatus::UnAuthorized);

//         assert_eq!(user.inner.name, None);
//         assert_eq!(user.inner.pass, None);

//         let json = serde_json::to_string(&user).unwrap();
//         assert_eq!(json, serde_json::to_string(&json!({})).unwrap());

//         let user: AuthorizedResult<AuthorizedUser> = based_user
//             .authorize(&"read:user admin".parse::<Scope>().unwrap())
//             .unwrap();

//         assert_eq!(user.status, AuthorizationStatus::Authorized);
//         assert_eq!(user.inner.name, Some("name".to_owned()));
//         assert_eq!(user.inner.pass, Some("pass".to_owned()));

//         let json = serde_json::to_string(&user).unwrap();
//         assert_eq!(
//             json,
//             serde_json::to_string(&json!({"name": "name", "pass": "pass"})).unwrap()
//         );

//         let user = Authorizor::authorize(&based_user, "read:user admin").unwrap();

//         assert_eq!(user.status, AuthorizationStatus::Authorized);
//         assert_eq!(user.inner.name, Some("name".to_owned()));
//         assert_eq!(user.inner.pass, Some("pass".to_owned()));

//         let json = serde_json::to_string(&user).unwrap();
//         assert_eq!(
//             json,
//             serde_json::to_string(&json!({"name": "name", "pass": "pass"})).unwrap()
//         );
//     }
// }