SetAccount(wanted_account) => {
let authorised = authorise_scope(cs, &wanted_account.scope)?;
- cs.account = ScopedName {
- scope: Some(authorised.into_inner()),
- scoped_nmae: wanted_account.scoped_name,
- };
+ cs.account = Some((
+ wanted_account,
+ authorised.therefore_ok(),
+ ));
Fine
},
CreateGame { game, insns } => {
let authorised = authorise_scope(cs, &game.scope)?;
+ let authorised : Authorisation<AccountName> = authorised.therefore_ok();
let gs = crate::gamestate::GameState {
table_size : DEFAULT_TABLE_SIZE,
execute_for_game(cs, &mut ig, insns, MgmtGameUpdateMode::Bulk)
.map_err(|e|{
let name = ig.name.clone();
- Instance::destroy_game(ig)
+ Instance::destroy_game(ig, authorised)
.unwrap_or_else(|e| warn!(
"failed to tidy up failecd creation of {:?}: {:?}",
&name, &e
GamesList(games)
},
- MgmtCommand::AlterGame { name, insns, how} => {
- let name = ScopedName {
- scope: cs.get_scope()?.clone(),
- scoped_name: name
- };
- let gref = Instance::lookup_by_name(&name)?;
+ MgmtCommand::AlterGame { game, insns, how } => {
+ let gref = Instance::lookup_by_name_unauth(&game)?;
let mut g = gref.lock()?;
execute_for_game(cs, &mut g, insns, how)?
},
let authorised : AuthorisedSatisfactory =
authorise_scope(cs, &AS::Server)?;
let authorised = match authorised.into_inner() {
- AS::Server => Authorised::<RawToken>::authorise(),
+ AS::Server => Authorisation::<RawToken>::authorise(),
_ => panic!(),
};
ig.player_access_register_fixed(
struct CommandStream<'d> {
euid : Result<Uid, ConnectionEuidDiscoverEerror>,
desc : &'d str,
- account : Option<(AccountName, Authorised<AccountName>)>,
+ account : Option<(AccountName, Authorisation<AccountName>)>,
chan : MgmtChannel,
who: Who,
}
}
#[throws(MgmtError)]
- fn current_account(&self) -> (&AccountName, Authorised<AccountName>) {
+ fn current_account(&self) -> (&AccountName, Authorisation<AccountName>) {
self.scope.as_ref()
.ok_or(ME::SpecifyAccount)?
.map(|(account,auth)| (account,*auth))
impl CommandStream<'_> {
#[throws(AuthorisationError)]
fn authorised_uid(&self, wanted: Option<Uid>, xinfo: Option<&str>)
- -> Authorised<(Passwd,Uid),> {
+ -> Authorisation<(Passwd,Uid),> {
let client_euid = *self.euid.as_ref().map_err(|e| e.clone())?;
let server_uid = Uid::current();
if client_euid.is_root() ||
client_euid == server_uid ||
Some(client_euid) == wanted
{
- return Authorised::authorise();
+ return Authorisation::authorise();
}
throw!(anyhow!("{}: euid mismatch: client={:?} server={:?} wanted={:?}{}",
&self.desc, client_euid, server_uid, wanted,
#[throws(MgmtError)]
fn authorise_scope(cs: &CommandStream, wanted: &AccountScope)
- -> Authorised<AccountScope> {
+ -> Authorisation<AccountScope> {
do_authorise_scope(cs, wanted)
.map_err(|e| cs.map_auth_err(e))?
}
#[throws(AuthorisationError)]
fn do_authorise_scope(cs: &CommandStream, wanted: &AccountScope)
- -> Authorised<AccountScope> {
+ -> Authorisation<AccountScope> {
match &wanted {
AccountScope::Server => {
- let y : Authorised<(Passwd,Uid)> = {
+ let y : Authorisation<(Passwd,Uid)> = {
cs.authorised_uid(None,None)?;
};
y.therefore_ok()
AccountScope::Unix { user: wanted } => {
struct InUserList;
- let y : Authorised<(Passwd,Uid,InUserList)> = {
+ let y : Authorisation<(Passwd,Uid,InUserList)> = {
struct AuthorisedIf { authorised_for : Option<Uid> };
- const SERVER_ONLY : (AuthorisedIf, Authorised<InUserList>) = (
+ const SERVER_ONLY : (AuthorisedIf, Authorisation<InUserList>) = (
AuthorisedIf { authorised_for: None },
- Authorised::authorised(InUserList),
+ Authorisation::authorised(&InUserList),
);
let pwent = Passwd::from_name(&wanted)
"requested username {:?} not found", &wanted
))
)?;
- let pwent_ok = Authorised::authorised(pwent);
+ let pwent_ok = Authorisation::authorised(pwent);
let ((uid, in_userlist_ok), xinfo) = (||{ <Result<_,AE>>::Ok({
let allowed = BufReader::new(match File::open(USERLIST) {
(AuthorisedIf{ authorised_for: Some(
Uid::from_raw(pwent.uid)
)},
- Authorised::authorised(InUserList),
+ Authorisation::authorised(InUserList),
),
None
))
use authproofs::*;
use authproofs::AuthorisationError;
-pub use authproofs::Authorised;
+pub use authproofs::Authorisation;
+pub use authproofs::Unauthorised;
mod authproofs {
use crate::imports::*;
+ #[derive(Debug,Copy,Clone)]
+ pub struct Unauthorised<T,A> (T, PhantomData<A>);
+ impl<T,A> Unauthorised<T,A> {
+ pub fn of(t: T) -> Self { Unauthorised(t, PhantomData) }
+ pub fn by(self, _auth: Authorisation<A>) -> T { self.0 }
+ }
+ impl<T,A> From<T> for Unauthorised<T,A> {
+ fn from(t: T) -> Self { Self::of(t) }
+ }
+
#[derive(Error,Debug)]
#[error("internal AuthorisationError {0}")]
pub struct AuthorisationError(pub String);
- pub struct Authorised<A> (PhantomData<A>);
+ pub struct Authorisation<A> (PhantomData<A>);
- impl<T> Authorised<T> {
- pub const fn authorise_any() -> Authorised<T> { Authorised(PhantomData) }
- pub const fn authorised(v: &T) -> Authorised<T> { Authorised(PhantomData) }
- }
-
- impl<T> Authorised<T> {
- pub fn therefore_ok<U>(self) -> Authorised<U> { Authorised(PhantomData) }
+ impl<T> Authorisation<T> {
+ pub const fn authorise_any() -> Authorisation<T> {
+ Authorisation(PhantomData)
+ }
+ pub const fn authorised(v: &T) -> Authorisation<T> {
+ Authorisation(PhantomData)
+ }
+ pub fn therefore_ok<U>(self) -> Authorisation<U> {
+ Authorisation(PhantomData)
+ }
}
impl From<anyhow::Error> for AuthorisationError {
}
}
- pub trait AuthorisedCombine {
+ pub trait AuthorisationCombine {
type Output;
- fn combine(self) -> Authorised<Self::Output> { Authorised(PhantomData) }
+ fn combine(self) -> Authorisation<Self::Output> {
+ Authorisation(PhantomData)
+ }
}
- impl<A,B> AuthorisedCombine
- for (Authorised<A>, Authorised<B>) {
- type Output = Authorised<(A, B)>;
+ impl<A,B> AuthorisationCombine
+ for (Authorisation<A>, Authorisation<B>) {
+ type Output = Authorisation<(A, B)>;
}
- impl<A,B,C> AuthorisedCombine
- for (Authorised<A>, Authorised<B>, Authorised<C>) {
- type Output = Authorised<(A, B, C)>;
+ impl<A,B,C> AuthorisationCombine
+ for (Authorisation<A>, Authorisation<B>, Authorisation<C>) {
+ type Output = Authorisation<(A, B, C)>;
}
}
}
}
+impl<A> Unauthorised<InstanceRef, A> {
+ #[throws(InstanceLockError)]
+ pub fn lock(&self) -> Unauthorised<InstanceGuard<'_>, A> {
+ let must_not_escape = self.by(Authorisation::authorise_any());
+ Unauthorised::of(must_not_escape.lock()?)
+ }
+}
+
impl Instance {
/// Returns `None` if a game with this name already exists
#[allow(clippy::new_ret_no_self)]
#[throws(MgmtError)]
- pub fn new(name: InstanceName, gs: GameState, _: Authorised<InstanceName>)
+ pub fn new(name: InstanceName, gs: GameState, _: Authorisation<InstanceName>)
-> InstanceRef {
let name = Arc::new(name);
}
#[throws(MgmtError)]
- pub fn lookup_by_name(name: &InstanceName, _: Authorised<InstanceName>)
+ pub fn lookup_by_name_unauth(name: &InstanceName)
+ -> Unauthorised<InstanceRef, InstanceName> {
+ Unauthorised::of(
+ GLOBAL.games.read().unwrap()
+ .get(name)
+ .ok_or(MgmtError::GameNotFound)?
+ .clone()
+ .into()
+ )
+ }
+
+ #[throws(MgmtError)]
+ pub fn lookup_by_name(name: &InstanceName, auth: Authorisation<InstanceName>)
-> InstanceRef {
- GLOBAL.games.read().unwrap()
- .get(name)
- .ok_or(MgmtError::GameNotFound)?
- .clone()
+ Self::lookup_by_name_unauth(name)?.by(auth)
}
#[throws(InternalError)]
- pub fn destroy_game(mut g: InstanceGuard, _: Authorised<InstanceName>) {
+ pub fn destroy_game(mut g: InstanceGuard, _: Authorisation<InstanceName>) {
let a_savefile = savefilename(&g.name, "a-", "");
let mut gw = GLOBAL.games.write().unwrap();
);
}
- pub fn list_names(scope: Option<&AccountScope>, _: Authorised<AccountScope>)
+ pub fn list_names(scope: Option<&AccountScope>,
+ _: Authorisation<AccountScope>)
-> Vec<Arc<InstanceName>> {
let games = GLOBAL.games.read().unwrap();
let out : Vec<Arc<InstanceName>> =
#[throws(MgmtError)]
pub fn player_access_register_fixed(&mut self,
player: PlayerId, token: RawToken,
- _safe: Authorised<RawToken>
+ _safe: Authorisation<RawToken>
) {
// xxx get rid of this or something ?
self.tokens_deregister_for_id(|id:PlayerId| id==player);
}
#[throws(MgmtError)]
- pub fn player_access_reset(&mut self, player: PlayerId)
+ pub fn player_access_reset(&mut self, player: PlayerId,
+ authorised: Authorisation<AccountName>)
-> Option<AccessTokenReport> {
// xxx call this function when access changes
.pst;
self.save_access_now()?;
- let access = AccountRecord::with_entry_mut(&pst.account, |acct|{
+ let access = AccountRecord::with_entry_mut(
+ &pst.account, authorised,
+ |acct|
+ {
let acct = acct.ok_or(MgmtError::AccountNotFound)?;
let access = acct.access;
let desc = access.describe_html();