Sunday, July 22, 2007

Manage site/list/item permissions in SharePoint from C#

Hi guys,

I have a little code bit that allows you, once you have a permission level defined in your SharePoint site, to change a site/list/item permissions using C#.

As you may or may not know, WSS 3 and MOSS 2007 handles security in 3 levels:
1 - Permission - which cannot be used directly to give access to a user
2 - Permission Level - which can be used to give access to a user or to control a SharePoint group access
3 - SharePoint Group - which is much like a cross site group that handles permission levels and user assignments to a group that can be used in several sites in the same site collection that does not inherit permissions, but share the same contributors/readers etc.

This code allows you to break the permissions inheritance of a site / list / item and assign a user to a permission level on that object only.

So, without further ado, here it is:



public static void CreatePermissions(SPWeb theWeb, string loginName, string roleName, string permissionLevel)
{
try
{
theWeb = new SPSite(theWeb.Site.ID).OpenWeb(theWeb.ID);
theWeb.AllowUnsafeUpdates = true;

SPRoleAssignment roleAssignment = new SPRoleAssignment(loginName, "", roleName, "");

SPRoleDefinition RoleDefinition = theWeb.RoleDefinitions[permissionLevel];

if (!roleAssignment.RoleDefinitionBindings.Contains(RoleDefinition))
roleAssignment.RoleDefinitionBindings.Add(RoleDefinition);

//Check inheritance
if (!theWeb.HasUniqueRoleAssignments)
{
theWeb.BreakRoleInheritance(false);
}

theWeb.RoleAssignments.Add(roleAssignment);

//If user already exists - update its display name
try
{
SPUser user = null;
user = theWeb.Users[loginName];
user.Name = roleName;
user.Update();
}
catch { }

theWeb.Update();
}
catch (Exception exc)
{
}
}

public static void CreatePermissions(SPWeb theWeb, SPListItem ListItem, string loginName, string roleName, string permissionLevel)
{
try
{
theWeb = new SPSite(theWeb.Site.ID).OpenWeb(theWeb.ID);
theWeb.AllowUnsafeUpdates = true;

ListItem = theWeb.Lists[ListItem.ParentList.ID].GetItemById(ListItem.ID);

SPRoleAssignment roleAssignment = new SPRoleAssignment(loginName, "", roleName, "");

SPRoleDefinition RoleDefinition = theWeb.RoleDefinitions[permissionLevel];

if (!roleAssignment.RoleDefinitionBindings.Contains(RoleDefinition))
roleAssignment.RoleDefinitionBindings.Add(RoleDefinition);

//Check inheritance
if (!ListItem.HasUniqueRoleAssignments)
{
ListItem.BreakRoleInheritance(false);
}

ListItem.RoleAssignments.Add(roleAssignment);

ListItem.Update();

}
catch (Exception exc)
{
}
}

public static void CreatePermissions(SPWeb theWeb, SPList list, string loginName, string roleName, string permissionLevel)
{
try
{
theWeb = Utilities.Refresh(theWeb);

SPRoleAssignment roleAssignment = new SPRoleAssignment(loginName, "", roleName, "");

SPRoleDefinition RoleDefinition = theWeb.RoleDefinitions[permissionLevel];

if (!roleAssignment.RoleDefinitionBindings.Contains(RoleDefinition))
roleAssignment.RoleDefinitionBindings.Add(RoleDefinition);

//Check inheritance
if (!list.HasUniqueRoleAssignments)
{
list.BreakRoleInheritance(false);
}

list.RoleAssignments.Add(roleAssignment);

list.Update();

}
catch (Exception ex)
{
}
}

Sunday, July 8, 2007

Adding a filter combo-box web part as you wish

Its been a while, not that I didnt have what to write about (I have loads - believe me), just had no time...

I want to share a simple solution for filtering list views I did for a customer that could help some of you guys.

I had a customer that needed a combo box web part (simple) that will hold several values for filtering other list viewers web parts on the same page.

Well, obviously we have our "SharePoint List Filter - Multiple Drop-Down" web part from our site for download, but here I was aiming for a simple solution that will not take values from fields automatically and did not need all the benifits of a product such as that (as great as it may be).

So, what I did was to add a content editor web part that will hold the HTML code for the drop-down list with all its values. On each change I passed the selected value to the query string and posted the page.
Here is the code for that web part:

select value: <select id="cmb_WPQ_" onchange="onChange_WPQ_(this);">
<option value="">select...</option><option value="value 1">option one</option>
<option value="">select...</option><option value="value 2">option two</option>
</select>
<script>

function onChange_WPQ_(ddl)
{
for(var i=0; i<ddl.options.length; i++)
{
if( ddl.options[i].selected )
{
view = ddl.options[i].value;
selected = i;
break;
}
}

if(view == '') return;

window.location = window.location.href.split('?')[0] +
'?view=' +
escape(view) +
'&selected=' +
escape(selected);
}

function onLoader_WPQ_()
{
try
{
if( window.location.href.indexOf("&selected=") > 0 )
{
var selected = window.location.href;
selected = selected.slice(selected.indexOf("&selected=") );
selected = selected.replace("&selected=","");
document.getElementById('cmb_WPQ_').options[selected].selected = true;
}
}
catch(e)
{}
}


onLoader_WPQ_();

</script>

(paste this code in the HTML editor of a content editor web part)

Now, when this takes care of showing the drop down list and sending information for the selection to the query string all I have to do to make this play is to add a query string filter web part (comes out of the box), set it to take "view" query string key and connect it to the list viewer web part I want!

This way I can use simple HTML web part as filter providers for more advanced solutions with no real .NET development.

Hope this helps, feel free to comment if you have question.