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.

Friday, June 15, 2007

Creating a new discussion item on Discussion Board

Hi all,

Ever tried to use C# to add list items to Tasks list? Annoumcements? piece of cake.

To a Document Library? saving a file, updaging meta data - no problem.

But - did you ever try to create a new discussion on a Discussion Board? Well, there is more to it than you think.

My customer had me create a new discussion automatically for every task created on the site. This way - when ever you assign a task to a group or a person they can communicate with each other and work a solution together.

Doing a little research i found that creating a new discussion is a bit different than working with a normal list that we are used to.

First you must create a new discussion using the SPUtility.CreateNewDiscussion method.
This method reiceves the name of the discussion and the SPListItemCollection of the SPList item representin the discussion.

well, for example if you have a discussion boared called "What say you" your code should look like this:

SPList list = web.Lists["What say you"];
SPListItemCollection myListItems = list.Items;
SPListItem d = SPUtility.CreateNewDiscussion(myListItems, "Talk about Task X");
d["Body"] = "What say you about task X?";
d.Update();

And a reply will look like this:

SPListItem r = SPUtility.CreateNewDiscussionReply(d);
r["Body"] = "Looks interesting... Doesnt it?";
r.Update();


Well, hope this helps...