Tuesday, May 5, 2015

Hacking SPRoleDefinition SPRoleType in the database

If you are a Site Collection Administrator, SharePoint allows you to go to a Site Collection, Site Actions->Site Permissions->Permission Levels, then edit a permission level and delete it.

Some predefined Permission Levels (SPRoleDefinition) have a Type (SPRoleType) defined. This is not visible via the UI. However you can get this via Powershell as follows:

$web = Get-SPWeb your-web-url
$web.RoleDefinitions | Format-Table Id, Name, Type, Hidden -AutoSize

This gives output like the following:

        Id Name                       Type Hidden
        -- ----                       ---- ------
1073741829 Full Control      Administrator  False
1073741828 Design              WebDesigner  False
1073741827 Contribute          Contributor  False
1073741826 Read                     Reader  False
1073741825 Limited Access            Guest   True

Now, if you delete one of these such as the Contribute and then decide to recreate it, the type is now "None". There is no way to make the Type "Contributor".

This is all fine, but if you have some code that calls Microsoft.SharePoint.SPRoleDefinitionCollection.GetByType then your code is now broken.

To "resolve" (using the term very loosely as I do not know if there are any implications), I was able to restore this by hacking the database directly.

Essentially, I looked into the Roles table in the WSS_Content database, filtered on the WebId and RoleId and set the Type column directly in the database. Is it a good idea? Who knows? It seemed to work for me, but I do not know what I may have broken as a result of this.