# Tuesday, 13 February 2007

One obvious thing you might want to do with an authorization system is to get a list of all the operations a given user is granted access to.  This is particularly useful for building up UI elements such as navigation menus.  Nobody likes navigation links that result in Access Denied errors, so it's best to only include in your navigation hierarchy those pages a user can actually execute successfully. 

Here's an example of how to do this with ADAM and AzMan.  It's a little weird, since you have to switch back and forth between an operation's string name, and its integer ID, hence the lookup dictionaries. 

 

   1:  public string[] AvailableOperations(string userId)
   2:  {
   3:      IAuthenticationStore authenticate = AuthenticationStoreFactory.Create();
   4:      UserInfo userInfo = authenticate.LookupUser(userId);
   5:      IAzClientContext2 client = setupClientContext(userId, userInfo);
   6:   
   7:      try
   8:      {
   9:          Dictionary<string, int> opToId = 
  10:      new Dictionary<string, int>(azApp.Operations.Count);
  11:          Dictionary<int, string> idToOp =
  12:      new Dictionary<int, string>(azApp.Operations.Count);
  13:          foreach (IAzOperation op in azApp.Operations)
  14:          {
  15:              opToId.Add(op.Name, op.OperationID);
  16:              idToOp.Add(op.OperationID, op.Name);
  17:              Marshal.ReleaseComObject(op);
  18:          }
  19:   
  20:          List<string> availableOps = new List<string>();
  21:   
  22:          object[] scope = new object[] { (object)"" };
  23:   
  24:          object[] operations = new object[idToOp.Count];
  25:          int i = 0;
  26:          try
  27:          {
  28:              foreach (int opId in idToOp.Keys)
  29:              {
  30:                  operations[i] = (object)opId;
  31:                  i++;
  32:              }
  33:          }
  34:          catch (COMException ex)
  35:          {
  36:              throw new InvalidOperationException("Failed", ex);
  37:          }
  38:          object[] results = (object[])client.AccessCheck("User authentication", scope,
  39:               operations, null, null, null, null, null);
  40:   
  41:          for (int j = 0; j < results.Length; j++)
  42:          {
  43:              if ((int)results[j] == 0)
  44:              {
  45:                  availableOps.Add(idToOp[(int)operations[j]]);
  46:              }
  47:          }
  48:          return availableOps.ToArray();            
  49:      }
  50:      finally
  51:      {
  52:          Marshal.ReleaseComObject(client);
  53:      }
  54:   
  55:  }

I talked about the LookupUser and setupClientContext methods yesterday.  This method returns a handy list of all the operations that the given user can access.  In practice, you probably want to cache the results, although so far it seems to perform very well.  It might prove particularly valuable to cache the ID->Name and Name->ID lookup tables, as they aren't likely to change very often.

Comments are closed.