Working with Roles
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.