chiark / gitweb /
new command api etc.
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 17 Oct 2020 17:00:48 +0000 (18:00 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 17 Oct 2020 17:00:48 +0000 (18:00 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/cmdlistener.rs
src/commands.rs
src/global.rs
src/spec.rs

index 39370b232c08cf8e314c8002f9701cbc99972e65..bffcb9c5d13e79756ddb16a6c4206a57fc6054cb 100644 (file)
@@ -182,6 +182,7 @@ fn execute_game_insn(cs: &CommandStream,
     },
 
     Insn::ListPieces => readonly(ig, {
+      // xxx put something in log
       let pieces = ig.gs.pieces.iter().map(|(piece,p)|{
         let &PieceState { pos, face, .. } = p;
         let pinfo = ig.pieces.get(piece)?;
index 6a81118d63e37108c9879c29d90f84ffbadb24d1..6666c82b89c9f2989b12cda6c9dbae2e781e76de 100644 (file)
@@ -7,19 +7,62 @@ use crate::imports::*;
 #[derive(Debug,Serialize,Deserialize)]
 pub enum MgmtCommand {
   Noop,
-  SetScope(AccountScope),
-  CreateGame { name: String, insns: Vec<MgmtGameInstruction> },
-  ListGames { all: Option<bool>, },
+
+  CreateAccont(AccountDetails),
+  UpdateAccont(AccountDetails),
+  DeleteAccount(AccountDetails),
+
+  SetAccount(ScopedName),
+
+  CreateGame {
+    game: ScopedName,
+    insns: Vec<MgmtGameInstruction>,
+  },
+  ListGames {
+    all: Option<bool>, // in same scope by default
+  },
   AlterGame {
-    // todo option scope, access control
-    name: String, insns: Vec<MgmtGameInstruction>,
+    game: ScopedName,
+    insns: Vec<MgmtGameInstruction>,
     how: MgmtGameUpdateMode,
   },
+
   LibraryListByGlob {
     glob: shapelib::ItemSpec,
   },
 }
 
+//---------- Accounts file ----------
+
+#[derive(Debug,Serialize,Deserialize)]
+pub struct AccountDetails {
+  pub account: ScopedName,
+  pub nick: String,
+  pub timezone: Option<String>,
+  #[serde(flatten)]
+  pub access: Option<Box<dyn PlayerAccessSpec>>,
+//  pub invite: Acl<AccountPerm>,   todo
+}
+
+//#[derive(Debug,Clone,Copy,Serialize,Deserialize)]
+//enum AccountPerm {
+//  InviteToGame,
+//  GameRunnerResetToken,
+//}
+
+#[derive(Debug,Serialize,Deserialize)]
+struct FixedToken { token: RawToken }
+
+#[derive(Debug,Serialize,Deserialize)]
+struct TokenOnStdout;
+
+//#[derive(Debug,Serialize,Deserialize)]
+//struct TokenByEmail { email: String };
+// xxx ^ implement this
+// xxx ^ 
+
+
+
 #[derive(Debug,Serialize,Deserialize)]
 pub enum MgmtResponse {
   Fine,
@@ -39,21 +82,23 @@ pub enum MgmtGameInstruction {
   AddPieces(PiecesSpec),
   DeletePiece(PieceId),
 
-  AddPlayer(MgmtPlayerState),
-  RemovePlayer(PlayerId),
   ResetPlayerAccesses { players: Vec<PlayerId> },
   ReportPlayerAccesses { players: Vec<PlayerId> },
   SetFixedPlayerAccess { player: PlayerId, token: RawToken },
+
+  AddPlayer(MgmtPlayerDetails),
+  UpdatePlayer(MgmtPlayerDetails),
+  RemovePlayer(ScopedName),
+  BlockPlayer(String),
 }
 
-// xxx self-add players
-// xxx permission system
 // xxx facilitator name?
 
 #[derive(Debug,Serialize,Deserialize)]
-pub struct MgmtPlayerState {
+pub struct MgmtPlayerDetails {
+  pub account: ScopedName,
   pub timezone: Option<String>,
-  #[serde(flatten)] pub st: PlayerState,
+  pub nick: Option<String>,
 }
 
 #[derive(Debug,Serialize,Deserialize)]
@@ -70,7 +115,13 @@ pub enum MgmtGameResponse {
 #[derive(Debug,Clone,Serialize,Deserialize)]
 pub struct MgmtGameResponseGameInfo {
   pub table_size: Pos,
-  pub players: PlayerMap,
+  pub players: DenseSlotMap<PlayerId, MgmtPlayerInfo>,
+}
+
+#[derive(Debug,Clone,Serialize,Deserialize)]
+pub struct MgmtPlayerInfo {
+  pub account: ScopedName,
+  pub nick: String,
 }
 
 #[derive(Debug,Clone,Serialize,Deserialize)]
index 676888f8ea9fe8a4b2a68e55b34a0fe7f0695b64..5522e281ade342acaec9c7d5f6888c84996966c8 100644 (file)
@@ -497,6 +497,7 @@ impl InstanceGuard<'_> {
   #[throws(MgmtError)]
   pub fn players_access_reset(&mut self, players: &[PlayerId])
                              -> Vec<RawToken> {
+      // xxx disconnect everyone when token changes
     for &player in players {
       self.c.g.gs.players.get(player).ok_or(MgmtError::PlayerNotFound)?;
     }
index 5002452e5db90a98d789c050263cd1bf238f1dc3..7c93727a2dc43c9f63363c73ba25ef0dec53c11d 100644 (file)
@@ -55,23 +55,26 @@ display_as_debug!{SpecError}
 
 #[derive(Debug,Serialize,Deserialize)]
 pub struct TableSpec {
-  pub players : Vec<PlayerSpec>,
-  pub timezone: Option<String>, // default for player timezones
+  pub players : Vec<ScopedName>,
+  pub acl : Acl<TablePermission>
 }
 
-#[derive(Debug,Serialize,Deserialize)]
-pub struct PlayerSpec {
-  pub nick: String,
-  pub timezone: Option<String>,
-  #[serde(flatten)]
-  pub access: Option<Box<dyn PlayerAccessSpec>>,
-}
+pub type Acl<Perm> = Vec<AclEntry<Perm>>;
 
-#[derive(Debug,Serialize,Deserialize)]
-struct FixedToken { token: RawToken }
+#[derive(Debug,Clone,Serialize,Deserialize)]
+pub struct AclEntry<Perm> {
+  pub account_glob: String,
+  pub allow: HashSet<Perm>,
+  pub deny: HashSet<Perm>,
+}
 
-#[derive(Debug,Serialize,Deserialize)]
-struct TokenOnStdout;
+#[derive(Debug,Clone,Copy,Serialize,Deserialize)]
+enum TablePermission {
+  AddPlayer,
+  ChangePieces,
+  RemovePlayer,
+  ChangeACL,
+}
 
 //---------- Game TOML file ----------