Thursday, September 13, 2012

Minimum set of search scope attributes to allow users to read other users

This one took me a while to track down.  I created a search scope for managers (and their assistants) to read their direct reports and their direct reports' direct reports in the FIM portal.  (I.e. a user may be read by her manager and her manager's manager; as well as an assistant of either said manager.)  Then I created an MPR to grant permissions for the managers to see these reports.  The trouble is, if you don't want to select All Attributes for Target Resources - Resource Attributes, what is the minimum set of attributes that you have to use in order for this search scope to work?

In fact, I never did find the answer in any official documentation.  Instead, I stumbled upon the answer in a forum answer that came from Brad Turner's impressive tribal knowledge of the product.  Here's Brad's answer:
"Correct, users will need rights to Read the scope and any object returned in the scope including the attributes you list in the ColumnsToDisplay as well as the ObjectID and ObjectType even though it may not be displayed. It's typically ColumnsToDisplay + any attributes in the query filter."
 Also, in case you're wondering, here's the XPath that I used for the search scope:

/Person[Manager = '%LoginID%'] |
/Person[Manager = /Person[Manager ='%LoginID%']] |
/Person[Manager = /Person[Assistant = '%LoginID%']] |
/Person[Manager = /Person[Manager = /Person[Assistant = '%LoginID%']]]

Wednesday, September 12, 2012

Hide Advanced Search button on Users page

Here's how you can hide the Advanced Search button on the default Users page in the FIM portal.

There are a few things to keep in mind:
  • You have to edit the ASPX page in Sharepoint designer.  This is not a supported change!
  • You can hide the ASP control by inserting some Javascript on the page.
  • You must call the Javascript upon load as well as upon AJAX response.
And here are the steps to accomplish it:
  • Open the IdentityManagement site in Sharepoint Designer.
  • Make a backup of aspx/users/AllPersons.aspx.
  • Add the following javascript:
    • Note that it's very important that the Javascript code go inside the tags.
<%@ Page masterpagefile="~masterurl/custom.master" language="C#" inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" meta:progid="SharePoint.WebPartPage.Document"  UICulture="auto" Culture="auto" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Import Namespace="Microsoft.SharePoint" %> <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<asp:Content ContentPlaceHolderID="PlaceHolderTitleBar" runat="server">
<script type="text/javascript">
    function hideElementByClass(matchClass) {
        var elems = document.getElementsByTagName('*'), i;
        for (i in elems) {
            if ((" " + elems[i].className + " ").indexOf(" " + matchClass + " ") > -1) {
                elems[i].style.display = 'none';
    function hideAdvancedSearch() {
    window.onload = function () {
// -->
<asp:Content id="content1" ContentPlaceHolderID="PlaceHolderMain" runat="server">
 <IdentityManagement:PersonList id="PersonList"  width="100%" height="100%" runat="server"/>