Displaying/Hiding Content based on User Permissions

Jan 14, 2010 at 5:18 PM

or "When Edit permissions don't work..."

Problem
I recently had a request to create an "intake" list to report Employee Injuries and Illnesses to HR. The requirements were that the Employee could create a list item, but not edit it. Seems simple enough: Create a permission that looks like Contribute, but remove Edit Items.

But, another requirement blew that out of the water: A create workflow needs to perform some lookups on the Employee, the Supervisor, an Assistant Supervisor (if any), and Medical Staff (if any); and then write those bits of data out to the list item, too. Since workflows run under the ID of the person who performed the task that caused them to fire, this workflow requires Edit Items permission.

OK, well, how about we start them off with Edit Items, run the workflow to make the updates, and have the last step in the workflow change the permissions on the item to Read for this user?

You can do that, but you wouldn't get the results you were hoping for.

SharePoint ORs all inherited permissions to determine if the user can perform a task. In other words, a user can edit a list item if:

  1. They have Edit Items permission on the item, OR
  2. They have Edit Items permission on the list, OR
  3. They have Edit Items permission on the site

So, even though they have Read permission on the item, they have Edit permission on the list so they can still edit the item.

Solution:
So, here's a solution that will help with this situation.

First, you'll need to edit the EditForm.aspx for the list and use IfHasRights() as a condition for displaying an editable field or just the text of the field. In my situation, users who CAN edit are those with Manage Permissions permission, which Contribute doesn't have. So, I used a <xsl:choose> structure to check for IfHasRights(33554432).

Next, you'll need to hide the Edit Item button on the DispForm.aspx if the user doesn't have Manage Permissions and doesn't have Full Control of the list. (Full Control has a permissions mask of 9223372036854775807, but is not the sum of all the permissions it has.) The following jQuery code accomplishes this (add it to a hidden CEWP at the bottom of the page).

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script> 
<script src="/js/jquery.SPServices-0.4.6.js" type="text/javascript"></script> 
<script type="text/javascript">
$(document).ready(function() {

   $().SPServices({
     operation: "GetRolesAndPermissionsForCurrentUser",
     async: false,
     completefunc: function(xData, Status) {
//        alert(xData.responseXML.xml);
        var userPerm = $(xData.responseXML).find("[nodeName=Permissions]").attr("Value");
//        alert("userPerm = " + userPerm);
        var nonAdminP = (33554432 & userPerm) == 33554432;
//        alert("nonAdminP == 33554432: " + nonAdminP);
        var adminP = userPerm == 9223372036854775807;
//        alert(adminP);
        var hideEdit = !(nonAdminP | adminP);
//        alert("hideEdit = " + hideEdit);

        
        if (hideEdit) {
		   //alert("Hide");
		   $("a[title='Edit Item']").parent().parent().parent().hide();
		   $("td.ms-separator:nth-child(2)").hide();
        }
     }
   });
   
});
</script>

To see how it's working and what each step is returning, uncomment the alerts.

Hope that helps someone.

Blessings,
Jim Bob

Coordinator
Jan 14, 2010 at 8:18 PM

Jim,

Very cool work here--lots of uses for similar code too, such as if you wanted to display a button only to site admins.

Thanks for taking the time to write it up and share!

Mike

Jan 14, 2010 at 8:27 PM

You're wecome, Mike. That's why I posted it: figured it could help someone! ;)

I knew Marc was looking for real world examples for his doco, too.

Blessings,
Jim Bob

Coordinator
Jan 15, 2010 at 4:27 PM

Yes, indeed, Jim Bob. It's a nice post and would make an excellent EndUserSharePoint.com article!  I'll also add it in as an example for the GetRolesAndPermissionsForCurrentUser operation.

M.

Jan 15, 2010 at 4:40 PM

Indeed. I just sent it off to Natasha! :)

Blessings,
Jim Bob

Jan 19, 2010 at 6:36 PM

The article went live today, complete with screen shots! ;)

EndUserSharePoint.com | jQuery to the Rescue: Requesting a review only once per user

Blessings,
Jim Bob

Apr 9, 2010 at 11:07 AM

This selector would be more culture neutral:

$("img[src$='edititem.gif']").parent().parent().parent().parent().hide();

Jun 8, 2010 at 7:52 PM

