Return to doc.sitecore.com

Valid for Sitecore 5.2, 5.3
How can I add custom fields to roles?

Q:

We would like to connect specific user groups with specific extranet areas ('Project rooms'). In order to list Project rooms easily, we would like to add a field to the Role template so that we can add the path to the Project room with which it is associated. How can we add a custom field to a role?

A:

Sitecore does not provide the Role Manager, only the User Manager. However, you can create your own Role Manager XAML application which works with your custom Role fields.  Please follow these steps as an example for Sitecore 5.2:

  1. Open \sitecore\shell\Security templates.xml and add your custom fields: 

    <template id="{A7DF04B4-4C4B-44B7-BE1E-AD901BD53DAD}" name="Role" fullname="Role" icon="Network/16x16/id_card.png" baseids="">

        <section id="" name="Appearance" icon="">

          <field id="{06D5295C-ED2F-4A54-9BF2-26228D113318}" name="Icon" icon="" shared="1" sortorder="" source="" style="" type="text" unversioned="1">Network/16x16/id_card.png</field>

        </section>

        <section id="" name="Data" icon="">

          <field id="{4C5B18DC-7794-47C6-9C27-A2ACC39885B1}" name="Fullname" icon="" shared="1" sortorder="" source="" style="" type="text" unversioned="1"/>

        </section>

      </template>


    Please see the added field in the Data section in bold above.
    Note: the field id should be unique id="{4C5B18DC-7794-47C6-9C27-A2ACC39885B1}" and you should generate it using e.g. Visual Studio 2005.
  2. We are going to customize the Security Manager. Please copy \sitecore\shell\Applications\Security\Security manager\Security manager.xml to \sitecore\shell\Override\Security manager.xml
    and change the CodeBeside class, for example: 

    <CodeBeside Type="Custom.CustomSecurityManagerForm,CustomSecurityManagerForm"/>


  3. Compile this class which should inherit the SecurityManagerForm:

1.  Code Snippet

using System;
using System.Collections.Generic;
using System.Text;
using Sitecore;
using Sitecore.Web.UI.Sheer;
using Sitecore.Text;
using Sitecore.Shell.Applications.Security.SecurityManager;
using Sitecore.Data;
using Sitecore.Web.UI.WebControls;
using Sitecore.Web.UI.HtmlControls;
using Sitecore.Data.Items;
using Sitecore.SecurityModel;
using Sitecore.Configuration;
namespace Custom
{
  
public class CustomSecurityManagerForm : SecurityManagerForm
   {
      
new protected void Open()
      {
        
base.Open();
         Item itm
= this.GetSelectedItem();
        
if ((itm != null) && (itm.TemplateID == TemplateIDs.Role))
         {
            Domain domain
= Factory.GetDomain(this.Domain);
            
if (domain != null)
            {
               EditRole(Factory.GetDomain(
this.Domain), itm.ID);
            }
         }
      }
      
public void EditRole(Domain domain, ID id)
      {
         UrlString url
= new UrlString("/sitecore/shell/default.html?xmlcontrol=SecurityEditRole");
         url.Add(
"do", domain.Name);
         url.Add(
"id", id.ToString());
         Context.ClientPage.ClientResponse.ShowModalDialog(url.ToString(),
"local:refresh");
      }
      
public override void HandleMessage(Message message)
      {
        
if (message.Name == "local:refresh")
         {
            Sitecore.Context.ClientPage.ClientResponse.SetLocation(
string.Empty);
         }
        
base.HandleMessage(message);
      }
      
private Item GetSelectedItem()
      {
        
foreach (ListviewItem itm in this.Listview.Items)
         {
            
if (Context.ClientPage.ClientRequest.Source == itm.ID)
            {
              
return this.DataContext.GetItem((itm as DataListviewItem).ItemID);
            }
         }
        
return null;
      }
   }
}

     4.  We are going to create the Role Manager. Please copy \sitecore\shell\Applications\Security\Edit user\Edit user.xml to \sitecore\shell\Override\edit role.xml

      5.   Here is the body of this XAML:          

<?xml version="1.0" encoding="utf-8" ?>

