From: Ian Jackson Date: Sat, 24 Oct 2020 11:50:29 +0000 (+0100) Subject: wip new account etc., adding acctid etc. X-Git-Tag: otter-0.2.0~597 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=0a971bbf2ec629609c98ff50bb44aa26ea07833b;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 00cd76a9..7acaf7a6 100644 --- a/src/accounts.rs +++ b/src/accounts.rs @@ -137,7 +137,7 @@ impl FromStr for AccountName { } } -#[derive(Serialize,Deserialize)] +#[derive(Serialize,Deserialize,Debug)] pub struct AccountRecord { pub nick: String, pub timezone: String, @@ -168,21 +168,64 @@ pub fn save_accounts_now() -> Result<(), InternalError> { panic!("xxx") } +#[derive(Default,Debug)] +struct LookupHelper { + acctid_r: Option, +} + +impl LookupHelper { + #[throws(as Option)] + fn get(&mut self, accounts: &Accounts, account: &AccountName) -> AccountId { + let acctid = *accounts.names.get(account)?; + self.acctid_r = Some(acctid); + acctid + } +/* + fn finish(self) -> impl FnOnce() -> Option<(T, AccountId)> + { + move |got: Result| Some((got.ok()?, self.acctid_r?)) + } +*/ + fn wrap(self, got: Result) -> Option<(T, AccountId)> { + Some((got.ok()?, self.acctid_r?)) + } +} + impl AccountRecord { + pub fn bulk_check(names: &[&AccountName]) -> Vec> { + let accounts = ACCOUNTS.read(); + names.iter().map(|&name|{ + accounts.as_ref()?.names.get(name).map(|&acctid| acctid) + }).collect() + } + pub fn lookup(account: &AccountName, _: Authorisation) - -> Option> { - RwLockReadGuard::try_map( - ACCOUNTS.read(), - |accounts| accounts.as_ref()?.get(account) - ).ok() + -> Option<(MappedRwLockReadGuard<'static, AccountRecord>, + AccountId)> + { + let mut helper : LookupHelper = default(); + helper.wrap( + RwLockReadGuard::try_map(ACCOUNTS.read(), |accounts| { + let accounts = accounts.as_ref()?; + let acctid = helper.get(accounts, account)?; + accounts.records.get(acctid) + }) + ) } - pub fn lookup_mut_caller_must_save(account: &AccountName, - _auth: Authorisation) - -> Option> { - RwLockWriteGuard::try_map( - ACCOUNTS.write(), - |accounts| accounts.as_mut()?.get_mut(account) - ).ok() + + pub fn lookup_mut_caller_must_save + ( account: &AccountName, _auth: Authorisation) + -> Option<(MappedRwLockWriteGuard<'static, AccountRecord>, + AccountId)> + { + let mut helper : LookupHelper = default(); + helper.wrap( + RwLockWriteGuard::try_map(ACCOUNTS.write(), |accounts| { + let accounts = accounts.as_mut()?; + let acctid = helper.get(accounts, account)?; + accounts.records.get_mut(acctid) + }) + ) } #[throws(MgmtError)] @@ -190,18 +233,22 @@ impl AccountRecord { auth: Authorisation, f: F) -> Result - where F: FnOnce(&mut AccountRecord) -> T + where F: FnOnce(&mut AccountRecord, AccountId) -> T { let entry = AccountRecord::lookup_mut_caller_must_save(account, auth) .ok_or(MgmtError::AccountNotFound)?; let old_access = entry.access.clone(); let output = f(entry); let mut ok = true; - if ! Arc::ptr_eq(old_access, entry.access) { -// xxx actually do this + if_chain!{ + if let Some(entry) = entry; + if Arc::ptr_eq(old_access, entry.access); + then { + // xxx actually do this // invalidate_all_tokens_for_account(accid) // .dont_just_questionmark - } + } + }; let ok = if entry.is_some() { save_accounts_now() } else { Ok(()) }; match ok { Ok(()) => Ok(output), diff --git a/src/bin/daemon-otter.rs b/src/bin/daemon-otter.rs index 3ab2fc98..97d5faa2 100644 --- a/src/bin/daemon-otter.rs +++ b/src/bin/daemon-otter.rs @@ -118,6 +118,7 @@ fn main() { shapelib::load()?; + load_accounts()?; load_games()?; let cl = CommandListener::new()?; diff --git a/src/global.rs b/src/global.rs index 912844c4..8676f178 100644 --- a/src/global.rs +++ b/src/global.rs @@ -164,7 +164,7 @@ pub struct TokenRegistry { pub struct InstanceAccessDetails { pub gref : InstanceRef, pub ident : Id, - pub accid : AccountId, + pub acctid : AccountId, } #[derive(Clone,Debug)] @@ -571,7 +571,7 @@ impl InstanceGuard<'_> { .ok_or(MgmtError::PlayerNotFound)? .pst; - let access = AccountRecord::with_entry_mut( + let (access, acctid) = AccountRecord::with_entry_mut( &pst.account, authorised, |acct, acctid| { @@ -585,7 +585,7 @@ impl InstanceGuard<'_> { }) .latest = now; acct.expire_tokens_revealed(); - Ok::<_,MgmtError>(access.clone()) + Ok::<_,MgmtError>((access.clone(), acctid)) })?.map_err(|(e,_)|e)??; if reset { @@ -604,7 +604,8 @@ impl InstanceGuard<'_> { let iad = InstanceAccessDetails { gref : self.gref.clone(), - ident : player + ident : player, + acctid }; self.token_register(token.clone(), iad); @@ -877,9 +878,18 @@ impl InstanceGuard<'_> { } let name = Arc::new(name); - tokens_players.retain( - |&(_,player)| gs.players.contains_key(player) - ); + let (tokens_players, acctids_players) = { + let mut tokens = Vec::with_capacity(tokens_players.len()); + let mut acctnames = Vec::with_capacity(tokens_players.len()); + for (token, player) in tokens_players { if_chain! { + if let Some(name) = gs.players.get(player); + then { + tokens.push((token, player)); + acctnames.push(name); + } + }} + (tokens, AccountRecord::bulk_check(&acctnames)) + }; let g = Instance { gs, iplayers, @@ -902,13 +912,18 @@ impl InstanceGuard<'_> { g.tokens_players.tr.insert(RawToken(token.clone())); } let mut global = GLOBAL.players.write().unwrap(); - for (token, player) in tokens_players.drain(0..) { + for ((token, player), acctid) in + tokens_players.drain(0..) + .zip(acctids_players) + { if_chain!{ + if let Some(acctid) = acctid; let iad = InstanceAccessDetails { + acctid, gref : gref.clone(), ident : player, }; - global.insert(RawToken(token), iad); - } + then { global.insert(RawToken(token), iad); } + } } drop(global); drop(g); GLOBAL.games.write().unwrap().insert(name.clone(), gref.clone()); diff --git a/src/imports.rs b/src/imports.rs index 4dc5b5cd..a673c5d6 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -108,6 +108,8 @@ pub use ordered_float::OrderedFloat; pub use either::{Either,Left,Right}; +pub use if_chain::if_chain; + pub use crate::global::*; pub use crate::gamestate::*; pub use crate::pieces::*; diff --git a/src/session.rs b/src/session.rs index 188f210b..b647d742 100644 --- a/src/session.rs +++ b/src/session.rs @@ -65,6 +65,7 @@ fn session(form : Json) -> Result { let ciad = InstanceAccessDetails { gref : iad.gref.clone(), ident : client, + acctid: iad.acctid, }; let ctoken = record_token(&mut ig, ciad)?; let ig = &mut *ig;