From: Ian Jackson Date: Wed, 28 Oct 2020 23:04:11 +0000 (+0000) Subject: wip new account etc., adding acctid etc. X-Git-Tag: otter-0.2.0~585 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=8b9acdeebedacbba7e9a339ae8aa250566699de0;p=otter.git wip new account etc., adding acctid etc. Signed-off-by: Ian Jackson --- diff --git a/src/accounts.rs b/src/accounts.rs index 4ba85afc..feb6e7e4 100644 --- a/src/accounts.rs +++ b/src/accounts.rs @@ -139,12 +139,17 @@ impl FromStr for AccountName { #[derive(Serialize,Deserialize,Debug)] pub struct AccountRecord { + pub account: Arc, pub nick: String, pub timezone: String, pub tokens_revealed: HashMap, - access: Arc, + pub access: AccessRecord, } +#[derive(Serialize,Deserialize,Debug)] +#[serde(transparent)] +struct AccessRecord (Arc); + #[derive(Copy,Clone,Debug,Ord,PartialOrd,Eq,PartialEq)] #[derive(Serialize,Deserialize)] pub struct TokenRevelation { @@ -155,12 +160,17 @@ pub struct TokenRevelation { #[derive(Debug,Default)] #[derive(Serialize,Deserialize)] struct Accounts { - names: HashMap, + names: HashMap, AccountId>, records: DenseSlotMap, } static ACCOUNTS : RwLock> = const_rwlock(None); +impl Deref for AccessRecord { + type Target = Arc; + fn deref(&self) -> &Self::Target { return &self.0 } +} + // xxx load, incl reveleation expiry // xxx periodic token reveleation expiry @@ -168,6 +178,22 @@ pub fn save_accounts_now() -> Result<(), InternalError> { panic!("xxx") } +trait AccountNameOrId : Copy { + fn initial_lookup(self, accounts: &Accounts) -> Option; +} + +impl<'n> AccountNameOrId for &'n AccountName { + #[throws(as Option)] + fn initial_lookup(self, accounts: &Accounts) -> AccountId { + *accounts.names.get(self)? + } +} + +impl AccountNameOrId for AccountId { + #[throws(as Option)] + fn initial_lookup(self, _: &Accounts) -> AccountId { self } +} + #[derive(Default,Debug)] struct LookupHelper { acctid_r: Option, @@ -175,8 +201,9 @@ struct LookupHelper { impl LookupHelper { #[throws(as Option)] - fn get(&mut self, accounts: &Accounts, account: &AccountName) -> AccountId { - let acctid = *accounts.names.get(account)?; + fn get(&mut self, accounts: &Accounts, key: &K) + -> AccountId { + let acctid = key.initial_lookup(accounts)?; self.acctid_r = Some(acctid); acctid } @@ -192,14 +219,17 @@ impl LookupHelper { } impl AccountRecord { - pub fn bulk_check(names: &[&AccountName]) -> Vec> { + pub fn bulk_check(keys: &[K]) -> Vec> { let accounts = ACCOUNTS.read(); - names.iter().map(|&name|{ - accounts.as_ref()?.names.get(name).map(|&acctid| acctid) + keys.iter().map(|&key|{ + let accounts = accounts.as_ref()?; + let acctid = key.initial_lookup(accounts)?; + let _record = accounts.records.get(acctid)?; + Some(acctid) }).collect() } - pub fn lookup(account: &AccountName, _: Authorisation) + pub fn lookup(key: K, _: Authorisation) -> Option<(MappedRwLockReadGuard<'static, AccountRecord>, AccountId)> { @@ -207,14 +237,14 @@ impl AccountRecord { helper.wrap( RwLockReadGuard::try_map(ACCOUNTS.read(), |accounts| { let accounts = accounts.as_ref()?; - let acctid = helper.get(accounts, account)?; + let acctid = helper.get(accounts, key)?; accounts.records.get(acctid) }) ) } - pub fn lookup_mut_caller_must_save - ( account: &AccountName, _auth: Authorisation) + pub fn lookup_mut_caller_must_save + ( key: &K, _auth: Authorisation) -> Option<(MappedRwLockWriteGuard<'static, AccountRecord>, AccountId)> { @@ -222,22 +252,27 @@ impl AccountRecord { helper.wrap( RwLockWriteGuard::try_map(ACCOUNTS.write(), |accounts| { let accounts = accounts.as_mut()?; - let acctid = helper.get(accounts, account)?; + let acctid = helper.get(accounts, key)?; accounts.records.get_mut(acctid) }) ) } #[throws(MgmtError)] - pub fn with_entry_mut(account: &AccountName, - auth: Authorisation, - set_access: Option>, - f: F) - -> Result - where F: FnOnce(&mut AccountRecord, AccountId) -> T + pub fn with_entry_mut + T + >( + key: K, + auth: Authorisation, + set_access: Option>, + f: F + ) + -> Result { let (entry, acctid) - = AccountRecord::lookup_mut_caller_must_save(account, auth) + = AccountRecord::lookup_mut_caller_must_save(key, auth) .ok_or(MgmtError::AccountNotFound)?; if let Some(new_access) = set_access() { diff --git a/src/global.rs b/src/global.rs index 8ee30d11..8e5b1be5 100644 --- a/src/global.rs +++ b/src/global.rs @@ -597,7 +597,7 @@ impl InstanceGuard<'_> { .pst; let (access, acctid) = AccountRecord::with_entry_mut( - &pst.account, authorised, None, + pst.acctid, authorised, None, |acct, acctid| { let access = acct.access; @@ -887,7 +887,7 @@ impl InstanceGuard<'_> { let pu_bc = PlayerUpdates::new_begin(&gs); - let iplayers = { + let iplayers : SecondarySlotMap = { let a = aplayers; a.drain() }.map(|(player, pst)| { @@ -905,15 +905,15 @@ impl InstanceGuard<'_> { let name = Arc::new(name); let (tokens_players, acctids_players) = { let mut tokens = Vec::with_capacity(tokens_players.len()); - let mut acctnames = Vec::with_capacity(tokens_players.len()); + let mut acctids = Vec::with_capacity(tokens_players.len()); for (token, player) in tokens_players { if_chain! { - if let Some(name) = gs.players.get(player); + if let Some(record) = iplayers.get(player); then { tokens.push((token, player)); - acctnames.push(name); + acctids.push(record.pst.acctid); } }} - (tokens, AccountRecord::bulk_check(&acctnames)) + (tokens, AccountRecord::bulk_check(&acctids)) }; let g = Instance { @@ -1079,14 +1079,15 @@ pub fn process_all_players_for_account< > (acctid: AccountId, f: F) { - let games = GLOBAL.games.write().unlock(); + let games = GLOBAL.games.write().unwrap(); for gref in games.values() { - let ig = gref.lock(); - let remove : Vec<_> = ig.iplayers.filter_map(|(player,pr)| { + let c = gref.lock_even_poisoned(); + let remove : Vec<_> = c.g.iplayers.iter().filter_map(|(player,pr)| { if pr.pst.acctid == acctid { Some(player) } else { None } }).collect(); + let ig = InstanceGuard { gref: gref.clone(), c }; for player in remove.drain(..) { - f(player)?; + f(&mut ig, player)?; } } }