David Grey's Blog

Friends of Redgate logo

September 2007 - Posts

WSS3/Sharepoint 2007 - Permissions to edit in Datasheet view

As mentioned in my previous post I've been doing some work with WSS3/Sharepoint 2007 recently in which we need to programmatically create custom permission levels for users of certain sites. Although I thought I'd correctly assigned the relevant permissions to the custom permission level our users have just reported an issue with the editing of lists in Datasheet view.

The custom permission level I've created assigns users add, delete, edit and view permissions on list items. Using the standard view of a list users can click the New menu option and add a new item to the list. So far, so good. However if they switch to Datasheet view and try to add a new item they receive an error stating that they do not have permission to add items to the list and the only option they can take is to discard their changes.

For reasons I won't even pretend to understand, the AddListItems permission on its own is not sufficient to allow a user to add to a list in Datasheet view. The user also need to have the BrowseUserInformation permission as well. Once this is added to our custom permission level users can now add, delete, edit and view list items correctly in Datasheet view.

  1. If you come across the same issue you can solve it using either of the following methods
  2. Add the BrowseUserInformation permission to your custom permission level
    Ensure that all users are granted the Limited Access permission level (this include the BrowseUserInformation permission by default).

del.ico.us del.ico.us | Digg It Digg It | Technorati Technorati | StumbleUpon StumbleUpon | Furl Furl | reddit reddit

Soap? You want to try the Sharepoint object model!

Does anybody remember the TV comedy Soap? Each episode ended with a epilogue which gave a brief trailer of the next episode and always ended with the line 'Confused? You will be after you watch next week's episode of Soap'. Well the guys who wrote Soap want to try the Sharepoint object model if they want to experience confusion...

Admittedly I don't do a great deal of Sharepoint development but I do have some familiarity with its object model. Some time ago I wrote an application for a customer which bulk created a batch of Sharepoint sites based on a custom site template, added custom security roles to each site and added certain users from the Active Directory to specific roles within each of the sites. I built the application as a simple command line utility which used the Sharepoint object model to create the sites and manage roles and users.

Fast forward now to this week and the customer has upgraded to Windows Sharepoint Services (WSS) 3.0. My application no longer works as it was compiled against the WSS2.0 libraries so I set in to rebuild it against the WSS3.0 libraries. It compiled first time and ran and all was looking good until it tried creating custom security roles, and that's when my confusion really set in again.

The thing that drives me mad about Sharepoint is that Microsoft change the terminology of the product with each release and the terminology used by Sharepoint users and administrators is inconsistent with that used by the object model. It took me an hour or so this morning to get my head around the fact that security roles, which were called site groups in WSS 2.0, are now called permission levels (not to be confused with permissions) but the object model refers to these as role definitions. The sites that my application creates are based on a template which disables permission inheritance from its parent and uses unique permissions.

TIP #1 : Using unique role definitions/permission levels in a  Sharepoint site
The problem I was having was that when my application tried to create new role definitions in one of these sites an exception would be thrown containing the message

System.ArgumentException: You cannot customize permission levels in a web site with inherited permission levels.

Well, this confused me no end. I could see how there could be a permissions inheritance error when the site is using unique permissions. Then I read the error message a bit more closely (Development Rule #1: Read the error messages carefully and fully) and released that it was an issue with permission level inheritance, not permission inheritance. In a WSS 3.0 site the inheritance of permissions and the inheritance of permission levels from the parent site are two distinct things. Disabling permission inheritance via the UI or through the object model (using the SPWeb.BreakInheritance method) does not disable permission level inheritance; this must be disable separately. If you don't disable permission level inheritance then you won't be able to create custom permission levels in the child site.

The way to disable role definition/permission level inheritance on a child site via the object model is to obtain an SPWeb instance that refers to the site then use the RoleDefintions property of the SPWeb instance. This returns an SPRoleDefinitionCollection instance which has a BreakInheritance method which is used to disable the role definition/permission level inheritance. This method takes two boolean arguments which allows you to control whether parent site permission levels are copied to the child site and whether existing user mappings to permission levels should be maintained.

TIP #2: Creating custom definitions/permission levels in a  Sharepoint site and assigning users to them
Having sorted that little issue I thought my application was now working as it no longer threw exceptions when trying to add custom role definitions to the RoleDefintions of my site. But then as soon as the application tried to assign a user to one of my newly created custom role definitions another exception occurred

Microsoft.SharePoint.SPException: Permission level cannot be found

How could the object model not find the role definition I had just created and added to the site's RoleDefintions collection? After many hours or laying around I finally came upon the answer. In my code I was obtaining an SPWeb instance that refered to my site and adding my custom role definitions to it. The SPRoleDefinitionCollection returned by SPWeb.RoleDefintions has a Count property which returns the number of role definitions in the collection. So far, so good. By running my application through the debugger I noticed that the Count property never increased when I added new custom roles. However if I viewed the permission levels for the site in the Sharepoint UI (under Site Settings, Advanced Permissions) I could clearly see the new role definitions I had added. It appears that the RoleDefinitionCollection.Add() method correctly creates the role definition and adds it to the Sharepoint content database but does not update the in-memory collection managed by the object model. How dumb is this?!

The only way I could get around this behaviour is to use my SPWeb instance to add all my custom role definitions then to call Close() on that SPWeb instance. Having done this I then immediately obtain a new SPWeb instance which refers to the same site. This causes the object model to read the data from the content database and correctly populate the SPWeb.RoleDefintions collection with all of the roles defined in my site, including the ones I have just added. I can then use the RoleAssignments collection of this new SPWeb instance to assign roles to specific users. I'm guessing this is a bug (either in Sharepoint or in my understanding). I tried various other fixes, including calling SPWeb.Update() after creating all the custom role definitions, but none of them worked and this is the only approach that solved the issue. If you come up against the same problem it's definitely worth a try.

Don't get me wrong, Sharepoint's a great product and I use extensively in my daily activities. But from a developer's perspective the terminology is just too confusing and the object model works in a counterintuitive manner. That kind of sucks Redmond guys!

If you want more info on role definitions and role assignment in WSS 3 take a look at Reza's blog.

del.ico.us del.ico.us | Digg It Digg It | Technorati Technorati | StumbleUpon StumbleUpon | Furl Furl | reddit reddit