The content you're reading is getting on in years
This post is on the older side and its content may be out of date.
Be sure to visit our blogs homepage for our latest news, updates and information.
In case you are building module where different users will have different level of permissions for working with the module, you can take advantage of the Generic Content security API. Generally speaking, there are four steps you will need to perform in order to enable permissions on your module.
Every module can inherit from WebModule or SecuredModule class. If module inherits from WebModule class, all users will be able to perform all operations. If module, however, inherits from SecuredModule class - we will have ability to access following two methods of the security API:
/// <summary> |
/// Gets the security root for the default provider |
/// </summary> |
public override ISecured SecurityRoot |
{ |
get |
{ |
return this.SecurityRoots[Configuration.ConfigHelper.Handler.DefaultProvider]; |
} |
} |
/// <summary> |
/// Gets key/value information for provider/global permissions. Preserves information |
/// for all providers. |
/// </summary> |
public override IDictionary<string, ISecured> SecurityRoots |
{ |
get |
{ |
return ProductsManager.SecurityRoots; |
} |
} |
You can examine the full code we are about to describe in ProductsManager class in our sample products module.
Our first goal is to make every provider of the products module a security root which can have its own permissions. Following excerpt of the code will allow us to do that:
/// <summary> |
/// Provides a static constructor of ProductsManager class. |
/// </summary> |
static ProductsManager() |
{ |
foreach (GenericContentElement element in ConfigHelper.Handler.GenericContentProviders) |
ProductsManager.contentSettings.Add(element.ProviderName, element); |
} |
/// <summary> |
/// Gets key/value information for provider/global permissions. Preserves information |
/// for all providers. |
/// </summary> |
public static Dictionary<String, ISecured> SecurityRoots |
{ |
get |
{ |
if (securityRoots == null) |
{ |
securityRoots = new Dictionary<String, ISecured>(ContentManager.Providers.Count); |
foreach (string name in contentSettings.Keys) |
securityRoots.Add(name, new GlobalPermissions(name)); |
} |
return securityRoots; |
} |
} |
private static Dictionary<String, ISecured> securityRoots; |
private static readonly IDictionary<string, GenericContentElement> contentSettings = new Dictionary<string, GenericContentElement>(); |
By doing so, we have set up the security for our module. From now on, we can use the CheckDemand and Demand methods explained at the beginning of this article.
To allow for centralized and simple access to permissions from all of our Views it is advisable that we implement the GetPermission methods in the manager class. Here is how this implementation looks like for the products module:
/// <summary> |
/// Gets the permissions for the current provider. |
/// </summary> |
public GlobalPermissions Permissions |
{ |
get |
{ |
return (GlobalPermissions)ProductsManager.SecurityRoots[this.settingsElement.ProviderName]; |
} |
} |
/// <summary> |
/// Gets GlobalPermission object for the secured object. |
/// </summary> |
/// <returns>GlobalPermission object</returns> |
public GlobalPermission GetPermission() |
{ |
return new GlobalPermission(this.Permissions); |
} |
/// <summary> |
/// Gets the current provider permissions for the specified rights. |
/// </summary> |
/// <param name="requestRights">the requested rights to check permissions for</param> |
/// <returns>GlobalPermission object</returns> |
public GlobalPermission GetPermission(int requestRights) |
{ |
return new GlobalPermission(this.Permissions, requestRights); |
} |
/// <summary> |
/// Gets the current provider permissions for the specified content owner identifier. |
/// </summary> |
/// <param name="contentOwnerId">the identifier of the content's owner</param> |
/// <returns>GlobalPermission object</returns> |
public GlobalPermission GetPermission(Guid contentOwnerId) |
{ |
IContent cnt = this.Content.GetCurrentState(contentOwnerId); |
return this.GetPermission(cnt); |
} |
/// <summary> |
/// Gets information for the current provider permissions for the specified |
/// content owner ID and rights. |
/// </summary> |
/// <param name="contentOwnerId">the identifier of the content's owner</param> |
/// <param name="requestRights">the requested rights to check permissions for</param> |
/// <returns>GlobalPermission object</returns> |
public GlobalPermission GetPermission(Guid contentOwnerId, int requestRights) |
{ |
IContent cnt = this.Content.GetCurrentState(contentOwnerId); |
return this.GetPermission(cnt, requestRights); |
} |
/// <summary> |
/// Gets the current provider permissions for the specified owner of the content. |
/// </summary> |
/// <param name="contentOwner">the owner of the content</param> |
/// <returns>GlobalPermission object</returns> |
public GlobalPermission GetPermission(IContent contentOwner) |
{ |
return new GlobalPermission(this.Permissions, contentOwner); |
} |
/// <summary> |
/// Gets the current provider permissions for the specified |
/// content owner and rights. |
/// </summary> |
/// <param name="contentOwner">the owner of the content</param> |
/// <param name="requestRights">the requested rights to check permissions for</param> |
/// <returns>GlobalPermission object</returns> |
public GlobalPermission GetPermission(IContent contentOwner, int requestRights) |
{ |
return new GlobalPermission(this.Permissions, requestRights, contentOwner); |
} |
/// <summary> |
/// Gets the permissions. |
/// </summary> |
/// <returns></returns> |
protected override GlobalPermissions GetPermissions() |
{ |
return this.Host.ProductsManager.Permissions; |
} |
/// <summary> |
/// Gets the permission. |
/// </summary> |
/// <returns></returns> |
protected override GlobalPermission GetPermission() |
{ |
return this.Host.ProductsManager.GetPermission(); |
} |
/// <summary> |
/// Gets the permission. |
/// </summary> |
/// <param name="requestRights">The request rights.</param> |
/// <returns></returns> |
protected override GlobalPermission GetPermission(int requestRights) |
{ |
return this.Host.ProductsManager.GetPermission(requestRights); |
} |
/// <summary> |
/// Gets the permission. |
/// </summary> |
/// <param name="contentOwnerId">The content owner id.</param> |
/// <returns></returns> |
protected override GlobalPermission GetPermission(Guid contentOwnerId) |
{ |
return this.Host.ProductsManager.GetPermission(contentOwnerId); |
} |
/// <summary> |
/// Gets the permission. |
/// </summary> |
/// <param name="contentOwnerId">The content owner id.</param> |
/// <param name="requestRights">The request rights.</param> |
/// <returns></returns> |
protected override GlobalPermission GetPermission(Guid contentOwnerId, int requestRights) |
{ |
return this.Host.ProductsManager.GetPermission(contentOwnerId, requestRights); |
} |
/// <summary> |
/// Gets the permission. |
/// </summary> |
/// <param name="contentOwner">The content owner.</param> |
/// <returns></returns> |
protected override GlobalPermission GetPermission(IContent contentOwner) |
{ |
return this.Host.ProductsManager.GetPermission(contentOwner); |
} |
/// <summary> |
/// Gets the permission. |
/// </summary> |
/// <param name="contentOwner">The content owner.</param> |
/// <param name="requestRights">The request rights.</param> |
/// <returns></returns> |
protected override GlobalPermission GetPermission(IContent contentOwner, int requestRights) |
{ |
return this.Host.ProductsManager.GetPermission(contentOwner, requestRights); |
} |
public class ProductsPermissionsView : PermissionsView<ProductsControlPanel> |
If you are unsure which Views are using permissions, you can simply try to override CheckPermission and DemandPermission in all Views - we have strictly followed this naming convention. For example, on the ProductsItemListView we have buttons for Creating new product, Editing existing product and Deleting a product. Since our products module is a secured module, we should check if currently logged in user has permissions to create new product, edit existing product and delete product and set up the user interface accordingly.
Generally, if we are building a custom module, we would need to perform all the logic for permissions and user interface alterations manually. Luckily, when you are building a Generic Content based module all this is done for you - all you need to do is point Sitefinity to the right GetPermission method.
In our example of the ProductsItemListView the only thing we need to do is to override CheckPermission method (this View does not demand any permissions) as follows:
/// <summary> |
/// Checks the permission. |
/// </summary> |
/// <param name="right">The right.</param> |
/// <returns></returns> |
protected override bool CheckPermission(int right) |
{ |
return this.Host.ProductsManager.GetPermission(right).CheckDemand(); |
} |
You can examine all the Views in products module and look for the regions named “Security overrides” to see different implementations of this approach, based on the security needs of every individual View.
View all posts from The Progress Team on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites
Progress collects the Personal Information set out in our Privacy Policy and the Supplemental Privacy notice for residents of California and other US States and uses it for the purposes stated in that policy.
You can also ask us not to share your Personal Information to third parties here: Do Not Sell or Share My Info
We see that you have already chosen to receive marketing materials from us. If you wish to change this at any time you may do so by clicking here.
Thank you for your continued interest in Progress. Based on either your previous activity on our websites or our ongoing relationship, we will keep you updated on our products, solutions, services, company news and events. If you decide that you want to be removed from our mailing lists at any time, you can change your contact preferences by clicking here.