Home > Development, SharePoint > HOWTO : Create a Site with a custom template through code and assign specific user security (User has no rights to create a site).

HOWTO : Create a Site with a custom template through code and assign specific user security (User has no rights to create a site).


Imagine the following scenario. In your site collections visitors need to be able to create 1 type of sites. When they create that type of site (with a custom template) they need to become the administrator of that site, as well as the people maintaining the site collection.

How do we do that in SharePoint? We create a site while running with Elevated Privileges, let it inherit the rights of the Site Collection. Once the site is created, we break the inheritance and add specific user rights for that user.

First of all we will be creating a function that accepts a few strings that we need to create the site.

Code Snippet
  1. public string CreateSite(string parentSiteUrl, string siteUrlRequested, string siteTitle, string siteTemplateName)
  2.         {
  3.             return “”;
  4.         }

The parentSiteUrl is the url in which we will be creating the site, the requested siteUrlRequested is the url we will be creating the site in, the siteTitle is the title we will be giving to the site, and the siteTemplateName is the name of the Custom Template we will be using.

Ok, let’s write the code to create our site in our parentsite. In the GetCustomWebTemplates functions we will be getting the custom web template list corresponding the language of the site. In that list we take the template as specified in the parameter of our function (siteTemplateName). As we can’t be sure that the user has checked if a site url already exists we increase a counter till we find a free siteUrl (this is not mandatory, you can also raise an error on the Exists boolean).

Code Snippet
  1. string siteUrlValid = “”;
  2.                 const Int32 localeIdEnglish = 1043;
  3.                 SPSecurity.RunWithElevatedPrivileges(delegate
  4.                                                          {
  5.                     
  6.                     using (SPSite siteCollection = new SPSite(parentSiteUrl))
  7.                     {
  8.                         using (SPWeb parentWeb = siteCollection.OpenWeb())
  9.                         {
  10.                             SPWebTemplateCollection templates = siteCollection.GetCustomWebTemplates(Convert.ToUInt32(localeIdEnglish));
  11.                             SPWebTemplate siteTemplate = templates[siteTemplateName];
  12.                             int counter = 1;
  13.                             siteUrlValid = siteUrlRequested + “_” + counter;
  14.                             while (parentWeb.Webs[siteUrlValid].Exists)
  15.                             {
  16.                                 counter++;
  17.                                 siteUrlValid = siteUrlRequested + “_” + counter;
  18.                             }
  19.                             parentWeb.AllowUnsafeUpdates = true;
  20.                             using (SPWeb myWeb = parentWeb.Webs.Add(
  21.                                 siteUrlValid,
  22.                                 siteTitle,
  23.                                 siteTitle,
  24.                                 Convert.ToUInt32(localeIdEnglish),
  25.                                 siteTemplate,
  26.                                 false, false))
  27.                             {
  28.                                 
  29.                             }
  30.                             parentWeb.AllowUnsafeUpdates = false;
  31.                         }
  32.                     }
  33.                 });
  34.                 return siteUrlValid;

 

With this code our site will be created by making use of the custom template. We are running with Elevated Privileges as the user does not have any permissions to create a subsite. In the using statement of myWeb we will be adding the security changes.

Code Snippet
  1. using (SPWeb myWeb = parentWeb.Webs.Add(
  2.                                 siteUrlValid,
  3.                                 siteTitle,
  4.                                 siteTitle,
  5.                                 Convert.ToUInt32(localeIdEnglish),
  6.                                 siteTemplate,
  7.                                 false, false))
  8.                             {
  9.                                 myWeb.BreakRoleInheritance(true);
  10.                                 SPUser user = myWeb.EnsureUser(SPContext.Current.Web.CurrentUser.LoginName);
  11.                                 SPRoleDefinition def = new SPRoleDefinition(myWeb.RoleDefinitions.GetByType(SPRoleType.Contributor));
  12.                                 SPRoleAssignment assignment = new SPRoleAssignment(user.LoginName, user.Email, user.Name,
  13.                                                                                    user.Notes);
  14.                                 assignment.RoleDefinitionBindings.Add(myWeb.RoleDefinitions[def.Name]);
  15.                                 myWeb.AllowUnsafeUpdates = true;
  16.                                 myWeb.RoleAssignments.Add(assignment);
  17.                                 myWeb.Update();
  18.                                 myWeb.AllowUnsafeUpdates = false;
  19.                                 
  20.                             }

 

