Provides a method for securing different parts of a browser based InfoPath form based on the current logged on users security rights.
Description:
The process will read the permissions from the specified list/library and populate a "Roles" list with each user that has permissions to the list. The workflow will drill down into each group listed and extract the users of these groups. The groups will be used as the user's role in Infopath. Any individually listed users in the permissions will not have a assigned group and as such cannot have any role verified to them. It is then recommended to put all users into a group for the permissions for the desired list/library.
The extracted roles can then be retrieved in InfoPath for use in hidding sections, buttons, etc.. based on if the current logged on user is a member of the specified role.
Installation:
Before the application of the following steps, the InfoPath form library that you wish to use this on should be created and published to the SharePoint environment. It's properites will be needed for configuration of the workflow. The "Roles" list should be created on the same site as the list you wish to read permissions from.
Create the Roles List:
1) Create a custom list named "Roles" on the site you wish to apply InfoPath role based security too.
2) Select No to "Display this list in the Quick Launch?"
3) Create two additional fields, "UserID" & "Group". Both of which are single line of text.
4) Add a new record to the list. Enter "Control" for each field. Your list view should look like the following image (without the names...those come later)
NOTE: The Roles list is now created. The first record is a control record. This is required and must NEVER be removed from the list. If it is, the list must be deleted and these steps repeated.
Apply the Workflow:
1) Save the "GetRoles.nwf" file (Attached to this post) to your desktop and unzip.
2) From the "Roles" list, click on the "Settings" drop down and select "Create Workflow".
3) When the "Select a Workflow Template" screen appears click the "Cancel" button.
4) Click on the "Actions" drop down and select "Import" -> "From File".
5) Click the "Browse" button and navigate to where you saved the "GetRoles.nwf" file and click the "Open" button.
6) Click on the "Import" button.
7) For both of the Web Service actions in the workflow, please use your admin login credentials.
NOTE: I am not sure if any other paths need to be changed as I have not ported to different servers. You may have to do some changing of options.
8) Please read the below "Configuration of Workflow" section. When you are done configuring the workflow then click the "Actions" drop down and select "Publish".
Configuration of Workflow:
There are several options that can/need to be configured for this workflow.
Optional, but Recommended-ID of Infopath Form Library:
The default library ID for where the workflow is read the permissions information must be supplied. There is an opportunity to change this value when you start the workflow (see below), but it is recommended that you enter the value now so that it is saved as the default in the case that you ever have to stop and restart the workflow. Otherwise, if you restart the workflow it will try to acccess this default list ID if you forget to change it.
Description:
Each list/library has a unique identifier in the SharePoint environment. The following is a set of instructions on how to retrieve this ID for use in scripts, workflows and web services.
Instructions:
1) Go to the list/library you wish to retrieve the ID for.
2) Click on the "Settings" drop down and select "List (Library) Settings".
3) In the URL at the top of the screen, note the fragment that starts "?List=". The List ID is located after this (as seen in the highlighted section below).
Note: The ID is in URL Encoded format. To decode the ID you can manually replace the characters identified with the "%" sign using the "URL Encoding Table" link above or copy the sting into the Decode section using the "URL Encode/Decode" link above. For example, the "%7B" represents the "{" character, "%2D" represents the "-" character and "%7D" represents "}" in the image above.
1) Click the "Settings" drop down and select "Start Data".
2) Click on the "ListID" variable.
3) Enter your list/library ID into the "Default value" field and click the "Add" button.
Optional-Workflow Name:
The workflow name can be modified to reflect the current type of Roles list that is being executed. This will allow for muliple instances and configurations of the workflow to run on the same site.
1) Click the "Settings" drop down and select "Title and Description".
2) In the default name, the "- Projects" was used to specify the library to which this workflow was reading the permissions list. This (and the description) may be changed to whatever is desired.
3) Click the "Save" button.
Configure the Execution Time:
1) Go back to the main page for the "Roles" list.
2) Click the drop down next to the "Control" text in the "Name" column and select "Schedule Workflows".
3) Click on the "Add Schedule" button.
4) This is the screen where you will configure how often to run the GetRoles workflow and refresh the data. It is recommended that the default be set to repeat dailey in case any changes to the security permissions have been changed (highlighted below). Also, make sure to select that the schedule runs "Indefinite". This is important or your updates will end unexpectedly.
5) At this point you have the opportunity to change the default "ListID" if desired. Please see the description in the "Optional, but Recommended-ID of Infopath Form Library:" section about stopping and restarting the workflow.
6) Click the "Save" button
Note: Your workflow will now start on the "Control" record on the specified date and time and will continue to update according to the parameters entered on the screen shot above.
Creation of Views:
A view for each role, that needs to be checked, needs to be created for InfoPath to read from. This is due to the fact that a user may be a member of several groups.
1) In the upper right corner of the "Roles" list, click the drop down arrow next to the "All Items" view and click "Create View".
2) Change the Filter criteria for the view based on the desired role. The filter value must match exactly the SharePoint group name that was setup for use in the permissions.
3) Click the "OK" button.
4) Make sure the new view displays expected results
5) Repeat the above steps for each group that will need to be checked in the InfoPath form.
List Security:
Security on the "Roles" list should be set up to allow only an administrator to start/stop the workflow and read only access for everyone else. Read access is required so that the InfoPath form can access the data for the current logged on user whom it is trying to retrieve roles for.
1) From the main screen of the "Roles" list, click the "Settings" drop down and select the "List Settings" option.
2) Click on the option under the "Permissions and Management" column for ""Permissions for this list".
3) By default the list inherits permissions from the main page of the site. Click the "Actions" drop down and select "Edit Permissions". This will break permisions for this list. When the warning box appears, click "OK".
4) Remove all permission except whomever is the Administrator (It is recommended this is either the Site Collection Administrator or Content Owner Administrator) and "NT AUTHORITY\authenticated users". The Admin group can be given "Full" or "Contribute" permissions. "NT AUTHORITY\authenticated users" should be given "Read" permissions.
Use in InfoPath:
The following is a list of instructions on how to implement the "Roles" list in InfoPath:
Hidden Fields:
Some fields need to be set up in InfoPath to receive our Role data. Our "Hidden Fields" are those elements that are in the forms data source, but not displayed on the form itself. they are inserted in a group for organizational purposes. For the purpose of this example, my data source fields are set up as the following:
The "Role-" fields are "True/False (Boolean)" fields with a default value of "FALSE". These fields represent each role that a user can have (that we are checking for).
The "CurrentUser" field is "Text" field with no default value. This will store the information (ID) of the current logged on user.
Data Connections:
Roles:
A secondary data connection will need to be set up for each role.
Description:
Creating a secondary data connection to a view allows for the filtering of the data returned to InfoPath. This is most useful in list/libraries that contain large amounts of data so that only a sub set of the data is actually retrieved and sent to InfoPath. This also allows InfoPath to take advantage of SharePoints sorting and filtering features.
Instructions:
The instructions start from having the InfoPath form that you wish to create the data connection in open and in design mode.
1) Clicking on "Tools" in the menu bar and selection "Data Connections...".
2) Click on the "Add" button.
3) Click on the option for "Create a new connection to" and select "Receive data". Click the "Next" button.
4) Select the option for "XML document" and click "Next".
5) In the text box a string of the following structure should be entered:
http://< your site>/_vti_bin/owssvr.dll?Cmd=Display&List=<Roles List ID>&View=<View ID of Role>&XMLDATA=TRUE
Example:
If you do not know how to get the List ID, click here. Instructions for finding the view ID can be found by clicking here.
6) Click "Next".
7) Select the option to "Access the data from the specified location" and click "Next".
Note: Do not check the option for "Store a copy of the data for offline use". This will cache your data and make the security that you are applying inaccurate.
8) Enter a name for your data connection.
Note: When entering a name for your data connection, I recommend something similar to:
Role-<Group Name>
Example:
Role-01G_GlobalMaint
This will provide a descriptive name that is easy to decipher if changes need to be made later.
9) Check mark the box for "Automatically retreive data when form is opened".
10) Click the "Finish" button.
Repeat this process for each view that was created for each role (See "Creation of Views:" section).
Current User:
Instructions to create a data connection to get the current users information can be found here:
InfoPath-GetCurrentUserbyName
Instructions on how to have a secondary data connection to get a users information from Active Directory.
Description:
Creating a secondary data connection to a view allows for the filtering of the data returned to InfoPath. This is most useful in list/libraries that contain large amounts of data so that only a sub set of the data is actually retrieved and sent to InfoPath. This also allows InfoPath to take advantage of SharePoints sorting and filtering features.
Instructions:
Setup Connection:
The instructions start from having the InfoPath form that you wish to create the data connection in open and in design mode.
1) Clicking on "Tools" in the menu bar and selection "Data Connections...".
2) Click on the "Add" button.
3) Click on the option for "Create a new connection to" and select "Receive data". Click the "Next" button.
4) Select the option for "Web Service" and click "Next".
5) In the text box a string of the following structure should be entered:
http://< your site collection>/_vti_bin/userprofileservice.asmx?wsdl
Example:
6) Click "Next".
7) Select the option to "GetUserProfileByName" and click "Next".
8) Leave the defaults for the parameter page and click "Next".
9) Do not check the option to "Store a copy of the data in the form template" as this can pull inaccurate user data depending on the connectivity status of the form.
10) Enter a name for your data connection.
11) Check mark the box for "Automatically retreive data when form is opened".
12) Click the "Finish" button.
Retrieve User Information:
In order to get information from the secondary data connection that retrieves the users Active Directory information perform the following steps:
1) In the "Data Source" section of the InfoPath form, create a text element to store the data that we are to retrieve.
2) Double-Click the field to go to it's properties.
3) In the "Default Value" section click the formula ("Fx") button next to the "Value" text box.
4) Click on the "Insert a Field or Group..." button.
5) Click the drop down the "Data Source" box and select your "GetUserProfileByName" data connection. (In this example, mine is named "GetUserProfileByName-Requestor").
6) Navigate down the "dataFields" branch and select the "Value" field as shown in the picture above.
7) Click on the "Filter Data..." button.
8) Click on the "Add" button to add a filter to retrieve the data specific to your needs.
9) In the first drop down box, select the "Name" field.
10) Leave the second box set to "is equal to".
11) Drop down the third box and select "type text...". This will allow you to enter the name of the Active Directory field you wish to retrieve for this selected user. So for example:
will retreive the current users ID (domain\userID). See the "Filter Options" section below for a list of standard Active Directory fields that can be filtered on.
12) Continue to click "OK" until you get back to the form.
Modify to Retreive a Specified User:
Active Directory information may be retreived for users other than the current logged on user. To do this:
1) Open the form, in design mode. A separate instance of the GetUserProfileByName is recommended for this functionality. See the above steps from the "Instructions" section. However, in step #11 do not check the option to "Automatically retreive data when form is opened".
2) Choose the field or button you wish to trigger this action and go to it's properties.
3) Click on "Rules"
4) Click on the "Add" button to add a rule entry.
5) Give your rule a descriptive name and/or a conditional statement if one applies.
6) Click on the "Add Action" button.
7) For the "Action" select "Set a field's value".
8) For the "Field" click the select button next to the text box. Drop down the "Data Source" box and select your "GetUserProfileByName" data connection. (In this example, mine is named "GetUserProfileByName-Requestor").
9) Navigate down the "queryFields" branch until you get to "AccountName". Click on it and then click "OK".
10) In the "Value" box, insert a field or value that is of the format domain/userID. This can be retrieved a number of ways, including lookup to a SharePoint list.
11) Click "OK".
12) Click on the "Add Action" button to add another action to this Rule.
13) In "Action", select "Query using a data connection".
14) For the "Data Connection" field, choose your data connection that was selected in step #8 (mine was "GetUserProfileByName-Requestor").
15) Continue to click the "OK" buttons until you arrive back at the form.
Whenever an action is taken on your field/button that the rule was applied to, the data connection will go out and retreive Active Directory information on the user supplied.
Filter Options:
Below are a list of standard Active Directory fields that can be accessed using the filter method above:
UserProfile_GUID
AccountName
FirstName
LastName
PreferredName
WorkPhone
Office
Department
Title
Manager
AboutMe
PersonalSpace
PictureURL
UserName
QuickLinks
WebSite
PublicSiteRedirect
SPS-Dotted-line
SPS-Peers
SPS-Responsibility
SPS-Skills
SPS-PastProjects
SPS-Interests
SPS-School
SPS-SipAddress
SPS-Birthday
SPS-MySiteUpgrade
SPS-DontSuggestList
SPS-ProxyAddresses
SPS-HireDate
SPS-LastColleagueAdded
SPS-OWAUrl
SPS-ResourceAccountName
SPS-MasterAccountName
Assistant
WorkEmail
CellPhone
Fax
HomePhone
NOTE: The "AccountName" filter should be applied to the retrieved value to get the users login ID into a field value.
Form Configuration:
A few rules need to be set up to execute when the form opens. To enter these Form Option Rules:
1) Click on "Tools" in the menu bar and select "Form Options...".
2) In the "Category" pane, click on "Open and Save".
3) In the "Open Behavior" section, click on "Rules...".
Several rules are needed for the configuration of the Roles.
Clear Roles:
The Roles need to be cleared each time the form is opened. Otherwise, the form will retain the roles of the last person to save the form.
1) Click the "Add..." button.
2) Enter "ClearRoles" in the name field for this rule.
3) Click the "Add Action..." button.
4) Set the "Action" to "Set a field's value".
5) Click the field selector button next to the text box for the "Field" entry.
6) Navigate through your field structure until you find one of the True/False (Boolean) fields that were set up in the "Hidden Fields" section (above) and started with "Role-" in the example.
7) Click the "OK" button.
8) Click the function button ("Fx") next to the "Value" text box.
9) Click the "Insert Function" button.
10) Click the "false" entry in the "Functions" pane on the right side.
11) Click "OK" three times until arriving back at the "Rules" page.
12) Repeat the process to clear out the role for each variable that was created. In the example used in the "Hidden Fields" section, this would be done three times.
Set Roles:
There are two rules set up for each Role. One to set the Role value to True and one for False.
1) Click the "Add..." button to create a new rule.
2) Type in a name for your Rule
3) Click the "Set Condition..." button.
4) In the first drop down box, select "The expression"
5) In the remaining text box, an XPath conditional expression is to be entered. It is of the following format:
False Condition (User not in Role):
xdXDocument:GetDOM("<Name of your Data Connection for the Role you are comparing>")/xml/rs:data/z:row/@ows_Group[../@ows_UserID = xdXDocument:get-DOM()<Your field where you are storing the current users ID ("CurrentUser" in "HiddenFields" example)> = ""
Example:
xdXDocument:GetDOM("Role-01G_GlobalMaint")/xml/rs:data/z:row/@ows_Group[../@ows_UserID = xdXDocument:get-DOM()/my:myFields/my:HiddenFields/my:CurrentUser] = ""
True Condition (User in Role):
xdXDocument:GetDOM("<Name of your Data Connection for the Role you are comparing>")/xml/rs:data/z:row/@ows_Group[../@ows_UserID = xdXDocument:get-DOM()<Your field where you are storing the current users ID ("CurrentUser" in "HiddenFields" example)> != ""
Example:
xdXDocument:GetDOM("Role-01G_GlobalMaint")/xml/rs:data/z:row/@ows_Group[../@ows_UserID = xdXDocument:get-DOM()/my:myFields/my:HiddenFields/my:CurrentUser] != ""
6) Click "OK"
7) Click the "Add Action..." button
8) Set the "Action" to "Set a field's value".
9) Click the field selector button next to the text box for the "Field" entry.
10) Navigate through your field structure until you find the True/False (Boolean) field for the Role you are setting that was set up in the "Hidden Fields" section (above) and started with "Role-" in the example.
7) Click the "OK" button.
8) Click the function button ("Fx") next to the "Value" text box.
9) Click the "Insert Function" button.
10) Click the "true" or "false" entry in the "Functions" pane on the right side depending on the condition you are setting.
11) Click "OK" four times until arriving back at the "Rules for Opening Forms" page.
12) Repeat the process to set a true and false condition for each Role.
Use:
When deciding to hide or show a section, button, field, etc...(object) on the form using the roles, perform the following steps:
1) Double-click the object on the form to get to it's properties.
2) Click on the "Display" tab.
3) Click on the "Conditional Formatting..." button.
4) Click "Add..." to add a new condition.
5) Click the first drop down and select "Select a field or group...".
6) Navigate to the "Role-" variable that was created and set that you wish to check.
7) Click "OK".
8) Leave the middle box (for this example) set to "is equal to".
9) Set the third drop down to "FALSE".
10) Click the "AND->" button and repeat this for any other Roles you wish to compare.
11) Check the box next to "Hide this control.
12) Click OK until you are back on the main form.
You have just now hidden an object for anyone that does not belong to the Roles you specified.