Exchange offers 16 folder-based roles named, coincidentally, Role1 through Role16 . By offering folder-based roles, you can set up roles per application and you do not need to modify Active Directory to create your roles. This gives workflow developers (or any developers, for that matter) the flexibility for using roles without requiring Active Directory permissions. The code for creating roles is beyond the scope of this chapter, but there is an excellent whitepaper on the Microsoft Exchange Developer Center at http://msdn.microsoft.com/exchange . The sample files for the book include Visual C++ code to work with and create folder-based roles. Also included is the compiled C++ code in a DLL so you can create roles without having to compile the source. The following code uses the DLL to create a new role and add users to that role:
Dim strDomain As String strDomain = "YOURDOMAIN" Dim strURL As String Dim rec As ADODB.Record Dim fld As ADODB.Field Dim rol As Role Dim sidAdmin As Sid Dim sidUser1 As Sid Dim sidUser2 As Sid Dim varRole As Variant Dim isid As Long 'Open a record and get access to PR_XMT_SECURITY_ROLE_1 strURL = "file://./backofficestorage/" & strDomain _ & "/public folders/NewFolder" Set rec = New ADODB.Record rec.Open strURL, , adModeReadWrite 'Create some sid's Set sidAdmin = New Sid sidAdmin.NT4CompatibleName = "Administrator" Set sidUser1 = New Sid sidUser1.NT4CompatibleName = "thomriz" Set sidUser2 = New Sid sidUser2.NT4CompatibleName = "user1" 'Create a role object with these sid's as members Set rol = New Role rol.Add sidAdmin rol.Add sidUser1 rol.Add sidUser2 varRole = rol.OpaqueData 'Set as value for role property rec.Fields.Append "http://schemas.microsoft.com/mapi/proptag/x3D250102", _ adVarBinary, Len(varRole), , varRole rec.Fields.Update rec.Close Set rec = Nothing 'Reopen Set rec = New ADODB.Record rec.Open "file://./backofficestorage/" & strDomain _ & "/public folders/NewFolder" Set fld = rec.Fields("http://schemas.microsoft.com/" _ & "mapi/proptag/x3D250102") 'Get the role object Set rol = New Role rol.OpaqueData = fld.Value 'Display what's there Debug.Print rol.Count For isid = 0 To rol.Count - 1 Dim sidT As Sid Set sidT = rol.Member(isid) Debug.Print sidT.NT4CompatibleName Next isid
Unfortunately, you cannot currently rename the 16 built-in roles. When you work with the workflow engine, you normally work with roles using the ItemAuthors and ItemReaders collections, which we discussed earlier. Therefore, you need to know what the different roles were used for in your application. One way to determine this is to use some form of lookup in your code. For example, you can store the role name in a multivalue property in the corresponding index in the array of values.
Once you have roles established in your workflow applications, using them is very straightforward. Instead of passing usernames to the workflow functions, you can pass roles. The following example uses Role1 , which corresponds to an approver's role in the workflow. It sets the ItemAuthors collection to Role1 and clears the ItemReaders collection. It also uses the IsUserInRole function to see if the person attempting to approve the item is in the Role1 role. If she is not, the state transition will fail.
Sub SetItemAuthors() WorkflowSession.ItemAuthors.Add "Role1", 1 End Sub Sub SetItemReaders() 'Clear the collection WorkflowSession.ItemReaders.Clear WorkflowSession.ItemReaders.Add "Role1", 1 End Sub Function CheckRole(strName, strRole) CheckRole = WorkflowSession.IsUserInRole(strName, strRole) End Function
As you can see in the code, it is easy to use roles once you know how. The DLL makes it easy to create roles for your applications that you can leverage and makes management of the membership of roles easy. Plus, with the built-in support for roles in the workflow engine, you should take advantage of roles when it makes sense for your applications ”such as when you do not have write permissions to Active Directory.