}
/// Record of acess for a player. Newtype prevents mutable access
-/// without invalidating old tokens.
+/// without invalidating old tokens and permissions check.
#[derive(Serialize,Deserialize,Debug)]
#[serde(transparent)]
pub struct AccessRecord (Arc<dyn PlayerAccessSpec>);
impl AccessRecord {
pub fn new_unset() -> Self{ Self( Arc::new(PlayerAccessUnset) ) }
-}
-impl From<Box<dyn PlayerAccessSpec>> for AccessRecord {
- // xxx get rid of this From impl and do a server permission check
- fn from(spec: Box<dyn PlayerAccessSpec>) -> Self { Self(spec.into()) }
+ #[throws(MgmtError)]
+ pub fn from_spec(spec: Box<dyn PlayerAccessSpec>,
+ superuser: Option<AuthorisationSuperuser>)
+ -> AccessRecord {
+ spec.check_spec_permission(superuser)?;
+ AccessRecord(spec.into())
+ }
}
//---------- AccountsGuard and lookup ----------
const DEFAULT_POS_START : Pos = PosC([20,20]);
const DEFAULT_POS_DELTA : Pos = PosC([5,5]);
+pub type AuthorisationSuperuser = Authorisation<authproofs::Global>;
+
pub struct CommandListener {
listener : UnixListener,
}
euid : Result<Uid, ConnectionEuidDiscoverEerror>,
desc : &'d str,
account : Option<AccountSpecified>,
- superuser: Option<Authorisation<authproofs::Global>>,
+ superuser: Option<AuthorisationSuperuser>,
chan : MgmtChannel,
who: Who,
}
CreateAccont(AccountDetails { account, nick, timezone, access }) => {
let mut ag = AccountsGuard::lock();
let auth = authorise_for_account(cs, &ag, &account)?;
- let access = access.map(Into::into)
+ let access = cs.accountrecord_from_spec(access)?
.unwrap_or_else(|| AccessRecord::new_unset());
let nick = nick.unwrap_or_else(|| account.to_string());
let account = account.to_owned().into();
let auth = get_auth(self, ag, ig, how, p.into())?;
(ig.by_mut(auth), auth)
}
+
+ #[throws(MgmtError)]
+ fn accountrecord_from_spec(&self, spec: Option<Box<dyn PlayerAccessSpec>>)
+ -> Option<AccessRecord> {
+ spec
+ .map(|spec| AccessRecord::from_spec(spec, self.superuser))
+ .transpose()?
+ }
+
}
#[throws(MgmtError)]
pub use implementation::PlayerAccessSpec;
+type ME = crate::commands::MgmtError;
+
//---------- common types ----------
pub type Coord = isize;
fn override_token(&self) -> Option<&RawToken> {
None
}
+ #[throws(MgmtError)]
+ fn check_spec_permission(&self, _: Option<AuthorisationSuperuser>) {
+ }
fn server_deliver<'t>(&self,
_gpl: &GPlayerState,
_ipl: &IPlayerState,
#[typetag::serde]
impl PlayerAccessSpec for FixedToken {
+ #[throws(MgmtError)]
+ fn check_spec_permission(&self, auth: Option<AuthorisationSuperuser>) {
+ auth.ok_or(ME::SuperuserAuthorisationRequired)?
+ }
fn override_token(&self) -> Option<&RawToken> {
Some(&self.token)
}