Documentation Center

Example: extending privileges

This example explains how I extend Content Manager to allow only users with some custom privilege to save Components to a specific folder.

Procedure

  1. Create a new TOM.NET extension project that references Tridion.ContentManager.dll.
  2. If you do not yet have an extension, create a simple extension with the following code:
    using Tridion.ContentManager.Extensibility;
    
    namespace CustomPrivileges
    {
      [TcmExtension("MyExtension")]
      public class MyExtension : TcmExtension
      {
    
      }
    }
  3. In your extension (in this example, the MyExtension class), register your custom privilege in a test method:
    public class MyExtension : TcmExtension
    {
      public TestEventSystem()
      {
        RegisterSystemPrivilege("PRIVILEGE_ID", "PRIVILEGE_TITLE_RESOURCE", "PRIVILEGE_DESCRIPTION_RESOURCE");
      }
    }
    where:
    • PRIVILEGE_ID is the identifier of your privilege, for example, FolderLimitingPrivilege. (Note that this ID must not start with the string tcm:, which is a reserved string).
    • PRIVILEGE_TITLE_RESOURCE is the resource that contains the localizable title of your privilege as it will appear in the user interface, for example, resFolderLimitingPrivilegeTitle. If no localization is required, this string can simply the non-localized title.
    • PRIVILEGE_DESCRIPTION_RESOURCE is the resource that contains the localizable description of your privilege as it will appear in the user interface, for example, resFolderLimitingPrivilegeDescription. If no localization is required, this string can simply the non-localized description.
  4. Extend the new TestEventSystem() method to include subscribing to the event of saving a Component:
    public class MyExtension : TcmExtension
    {
      public TestEventSystem()
      {
        RegisterSystemPrivilege("PRIVILEGE_ID", "PRIVILEGE_TITLE_RESOURCE", "PRIVILEGE_DESCRIPTION_RESOURCE");
        EventSystem.Subscribe<Component,SaveEventArgs>(SaveComponentHandler, EventPhases.Initiated);
      }
    }

    where FOLDER_URI is the Content Manager URI of the Folder in which only users with the custom privilege are allowed to save.

  5. In the same class, implement an Event Handler method to implement your business logic:
    private static void SaveComponentHandler(Component subject, SaveEventArgs e, EventPhases phase)
    {
      if (subject.OrganizationalItem.Id == "FOLDER_URI" && !HasSystemPrivilege(subject.Session.AccessToken, "PRIVILEGE_ID"))
      {
        throw new Exception("You are not authorized to save to this Folder.");
      }
    }
  6. In the same class, implement a privilege checking method to implement your business logic, which allows users with your specific privilege, or with administrator privileges, to perform the save:
    private static bool HasSystemPrivilege(AccessToken accessToken, string privilegeKey = TcmSystemPrivileges.TcmSystemAdministration)
    {
      return accessToken.InheritedSystemPrivileges != null && 
             accessToken.InheritedSystemPrivileges.Keys.Any(sysPriv => sysPriv.Key == privilegeKey || 
                                                            sysPriv.Key == TcmSystemPrivileges.TcmSystemAdministration);
    }
  7. Save and close your changes and add your extension DLL and resources to the Global Assembly Cache.
  8. On the Content Manager server, open Tridion.ContentManager.config for editing and configure the assembly in the extensions section:
    <add assemblyName="CustomPrivileges, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ddfc895746e5ee6b" />
  9. If you use resources file for localization, also configure these resources in the resources section under localization, which is itself under tridion.common:
    <add baseName="CustomPrivileges.Properties.Resources" assembly="CustomPrivileges, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ddfc895746e5ee6b" />
  10. Save and close Tridion.ContentManager.config.
  11. Use the Core Service client (typically in combination with a GUI extension) to get the new custom privilege and set it on a Group. This code sample shows the Core Service interaction:
    var systemPrivileges = clientUser.GetSystemPrivileges.ToList();
    var myPrivilege = privileges.FirstOrDefault(p => p.Key == "PRIVILEGE_ID");
    
    var group = (GroupData)clientUser.Read("GROUP_URI", new ReadOptions());
    group.SystemPrivileges = new [] { systemPrivilege };
    group = (GroupData)clientUser.Update(group, readOptions);

    where GROUP_URI is the Content Manager URI of the Group to which you want to grant this custom privilege.