chiark / gitweb /
cmdlistener: authorise_by_account
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 30 May 2021 12:24:30 +0000 (13:24 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 30 May 2021 12:44:07 +0000 (13:44 +0100)
Do not re-authorise the account.  Instead, check what we got from
previous SelectAccount.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
daemon/cmdlistener.rs

index 959753c2a51e63ae0ba2e59697a12a7d0f3ce9f6..f2ca5baff53e38cfd23732ad7620a47b9f8d183f 100644 (file)
@@ -61,7 +61,7 @@ enum AuthState {
 struct AccountSpecified {
   notional_account: AccountName, // might not exist
   cooked: String, // account.to_string()
-  auth: Authorisation<AccountName>,
+  auth: Authorisation<AccountName>, // but we did check permissions
 }
 
 enum PermissionCheckHow {
@@ -1691,10 +1691,28 @@ fn authorise_for_account(
 fn authorise_by_account(cs: &CommandStreamData, ag: &AccountsGuard,
                         wanted: &InstanceName)
                         -> Authorisation<InstanceName> {
-  let account = &wanted.account;
-  ag.check(account)?;
-  authorise_for_account(cs, ag, account)?
-    .therefore_ok()
+  let current = cs.current_account()?;
+  ag.check(&current.notional_account)?;
+
+  if let Some(y) = cs.superuser() {
+    return y.therefore_ok();
+  }
+
+  if &current.notional_account == &wanted.account {
+    current.auth.map(
+      // Not executed, exists as a proof.
+      // we need this Box::leak because map wants us to return a ref
+      // borrowing from the incoming subject, which would imply narrowing
+      // of scope and of course we are widening scope here.  We're
+      // saying that the account can access all its games.
+      |account: &AccountName| Box::leak(Box::new(InstanceName {
+        account: account.clone(),
+        game: wanted.game.clone(),
+      }))
+    )
+  } else {
+    throw!(ME::AuthorisationError);
+  }    
 }
 
 #[throws(MgmtError)]