lrau 0.1.0

LrAU is an authentication and permission management system for rust.
Documentation
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// The permissions struct stores a vector of
/// `Permissions`
#[derive(Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Permissions {
    #[cfg_attr(feature = "serde", serde(rename = "permissions"))]
    pub vec: Vec<Permission>,
}

impl Permissions {
    /// To create a new permissions you need to specify a vec to use.
    /// If you don't want this you can use the `default` function
    pub fn new(vec: Vec<Permission>) -> Self {
        Self { vec }
    }

    /// This function gets wether the permissions at
    /// `path` have the desired permissions.
    pub fn get_permission(&self, path: &str, r#mut: bool) -> bool {
        // Variable to store the closest path that we have
        // found.
        let mut best = None;
        // Variable to store how many path segments match
        let mut bestn = 0;
        // Splits the required path by path separators
        let path: Vec<&str> = path.split('/').collect();

        // Check the len isn't 0
        if path.is_empty() {
            return false;
        }

        // Begins a loop through the vec
        for i in &self.vec {
            // Gets the path, split by path separators
            let ipath: Vec<&str> = i.path.split('/').collect();
            let mut matches = 0;
            // Loops through the path separators.
            for path_segment in ipath {
                // Checks for a match
                if path_segment
                    == match path.get(matches) {
                        Some(m) => *m,
                        None => break,
                    }
                {
                    matches += 1;
                    // Checks if we have suppassed the required
                    // ammount of matches.
                    if bestn < matches {
                        // And if so makes this the new best.
                        bestn = matches;
                        best = Some(i);
                        // Checks if we already have a full
                        // match.
                        if matches == path.len() {
                            break;
                        }
                    }
                } else if matches == 0 {
                    break;
                }
            }
        }

        // Now check if there even was a match
        if let Some(best) = best {
            // And if so check if its permissions are valid
            return best.auth && (best.r#mut || !r#mut);
        }

        // Return false if in doubt.
        false
    }
}

// Its just easier to do it this way.
impl From<Vec<Permission>> for Permissions {
    fn from(vec: Vec<Permission>) -> Self {
        Self { vec }
    }
}

// Simple default
impl Default for Permissions {
    fn default() -> Self {
        Self { vec: Vec::new() }
    }
}

/// The permission struct stores an individual
/// permission.
/// This contains information about a user accessing
/// certain areas of a program.
///
/// It can be configured in toml like below:
/// First specify an individual element in a
/// `permissions` array.
/// In this you need to specify a path `path`,
/// and wether the user has permission `auth`.
/// Then you can specify mutability `mut`.
///
/// ```toml
/// # Create an array element
/// [[permissions]]
/// # Specify the path
/// path = "/contacts"
/// # Specify the authentication
/// auth = true
/// # Specify if they can mutate the contacts
/// mut = true
/// ```
///
/// This creates a permission in the `/contacts`
/// path, where the user can both read and mutate it.
#[derive(Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Permission {
    pub path: String,
    pub auth: bool,
    #[cfg_attr(feature = "serde", serde(default))]
    pub r#mut: bool,
}

impl Permission {
    /// Creates a new permission.
    pub fn new(path: String, auth: bool, r#mut: bool) -> Self {
        Self { path, auth, r#mut }
    }
}