nopCommerce SuperAdmin and Access Control

The nopCommerce access control is fantastic and it achieves its purpose fully. If for example, me as the ultimate administrator doesn’t want the Staff users to see my PalPal configuration settings, I can simply disable the access from the list and they will get an access denied message when they try that link. However, there are cases where us as a consultant / developer we want to refrain the users (owner or staff) from seeing some of the available features for various reasons – maybe you didn’t sell that to them, maybe that’s not applicable to their business (the simpler the application the better). It could be sometimes confusing being a business owner but got denied access to part of your website. In addition, in order to handle such “exceptions” you need good documentations and overtime it just increases your maintenance costs. Hence I am adding a SuperAdmin property to the Customer class and also a custom configuration setting in web.config to achieve the hiding of some features. The reason for adding this into the web.config is to help ourselves remember what we’ve done in the future.

First in ~/Libraries/Nop.BusinessLogic/Customer/Customer.cs I am adding a public property called IsSuperAdmin.

/// <summary>
/// Gets a boolean indicating if this custom is a Super Admin (CustomerRoleId == 1)
/// </summary>
public bool IsSuperAdmin
{
    get
    {
        if (this.CustomerRoles.SingleOrDefault(t => t.CustomerRoleId == 1) != null)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

It’s defining the CustomerRold with ID = 1 as the “Super Admin” role, which means that you will need to make sure in the database that the one with ID = 1 is indeed the customer role you want to have the ultimate access. Ideally there should be a column in the Customer table for this flag, but I think this is the easiest way without modifying the data structure.

Next I will add a new section to NopConfig in web.config, which I am calling AdminSettings (Of course you could name it as whatever makes most sense to you).

<NopConfig>
    …            <AdminSettings>        <AdminSetting key="CategorySEOTabVisibility" value="false" />    </AdminSettings></NopConfig>

The NopConfig class handles the custom config section <NopConfig> in web.config. So I am adding a property called AdminSettings in ~/Libraries/BusinessLogic/Configuration/NopConfig.cs to store this new </AdminSettings> config section.

private static Dictionary<string, string> _adminSettings = null;
public static Dictionary<string, string> AdminSettings
{
    get { return _adminSettings; }
}

The ideal place to initialize this property is in the Create method. If you follow the code path, you can see that these config settings are initialized in global.asax.

public object Create(object parent, object configContext, XmlNode section){
    // Other code
    XmlNode adminSettingNodes = section.SelectSingleNode("AdminSettings");
    if (adminSettingNodes != null)
    {
        _adminSettings = new Dictionary<string, string>();
        foreach (XmlNode pdNode in adminSettingNodes.ChildNodes)
        {
            if (string.Compare(pdNode.Name.Trim(), "adminsetting", true) == 0)
            {
                _adminSettings.Add((string)pdNode.Attributes["key"].Value, (string)pdNode.Attributes["value"].Value);
            }
        }
    }
    return null;
}

 

With all of these in place, we can start to hide out some of the components in the admin pages. For example, if we wish to hide the SEO tab in the category editing page. We will use the following line in Page_Load of the CategoryDetailsControl class (~/Administration/Modules/CategoryDetails.ascx.cs)

pnlCategorySEO.Enabled = pnlCategorySEO.Visible = ((!NopConfig.AdminSettings.ContainsKey("CategorySEOTabVisibility")) || Boolean.Parse(NopConfig.AdminSettings["CategorySEOTabVisibility"]) || NopContext.Current.User.IsSuperAdmin);

For another instance, if we wish to not hide the “Customer Enter Price” checkbox in product variant editing page because the business just will never allow customers to enter their own price, we can do the following in ~/Administration/Modules/ProductVariantInfo.ascx.

<% if (!NopSolutions.NopCommerce.BusinessLogic.Configuration.NopConfig.AdminSettings.ContainsKey("ProductVariantCustomerEnterPriceCheckboxVisibility") ||
           Boolean.Parse(NopSolutions.NopCommerce.BusinessLogic.Configuration.NopConfig.AdminSettings["ProductVariantCustomerEnterPriceCheckboxVisibility"]) ||
           NopContext.Current.User.IsSuperAdmin)
       {%>
    <tr>
        <td class="adminTitle">
            <nopcommerce:tooltiplabel runat="server" id="lblCallForPrice" text="<% $NopResources:Admin.ProductVariantInfo.CallForPrice %>"
                tooltip="<% $NopResources:Admin.ProductVariantInfo.CallForPrice.Tooltip %>" tooltipimage="~/Administration/Common/ico-help.gif" />
        </td>
        <td class="adminData">
            <asp:CheckBox ID="cbCallForPrice" runat="server" Checked="False"></asp:CheckBox>
        </td>
    </tr>
<%} %>

 

Hope this is useful! Feedbacks are welcome and maybe better ways to achieve such!

By Bryan Xu

Tagged with: ,
Posted in eCommerce

Leave a Reply