Thanks you for the post... Wanted to share this... If looking for the mask associated with a set of permissions, I found a post that details what the different permissions MASKS are... Post can be found here:

http://bazhkou.blogspot.com/2009/06/sharepoint-data-view-conditional.html

Here is the info:

The permissinMask value is the sum of any of the values below:

  • ViewListItems - 1
  • AddListItems - 2
  • EditListItems - 4
  • DeleteListItems - 8
  • ApproveItems - 16
  • OpenItems - 32
  • ViewVersions - 64
  • DeleteVersions - 128
  • CancelCheckout - 256
  • PersonalViews - 512
  • ManageLists - 2048
  • ViewFormPages - 4096
  • Open - 65536
  • ViewPages - 131072
  • AddAndCustomizePages - 262144
  • ApplyThemeAndBorder - 524288
  • ApplyStyleSheets - 1048576
  • ViewUsageData - 2097152
  • CreateSSCSite - 4194314
  • ManageSubwebs - 8388608
  • CreateGroups - 16777216
  • ManagePermissions - 33554432
  • BrowseDirectories - 67108864
  • BrowseUserInfo - 134217728
  • AddDelPrivateWebParts - 268435456
  • UpdatePersonalWebParts - 536870912
  • ManageWeb - 1073741824
  • UseRemoteAPIs - 137438953472
  • ManageAlerts - 274877906944
  • CreateAlerts - 549755813888
  • EditMyUserInfo - 1099511627776
  • EnumeratePermissions - 4611686018427387904
  • FullMask - 9223372036854775807
Apr 1, 2011 at 10:43 PM

Sorry - don't know what I'm doing wrong and I'm just learning as I go along.  I have a list with three permission levels - 1 person has full control (site, list, item), 2 persons have contribute (site, list, item), everybody else has a new permision level that was created just for workflow. 

  • For List permissions - Edit, View, Open, Create Alerts and View Application Pages.
  • For Site permissions - Browse Directories, View pages, Browse User Information, Use remote interfaces, Use client integration features, open, edit personal user information
  • For Personal Permissions - All

We don't want everyone, besides the first 3 people, to be able to add, delete or edit.  However, with workflow, they have to be able to edit.  I want to be able to disable to the edit form altogether and disable the edit button on the display form.  I am not able to add a CEWP to the display form, the Edit Page is greyed out.  So, I placed the above code under <asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">.  However, the edit button is still showing up.  Is there something else that I need to be doing?

Thanks for the help.

Coordinator
Apr 3, 2011 at 2:00 PM
Edited Apr 3, 2011 at 2:02 PM

hlock:

This is an old thread, and the code is referring to very dated versions of both jQuery and SPServices. I'd suggest that you get the most recent of both and see how it goes from there.

Note that a script solution for permissions isn't at all secure in that if the script doesn't run, the security isn't there.

M.

Nov 28, 2011 at 3:27 PM

I don't understand - isn't this an enormous security hole?  If the user puts a breakpoint in the jquery code and changes the value of adminP, he can very easily just give himself full access.  

This example seems like a very dangerous example to be suggesting to everyone - using client-side javascript to control permissions is a blatant security violation. 

Coordinator
Nov 28, 2011 at 3:30 PM

No, you cannot change your own permissions in any way (other than logging in as someone else). Script and Web Services calls all happen using the current user's credentials and there is no way to override that. There is no "elevate permissions" possibility.

Also, note that the operation used here is a Get in any case. There's no attempt to write permissions. There are other operations whivh allow that, but again, only using the current user's credentials.

M.

Nov 28, 2011 at 3:37 PM

Yes, ses4j, you're right! As Marc said, it's not all secure. If you have very sensitive data, this isn't the way to go.

If you're looking for a way to impact the UI based on permissions, this could be helpful.

Nov 28, 2011 at 3:38 PM

@sympmarc: But the "Employee" in this example has actual Edit permissions on the list.  The code intends to restrict the employees permissions beyond what SP can do (an Edit-sometimes permission), simply by modifying the UI with javascript, but this is impossible.  The server will still allow him to edit the item if he can find an Edit button to click, and if he plays with the javascript as I described, he can make the form show him the Edit button.  So my point is that this technique should NOT be relied on to control users' permissions, it can only be used for superficial UI management, because it can be trivially circumvented.  A disclaimer should be added to the example above, IMO.