http://www.developer.com/net/asp/article.php/3835196/Simple-Custom-Group-Assignments-in-SharePoint.htm
Many of my clients ask for ways to give certain, very specific rights to their users without giving other rights within the same standard SharePoint role. For instance, it would be nice if distributed site/content managers could add users to SharePoint security groups on their site without actually giving them explicit rights via SharePoint roles and permissions to add users to groups within their site. Out-of-the-box, in order to be able to add and remove users from a group, you need to be the Group Owner, have Full Control rights to the site, be the Site Administrator, or be the Site Collection Administrator. In many cases, none of those options are acceptable, as they all potentially bring along other rights that clients are not willing to give a content or site manager within the construct of their corporate and/or SharePoint governance policies. They simply want a user to be able to add other users to existing SharePoint groups on their site and that's it. They don't want that user to have any rights whatsoever to change the groups on the site, other than adding new users to them. This article presents a simple solution I have found to allow this functionality. In your Visual Studio product of choice, create a new Class Library project. Please note that I am not using the SharePoint Web Part templates provided by Microsoft; I'm just creating my own Class Library from scratch and implementing the SharePoint Web Part class. If you are comfortable with using the SharePoint templates for your version of Visual Studio, please feel free to do so. So, create a Class Library project. In my case, I am calling it CustomGroupAssignment. Once you have created the project, you will need to add references to System.Web and Microsoft.SharePoint. Now, add the following "using" directives if they do not exist already: At this point, go ahead and set up the class. Please note that I am inheriting from Microsoft.SharePoint.WebPartPages.WebPart and not from System.Web.UI.WebControls.WebParts.WebPart. You are going to override the two core web part methods, CreateChildControls and RenderWebPart, so you will add some placeholders in the code as well. Please add the placeholders like so: Once you have the shell for your class in place, go ahead and add in some class-level variables for the child controls that you will use in the web part. Basically, what you are going to do is incorporate a few controls into your web part that will allow you to provide the user with some guidance about what to do, require the user to choose one or more users, assign them to groups via checkboxes and click the "Submit" button. The next thing you need to do is add all of your custom controls into the CreateChildControls method. First, implement a base method. In case it was not included when you typed in your shell earlier, or you deleted it by accident, here is the statement to do so: Then, put in the PeoplePicker section. Now, add in the section for the Group controls. As you may have noticed, the main actionable Groups control is built by grabbing the current sites groups, storing them in an SPGroupCollection object, and then iterating through that collection, creating a check box for each group, using the actual group name, which will serve you well in the next step. Now, for the Submit Button, the Cancel Button and our Status Window. Please note the treatment of the Click events for the two buttons. Hopefully you noticed the way the Click events were handled. For the Cancel button, you merely send it to the previous page in the browsers history by adding an onClick attribute through code, and then assigning some JavaScript as the value for that attribute. The Submit button is using the .NET EventHandler, which will be explored next. Now its time for the heavy lifting of this web partadding the users to the groups. Here is the basic code to do that, and we will walk through it briefly below. First things first the SPSecurity.RunWithElevatedPrivileges method is being used to make sure that the code is going to run as a user with the proper rights. You could just as easily have explicitly declared some credentials, but the SPSecurity class has provided us with this excellent alternative. The next thing that jumps out is the AllowUnsafeUpdates property. In order for the code to be able to add users to groups within the site, this property must first be set to true temporarily. After that, it is just a simple nested loop wherein each checkbox is inspected to see if it is checked, and if it is, each user is retrieved from the Entities collection of the People Picker control in the web part, and added to the group. A few things are also written to the Status window so that you can see what is happening. Obviously this status updating is removed before being put into production, where you would send the user to a follow-on page that lets them know if the users were successfully added to the groups or not. I would highly encourage you to do something similar if you implement this kind of functionality in your SharePoint environment. You also have the clean-up action of setting the AllowUnsafeUpdates property back to false on your way out of this function. Hopefully, I do not need to remind you how crucial this one line of code could be to your happiness and career longevity as a SharePoint developer. The final thing to do is to render the content of the web part, which is accomplished through the code below. As you will notice, an ever-so-simple HTML table is created to house the controls in an easy way for the user to interact with the controls and meet our expectation of choosing one or more users using the People Picker, selecting one or more groups to which they want to add the user(s) and clicking the Submit button. Once again, this is a very simple treatment of the RenderWebPart method. You may want to provide additional detail to your users in this method or in the CreateChildControls method. All that is left to do is deploy your Web Part to your SharePoint environment and add it to a page to see it in action. In order to deploy the web part, you need to either:
The simple and easiest way to ensure that you always have the latest version of the DLL(s) from your Web Part in the bin folder for your SharePoint web application is to add the appropriate folder to the Output Path property of your Visual Studio project. In order to do so:
The next step is to add a SafeControl entry in the configuration file (web.config) for your SharePoint web application. In Windows Explorer, browse to the location of the files for your web application. By default, it will look similar to this: C:\intepub\wwwroot\wss\VirtualDirectories\<<ApplicationNameandPort>>. Web.config is located in the root folder for the web applicaiton. Open it in a text editor and find the <SafeControls> section. The easiest way to add a new safe control is to just copy the tag from the last SafeControl in the list already and modify it for your web part. In this case, your SafeControl tag should like almost exactly like this, depending on whether or not you used a different name for your Assembly and/or Namespace: While you have web.config open, you should also ensure that you have the correct setting for the trust property. Since our web part is going to be using the SharePoint Object Model, we need to have a trust level of WSS_Medium. Your trust tag should look like this: Save web.config, run an iisreset and you should be ready to add your web part to your SharePoint site collection. Now that you have finished deploying the web part, you need to add it to the Web Part Gallery of your web application's top-level site collection. Now your web part is ready to use on any web part page in your site collection. Here are the steps for adding the web part to a web part page. Because our web part is running with elevated priviledges, we only want to allow certain users to use the web part. Luckily, every SharePoint web part comes along with this functionality in the form of audience targeting. In order to implement audience targeting for your web part, click the edit button in the upper right corner of your web part and select Modify Shared Web Part. On the Task Pane, expand the Advanced node, scroll all the way to the bottom and use the Target Audiences control to add in the user(s) / group(s) that you want to be able to use this web part. You may also want to control access at the page level. This makes the most sense if you want to combine this web part with some others into an Admin Console for your distributed content managers to accomplish certain Administrative tasks without giving them access to perform other things when you are not comfortable with them doing so. You may have noticed that there are a few things missing here that you would most certainly want to incorporate into a production system, but those should be relatively simple for a programmer. Hopefully, if you have not worked with this kind of a customization in SharePoint before, you can use this article as a good starting point. Joe Mack is a Knowledge Management Evangelist and SharePoint Solution Architect, Consultant and Programmer. He has been working with SharePoint for over 6 years and has over 50 successful SharePoint implementations under his belt. He blogs at The Mack Page, tweets under mack247 and can usually be found at a client site somewhere in the world trying to proliferate his special brand of Knowledge Management, SharePoint, Business Transformation and/or Business Intelligence insanity. He is a graduate of The United States Military Academy at West Point and lives in Indianapolis with his family.
Simple Custom Group Assignments in SharePoint
August 19, 2009
Step 1: Create and Configure the Project
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Collections;
Step 2: Setting up the Class
namespace TPG.WebParts
{
public class CustomGroupAssignment : Microsoft.SharePoint.WebPartPages.WebPart
{
protected override void CreateChildControls()
{
base.CreateChildControls();
}
protected override void RenderWebPart(HtmlTextWriter writer)
{
}
}
}
//People Picker UI controls
Label lblPplPicker;
PeopleEditor pplPicker;
Label lblPplPickerDesc;
//Groups UI controls
Label lblGroups;
CheckBoxList cblGroups;
Label lblGroupsDesc;
//Button controls
Button btnSubmit;
Button btnCancel;
//Status "window"
TextBox txtStatus;
Step 3: CreateChildControls
base.CreateChildControls();
//Create People Picker Label
lblPplPicker = new Label();
lblPplPicker.Text = "Users:";
this.Controls.Add(lblPplPicker);
//Create People Picker Control
pplPicker = new PeopleEditor();
pplPicker.AllowEmpty = false;
pplPicker.ValidatorEnabled = true;
pplPicker.SelectionSet = "User";
this.Controls.Add(pplPicker);
//Create People Picker Description
lblPplPickerDesc = new Label();
lblPplPickerDesc.Text = "Please select the users you would like to add to the current site.";
this.Controls.Add(lblPplPickerDesc);
//Create Groups Label
lblGroups = new Label();
lblGroups.Text = "Groups:";
this.Controls.Add(lblGroups);
//Create Groups Control
cblGroups = new CheckBoxList();
cblGroups.ID = "groupsList";
using (SPWeb oWebSite = SPContext.Current.Web)
{
SPGroupCollection collGroups = oWebSite.Groups;
foreach (SPGroup oGroup in collGroups)
{
cblGroups.Items.Add(oGroup.Name.ToString());
}
}
this.Controls.Add(cblGroups);
//Create Groups Description
lblGroupsDesc = new Label();
lblGroupsDesc.Text = "Please select the groups to which you would like to add the selected user(s).";
this.Controls.Add(lblGroupsDesc);
//Create Submit Button
btnSubmit = new Button();
btnSubmit.Text = "Submit";
btnSubmit.Click += new EventHandler(btnSubmit_Click);
this.Controls.Add(btnSubmit);
//Create Cancel Button
btnCancel = new Button();
btnCancel.Text = "Cancel";
btnCancel.Attributes.Add("onClick", "history.back(); return false;");
this.Controls.Add(btnCancel);
//Create Status Window
txtStatus = new TextBox();
txtStatus.TextMode = TextBoxMode.MultiLine;
txtStatus.Width = 500;
txtStatus.Rows = 10;
txtStatus.Visible = false;
this.Controls.Add(txtStatus);
Step 4: Submit Button
void btnSubmit_Click(object sender, EventArgs e)
{
try
{
SPSecurity.RunWithElevatedPrivileges(delegate
{
using (SPSite spSite = new SPSite(Page.Request.Url.ToString()))
{
using (SPWeb spWeb = spSite.OpenWeb())
{
try
{
//Temporarily allow unsafe updates
spWeb.AllowUnsafeUpdates = true;
SPGroup spGroup;
string userLogin = "";
string userEmail = "";
string userDisplayName = "";
foreach (ListItem cblItem in cblGroups.Items)
{
if (cblItem.Selected)
{
spGroup = spWeb.Groups[cblItem.Text];
txtStatus.Text += "Found Group: " + spGroup.Name.ToString() +
" ... Adding Usersrn------------rn";
foreach (PickerEntity pe in pplPicker.Entities)
{
userLogin = pe.Key;
Hashtable userData = pe.EntityData;
if (userData.ContainsKey("Email"))
userEmail = userData["Email"].ToString();
if (userData.ContainsKey("DisplayName"))
userDisplayName = userData["DisplayName"].ToString();
txtStatus.Text += "Found user: " + userLogin.ToString() + "rn";
spGroup.AddUser(userLogin, userEmail, userDisplayName, "");
txtStatus.Text += "Added user: " + userLogin + "rn";
}
txtStatus.Text += "============rn";
}
}
}
catch (Exception ex)
{
txtStatus.Text += ex.Message;
}
finally
{
spWeb.AllowUnsafeUpdates = false;
}
}
}
});
}
catch (Exception exception)
{
txtStatus.Text += exception.Message;
}
txtStatus.Visible = true;
}
Step 5: Rendering the Web Part
protected override void RenderWebPart(HtmlTextWriter writer)
{
EnsureChildControls();
writer.Write("<TABLE><TR><TD>");
this.lblPplPicker.RenderControl(writer);
writer.Write("</td><td>");
this.pplPicker.RenderControl(writer);
writer.Write("<BR />");
this.lblPplPickerDesc.RenderControl(writer);
writer.Write("</td></tr>");
writer.Write("<tr><td>");
this.lblGroups.RenderControl(writer);
writer.Write("</td><td>");
this.cblGroups.RenderControl(writer);
writer.Write("<BR />");
this.lblGroupsDesc.RenderControl(writer);
writer.Write("</td></tr>");
writer.Write("<tr><td colspan="2" align="center">");
btnSubmit.RenderControl(writer);
btnCancel.RenderControl(writer);
writer.Write("</td></tr></table>");
writer.Write("<BR/><BR/>");
this.txtStatus.RenderControl(writer);
}
Deploying the Web Part
I am going to use the second option during this article.
<SafeControl Assembly="CustomGroupAssignment" Namespace="TPG.WebParts" TypeName="*" Safe="True" />
<trust level="WSS_Medium" originUrl="" />
Configuring Your Site Collection to Use the Web Part
Using Your Web Part
Conclusion
About the Author