|
|
@ -2,6 +2,7 @@
|
|
|
|
use super::*;
|
|
|
|
use super::*;
|
|
|
|
use std::collections::HashMap;
|
|
|
|
use std::collections::HashMap;
|
|
|
|
use std::borrow::Cow;
|
|
|
|
use std::borrow::Cow;
|
|
|
|
|
|
|
|
use std::ops::Deref;
|
|
|
|
use bitflags::bitflags;
|
|
|
|
use bitflags::bitflags;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -28,6 +29,101 @@ pub struct User
|
|
|
|
groups: Vec<GroupID>,
|
|
|
|
groups: Vec<GroupID>,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// A reference to a user in a userspace from their ID.
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
|
|
|
|
|
|
pub struct UserRef<'a>(UserID, &'a Userspace);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<'a> UserRef<'a>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/// The ID of this user reference
|
|
|
|
|
|
|
|
#[inline] pub fn id(&self) -> &UserID
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
&self.0
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// The userspace of this user
|
|
|
|
|
|
|
|
#[inline] pub fn space(&self) -> &Userspace
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
self.1
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// # Note
|
|
|
|
|
|
|
|
/// This is for testing purposes only, and should never return `None`.
|
|
|
|
|
|
|
|
#[inline(always)] fn try_user(&self) -> Option<&'a User>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
self.1.users.get(&self.0)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// The user this ID is referring to
|
|
|
|
|
|
|
|
#[inline] pub fn user(&self) -> &User
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
self.try_user().unwrap()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Consume into a reference to the user with the lifetime of the `Userspace` containing it.
|
|
|
|
|
|
|
|
#[inline] pub fn into_user(self) -> &'a User
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
self.try_user().unwrap()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<'a> Deref for UserRef<'a>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
type Target = User;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
|
|
|
|
self.user()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// A reference to a group in a userspace from their group ID.
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
|
|
|
|
|
|
pub struct GroupRef<'a>(GroupID, &'a Userspace);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<'a> GroupRef<'a>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/// The ID of this group reference
|
|
|
|
|
|
|
|
#[inline] pub fn id(&self) -> &GroupID
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
&self.0
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// The userspace of this group ref
|
|
|
|
|
|
|
|
#[inline] pub fn space(&self) -> &Userspace
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
self.1
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// # Note
|
|
|
|
|
|
|
|
/// This is for testing purposes only, and should never return `None`.
|
|
|
|
|
|
|
|
#[inline(always)] fn try_group(&self) -> Option<&'a Group>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
self.1.groups.get(&self.0)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// The group this ID is referring to
|
|
|
|
|
|
|
|
#[inline] pub fn group(&self) -> &Group
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
self.try_group().unwrap()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Consume into a reference to the group with the lifetime of the `Userspace` containing it.
|
|
|
|
|
|
|
|
#[inline] pub fn into_group(self) -> &'a Group
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
self.try_group().unwrap()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<'a> Deref for GroupRef<'a>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
type Target = Group;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
|
|
|
|
self.group()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// A group is a way of setting permissions for a whole set of users.
|
|
|
|
/// A group is a way of setting permissions for a whole set of users.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Users have groups, not the other way around.
|
|
|
|
/// Users have groups, not the other way around.
|
|
|
@ -51,21 +147,6 @@ pub struct Group
|
|
|
|
inherits: Option<Vec<GroupID>>,
|
|
|
|
inherits: Option<Vec<GroupID>>,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Group
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
//TODO: Create bespoke iterator type for this, it's not possible here.
|
|
|
|
|
|
|
|
pub fn inherits<'b, 'a>(&'b self, space: &'a Userspace) -> impl Iterator<Item = GroupID> +'a
|
|
|
|
|
|
|
|
where 'b: 'a
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
match &self.inherits {
|
|
|
|
|
|
|
|
Some(inherits) => inherits.iter()
|
|
|
|
|
|
|
|
.filter_map(|group| group.find_in_space(space).map(|parent| parent.inherits(space))).flatten(),
|
|
|
|
|
|
|
|
None => todo!()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub trait AsEntityId
|
|
|
|
pub trait AsEntityId
|
|
|
|
{
|
|
|
|
{
|
|
|
|
fn entity_id(&self) -> Cow<'_, EntityID>;
|
|
|
|
fn entity_id(&self) -> Cow<'_, EntityID>;
|
|
|
@ -290,4 +371,24 @@ impl Userspace
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ent.entity_id().find_in_space(self).is_some()
|
|
|
|
ent.entity_id().find_in_space(self).is_some()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Get a user reference from their ID
|
|
|
|
|
|
|
|
pub fn user_ref(&self, id: UserID) -> Option<UserRef<'_>>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if self.users.contains_key(&id) {
|
|
|
|
|
|
|
|
Some(UserRef(id, &self))
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
None
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Get a group reference from their ID
|
|
|
|
|
|
|
|
pub fn group_ref(&self, id: GroupID) -> Option<GroupRef<'_>>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if self.groups.contains_key(&id) {
|
|
|
|
|
|
|
|
Some(GroupRef(id, &self))
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
None
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|