With BreakRoleInheritance we break the inheritance of the rules. We do this to be able to add the user to the security of that specific site. We are breaking the security afterwards because we want to make sure that the existing security on the site is copied as well. With the EnsureUser statement we make sure the user exists in that site. The SPRoleDefinition isn’t necessary, but I’m using it to make sure that my code runs on multilingual systems. You could use:

Code Snippet
  1.                                 assignment.RoleDefinitionBindings.Add(myWeb.RoleDefinitions[“Contributor”]);

but in a multilingual environment that RoleDefinition isn’t called Contributor. That’s why I will first create a SPRoleDefinition object to make sure that whatever Contributor is called will return the correct name in my SPRoleAssignment. I add the roledefinition to the assignment and then I add the user/role link to the site. Once you have implemented all this your code should look like this:

Code Snippet
  1. public string CreateSite(string parentSiteUrl, string siteUrlRequested, string siteTitle, string siteTemplateName)
  2.         {
  3.             if (siteUrlRequested == null) throw new ArgumentNullException(“siteUrlRequested”);
  4.             try
  5.             {
  6.                 bool returnCondition = false;
  7.                 string siteUrlValid = “”;
  8.                 const Int32 localeIdEnglish = 1043;
  9.                 SPSecurity.RunWithElevatedPrivileges(delegate
  10.                                                          {
  11.                     int counter = 1;
  12.                     using (SPSite siteCollection = new SPSite(parentSiteUrl))
  13.                     {
  14.                         using (SPWeb parentWeb = siteCollection.OpenWeb())
  15.                         {
  16.                             SPWebTemplateCollection templates = siteCollection.GetCustomWebTemplates(Convert.ToUInt32(localeIdEnglish));
  17.                             SPWebTemplate siteTemplate = templates[siteTemplateName];
  18.                             siteUrlValid = siteUrlRequested + “_” + counter;
  19.                             while (parentWeb.Webs[siteUrlValid].Exists)
  20.                             {
  21.                                 counter++;
  22.                                 siteUrlValid = siteUrlRequested + “_” + counter;
  23.                             }
  24.                             parentWeb.AllowUnsafeUpdates = true;
  25.                             using (SPWeb myWeb = parentWeb.Webs.Add(
  26.                                 siteUrlValid,
  27.                                 siteTitle,
  28.                                 siteTitle,
  29.                                 Convert.ToUInt32(localeIdEnglish),
  30.                                 siteTemplate,
  31.                                 false, false))
  32.                             {
  33.                                 myWeb.BreakRoleInheritance(true);
  34.                                 SPUser user = myWeb.EnsureUser(SPContext.Current.Web.CurrentUser.LoginName);
  35.                                 SPRoleDefinition def = new SPRoleDefinition(myWeb.RoleDefinitions.GetByType(SPRoleType.Contributor));
  36.                                 SPRoleAssignment assignment = new SPRoleAssignment(user.LoginName, user.Email, user.Name,
  37.                                                                                    user.Notes);
  38.                                 assignment.RoleDefinitionBindings.Add(myWeb.RoleDefinitions[def.Name]);
  39.                                 myWeb.AllowUnsafeUpdates = true;
  40.                                 myWeb.RoleAssignments.Add(assignment);
  41.                                 myWeb.Update();
  42.                                 myWeb.AllowUnsafeUpdates = false;
  43.                             }
  44.                             returnCondition = true;
  45.                             parentWeb.AllowUnsafeUpdates = false;
  46.                         }
  47.                     }
  48.                 });
  49.                 if (!returnCondition)
  50.                 {
  51.                     siteUrlValid = “”;
  52.                 }
  53.                 return siteUrlValid;
  54.             }
  55.             catch (Exception)
  56.             {
  57.                 return null;
  58.             }
  59.         }

Calling the function can be done like this (Web is the SPContext.Current.Web object).

Code Snippet
  1. siteUrl = CreateSite(Web.Url, siteUrl, siteTitle, “tbtemplate.stp”);
Advertisements
  1. KS
    November 11, 2009 at 5:16 pm

    Koen,

    Is it possible to execute Ajax code (ex. a web service call) in sharepoint with elevated privileges?

    Thanks,

  2. koenvosters
    November 12, 2009 at 8:37 am

    KS, you don’t need RunWithElevatedPrivileges to call webservices. To use Ajax you do need to modify your web.config to support it.
    I suppose you are asking the question because you are experiencing the double hop issue?
    You can call webservices by making use of DefaultCredentials
    http://support.microsoft.com/kb/813834
    Double hop is explained here
    http://blogs.msdn.com/knowledgecast/archive/2007/01/31/the-double-hop-problem.aspx
    So you can either use the method described in the support or use Kerberos authentication.

    Did this answer your question?

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: