I got a lot of questions about this at my TEC session where I demonstrated the work I’ve been doing to configure the FIM Portal as a front-end for BPOS administrative tasks. I don’t think I answered as well as I could have, so I’m going to lay it all out in this post: why creating a Delegation resource type is a better optionĂ‚Â than trying to bend the existing Person resource type to a permissions granting scenario.
The Requirement
I want to be able to handle mailbox permissions in the FIM Portal. Initially I am looking at Full Access, Send As and Send On Behalf, but later I might want to add folder access roles such as for Inbox and Calendar.
Multiple mail users may be given access to a single mailbox – especially in the case of shared mailboxes. Additionally there may be different permission sets applied – so some users get Full Access, while others also get Send As or Send On Behalf. So clearly however we do this it has to allow for multiple delegates with varying permissions.
Doing it all with the Person resource type
Everyone kept asking me “why didn’t you just add extra fields to the Person type?” So let’s work through that scenario.
Schema Modifications
We couldĂ‚Â try a multi-valued Reference attribute called “MailboxDelegate” and just list the delegates there. But this would only work if they all had the exact same permissions. Which they don’t.
So we’ll needĂ‚Â to create three multi-valued Reference attributes: “FullAsDelegate”, “SendAsDelegate” and “SendOnBehalfDelegate” and then list the delegates seperately for each permission.
Now if you think ahead to later adding Inbox and Calendar permissions with their various possible roles (Reviewer, Editor, Author etc) you’ll see this model would lead to a lot of extra attributesĂ‚Â on the Person type, and all sorts of messiness to prevent someoneĂ‚Â being assignedĂ‚Â multiple roles to the same folder… But perhaps you don’t think you’d ever add those extra permissions anyway, so let’s continue with just the three new attributes.
Adding a Delegate
Let’s say you want to grant user JonB both “Full Access” and “Send As” to the mailbox of user KateS. We do a reference lookup for both the fields and add JonB. In the case of Full Access we had another delagate already assigned.
Full Access | Send As | Send On Behalf |
PeteS JonB |
JonB |
Using powershell to assign the permission
To actually assign the permissions in BPOS we use powershell:
Add-MSOnlineMailPermission -Identity target_identity -TrustedUser delegate_identity -GrantFullAccess "true/false" -GrantSendAs "true/false" -GrantSendOnBehalfOf "true/false"
Note that setting one of the permission switches to “false” does not remove the permission. To actually remove a permission you have to use Remove-MSOnlineMailPermission:
Remove-MSOnlineMailPermission -Identity target_identity -TrustedUser delegate_identity -RemoveFullAccess "true/false" -RemoveSendAs "true/false" -RemoveSendOnBehalfOf "true/false"
Powershell Workflow Activity
So you’re going to need a custom activity which runs the BPOS powershell cmdlets for you. I think most people would agree it’sĂ‚Â preferable to have a single “BPOS Powershell Activity” that you can use for all cases, but with this Person object approach I don’t see how that would be possible.
The first problem is the multi-valued nature of the attributes. In the table above we added JonB to “Full Access” when PeteS was already there. If I query that attributeĂ‚Â in an Action workflow I will receive both references, and I won’t be able to tell which is the new one. Do I run the powershell against every name in the list each time? How would this work for Removes? And what about Notifications?
The solution would be to use the Request objectĂ‚Â to find which names have been added or removed. This is clearly more efficient, but leads to its own problems. Unfortunately you can’t (at the moment anyway) directly query the Request object with the OOB Function Evaluator so you will either have to develop another custom workflow activity to do this, or you’ll have to write a specialised activity just for mailbox permissions.
You will also have to consider how changes will work, keeping in mind that a seperate cmdlet is used to remove a permission.
RCDC
The one advantage to this method is you can control the delegation from the target person’s properties, which is where it’s most intuitive to do it. Though as I mentioned above, if you subsequently add ten extra reference fields for the various Inbox and Calendar roles it won’t look so pretty after all.
Creating a Delegation Resource Type
The method I have opted for is to create a new resource type which references the “Delegate” and the “Delegation Target” and then describes the nature of the delegation relationship.
Schema Modifications
My Delegation type has the following attributes:
- DelegationType, indexed string
- Delegate, reference
- DelegationTarget, reference
- FullAccess, boolean
- SendAs, boolean
- SendOnBehalf, boolean
Now straight away you should be able to see how easy it will be for me to add extra options to this list – for instance string types for “Calendar” and “Inbox” which can be represented by a simple drop-down list of the possible roles in the RCDC. I have also included a “DelegationType” in case I want to extend this to other types of permission assignments later.
Powershell Workflow Activity
The best thing about this approach is I’m now only dealing with single-valued attributes – this makes the whole Workflow side a lot easier.
I am doing everything using the one generic BPOS Powershell Activity which I’m also using for other functions sich as password reset and activation.
I have alsoĂ‚Â need only two Workflows – one for Add Permission and one for Remove Permission. In the case of a modify I run both, with the Remove running in the AuthZ phase so I can ensure it runs before the Add. I’m going to describe this properly in another post.
RCDC
As we’re dealing with a different resource type we’ll have to create one or more RCDCs to control the Delegation objects. Unfortunately we can’t add, remove or modify delegations directly from a Person page – though we can at least list them.
Here’s the RCDC code:
<my:Control my:Name="MBDelegations" my:TypeName="UocListView" my:ExpandArea="true" my:Caption="Mailbox Delegations" my:RightsLevel="{Binding Source=rights, Path=ForwardDeliveryOnly}" > <my:Properties> <my:Property my:Name="ColumnsToDisplay" my:Value="DisplayName,PermFullAccess,PermSendAs,PermSendOnBehalf" /> <my:Property my:Name="EmptyResultText" my:Value="There are no delegations according to the filter definition." /> <my:Property my:Name="PageSize" my:Value="20" /> <my:Property my:Name="ShowTitleBar" my:Value="true" /> <my:Property my:Name="ShowActionBar" my:Value="false" /> <my:Property my:Name="ShowPreview" my:Value="false" /> <my:Property my:Name="ShowSearchControl" my:Value="false" /> <my:Property my:Name="EnableSelection" my:Value="false" /> <my:Property my:Name="SingleSelection" my:Value="false" /> <my:Property my:Name="ItemClickBehavior" my:Value=" ModelessDialog " /> <my:Property my:Name="ListFilter" my:Value="/Delegation[(DelegationType='Mailbox') and (DelegationTarget='%ObjectID%')]" /> </my:Properties> </my:Control>
Clearly I could also make this go the other way and it would be just as simple to list all the mailboxes a particular person has access to.
In Conclusion
I’m sticking to my guns that creating the extra Delegation resource type is cleaner, more extensible, and simpler from a Workflow perspective – even though it is not as intuitive from a user pov. The FIM Portal is object-oriented by its very nature and often the immediately obvious approach will lead to far more complexity down the track. As everĂ‚Â it’s important to think through allĂ‚Â possible scenarios and plan for future extensions before locking in to an approach.
This approach makes a lot of sense. I see why you had difficulty fitting this into a 2 min verbal answer.