<control xmlns="http://schemas.sitecore.net/Visual-Studio-Intellisense" >

  <SecurityEditRole>

    <FormDialog Icon="People/32x32/user1_view.png" Header="Edit user"

      Text="Change the role information. When done, click the Save button" OKButton="Save"> 

      <CodeBeside Type="Custom.EditRoleForm,CustomSecurityManagerForm"/>   

      <GridPanel ID="Fields" Columns="2" Width="100%" CellPadding="2"> 

        <Literal Text="Role name:" GridPanel.NoWrap="true"/>

        <Edit ID="Name" Width="100%" ReadOnly="true" background="#e9e9e9" Border="none" GridPanel.Width="100%"/>       

        <Literal Text="Full name:" GridPanel.NoWrap="true" GridPanel.VAlign="top"/>

        <Edit ID="FullName" Width="100%" GridPanel.Width="100%"/>       

      </GridPanel>     

    </FormDialog>

  </SecurityEditRole>

</control> 

       Please pay attention to the CodeBeside.

      6.   Here is the codebeside class:

2.  Code Snippet

using System;
using System.Collections.Generic;
using System.Text;
using Sitecore;
using Sitecore.Text;
using Sitecore.Shell.Applications.Security.SecurityManager;
using Sitecore.Data;
using Sitecore.Diagnostics;
using Sitecore.Configuration;
using Sitecore.SecurityModel;
using Sitecore.Web.UI.WebControls;
using Sitecore.Web;
using Sitecore.Web.UI.Pages;
using Sitecore.Web.UI.HtmlControls;
using Sitecore.Data.Items;
using Sitecore.Data.Fields;
namespace Custom
{
  
class EditRoleForm : DialogForm
   {
      
protected Edit Name;
      
protected Edit FullName;
      
protected override void OnLoad(EventArgs e)
      {
        
base.OnLoad(e);
        
if (!Context.ClientPage.IsEvent)
         {
            
string domainString = WebUtil.GetQueryString("do");
            
if (domainString.Length == 0)
            {
               domainString
= Context.GetDomainName();
            }
            
this.Domain = domainString;
            
string idRole = WebUtil.GetQueryString("id");
            Error.Assert(idRole.Length
> 0, "Querystring parameter \"id\" not found.");
            Domain domain
= Sitecore.Configuration.Factory.GetDomain(this.Domain);
            Sitecore.SecurityModel.RoleItem roleItem
= domain.GetRole(idRole);
            Error.Assert(roleItem
!= null, "Role \"" + idRole + "\" not found");
            
this.Name.Value = roleItem.Name;
            roleItem.InnerItem.Fields.ReadAll();
            roleItem.InnerItem.Fields.Sort();
            
foreach (Field field in roleItem.InnerItem.Fields)
            {
              
if (field.Key.Length > 0)
               {
                  
//Restore value to Full name filed
                  if (field.Name.Equals("Fullname"))
                  {
                     FullName.Value
= field.Value;
                  }
               }
            }
            Context.ClientPage.ServerProperties[
"id"] = idRole;
         }
      }
      
public string Domain
      {
        
get
         {
            
return StringUtil.GetString(Context.ClientPage.ServerProperties["Domain"]);
         }
        
set
         {
            Context.ClientPage.ServerProperties[
"Domain"] = value;
         }
      }
      
protected override void OnOK(object sender, EventArgs args)
      {
        
string idRole = Context.ClientPage.ServerProperties["id"] as string;
         Domain domain
= Sitecore.Configuration.Factory.GetDomain(this.Domain);
         Sitecore.SecurityModel.RoleItem roleItem
= domain.GetRole(idRole);
        
if (roleItem != null)
         {
            roleItem.InnerItem.Fields.ReadAll();
            roleItem.InnerItem.Editing.BeginEdit();
            roleItem[
"FullName"] = StringUtil.GetString(Context.ClientPage.ClientRequest.Form["FullName"]);
            roleItem.InnerItem.Editing.EndEdit();            
            Sitecore.Context.ClientPage.ClientResponse.SetDialogValue(
"Ok");
            
base.OnOK(sender, args);
         }
        
else
         {
            Context.ClientPage.ClientResponse.ShowError(
"Failed to save role.", "");
         }
      }
   }
}

See more relevant methods: OnLoad() in which you should output your custom fields and OnOK in which you should save data in the custom fileds (see the image below).

/upload/sdn5/faq/security/adding custom fields to roles/custom_role_field.jpg 

Download the sources for this article by following the links below: