Extending opportunities with AX 2012 XDS

Updated: 04.03.2016

How to create flexible tables’ elements’ access solution using AX 2012 XDS.

What is XDS in AX 2012

It is a new functionality which lets restrict access to datasets based on Query for either all users or users with specified role (or by other conditions).

The example below shows how to restrict access to Customer Group, Customer, Order directories and all related objects in the context of company.

Terms & conditions:

  1. Customer and Customer Group directories are shared for all companies;
  2. Screenshots don’t show initial task, but common principles are kept.

Example

  1. We create new table where we store link to a Customer Group and company, which one is allowed to have access. The new table is universal, so we can use it to store access rights for the objects in the context of companies. It’s necessary to establish relations between new table and CustTable and CustGroup tables.

 

public static Axp_VirtualTable find(DataAreaId _companyId, RefTableId _refTableId, RefRecId _refRecId)

{

    Axp_VirtualTable    virtualTable;

    ;

    if (_companyId && _refTableId && _refRecId)

    {

        select firstOnly firstFast virtualTable

            where virtualTable.RefTableId == _refTableId

               && virtualTable.RefRecId   == _refRecId

               && virtualTable.CompanyId  == _companyId;

    }

 

    return virtualTable;

 

}

public static boolean exist(DataAreaId _companyId, RefTableId _refTableId, RefRecId _refRecId)

{

    ;

    return (Axp_VirtualTable::find(_companyId, _refTableId, _refRecId).RecId != 0);

 

}

 

  1. We create function to fill new table. To do it we used a class and small form’s modification.

Using “+” and “-” buttons we can add and delete records in new table. It lets us allow or deny proceeding of operations defined by current policy in selected company.

In last field we see a list of companies where operations defined by current policy are allowed.

class Axp_VirtualTableService

{

    Common              record;

    Object              caller;

    FormStringControl   control;

    Axp_VirtualTable    virtualTable;

}

 

public void addCompany(DataAreaId _companyId)

{

    ;

    if (_companyId && record.RecId && ! Axp_VirtualTable::exist(_companyId, record.TableId, record.RecId))

    {

        virtualTable.clear();

        virtualTable.RefTableId = record.TableId;

        virtualTable.RefRecId   = record.RecId;

        virtualTable.CompanyId  = _companyId;

        virtualTable.insert();

    }

}

public display string50 companyList()

{

    string50         ret = "";

    ;

    while select CompanyId from virtualTable

        where virtualTable.RefTableId   == record.TableId

           && virtualTable.RefRecId     == record.RecId

    {

        if (! ret)

        {

            ret = virtualTable.CompanyId;

        }

        else

        {

            ret = ret + strFmt(", %1", virtualTable.CompanyId);

        }

    }

    return ret;

}

public void init()

{

    ;

    if (control)

    {

        control.text(curext());

    }

}

public Object parmCaller(Object _caller = caller)

{

    ;

    caller = _caller;

 

    return caller;

}

public FormStringControl parmControl(FormStringControl _control = control)

{

    ;

    control = _control;

 

    return control;

}

public Common parmRecord(Common _record = record)

{

    ;

    record = _record;

 

    return record;

}

public void removeCompany(DataAreaId _companyId)

{

    ;

    if (_companyId && record.RecId)

    {

        delete_from virtualTable

            where virtualTable.RefTableId == record.TableId

               && virtualTable.RefRecId   == record.RecId

               && virtualTable.CompanyId  == _companyId;

    }

}

public static Axp_VirtualTableService construct(Common _record, object _caller = null, FormStringControl _control = null)

{

    Axp_VirtualTableService     virtualTableService;

    ;

    virtualTableService = new Axp_VirtualTableService();

    virtualTableService.parmRecord(_record);

    virtualTableService.parmCaller(_caller);

    virtualTableService.parmControl(_control);

 

    virtualTableService.init();

 

    return virtualTableService;

}

Class is extensible to draw all necessary buttons by itself.

  1. We create an Query which will be an basement for SecurityPolicy

Query can be as complicated as you want but it has to work fast and compile with no errors. In the example you see Union query. It lets get access to all group’s elements if group is marked as available, and to elements which are allowed by themselves. In our case it’s enough to create CustTable group and create Exist Join with new table.

Pay attention on filter in Query. We use a dynamical value. We can add our methods in SysQueryRangeUtil class.

  1. Eventually, we create SecurityPolicy. More details are available in attached documents.

 

Pay attention on Constrainedtable. In our case PrimaryTable has to have CustGroup value, and ConstrainedTable property has to have CustTable value. Both of tables have to have Yes value in ConstrainedTable property on elements’ properties.

  1. Initially, let’s restrict policy action by Select statement. It’s necessary to compile everything. Policy is ready to use. In our case, policy will be applied for all users except Administrator. If necessary you can use policy for selected role.
 

Other blog posts

14.11.2017
Why outsourcing company is more effective than In-house IT-specialists There are situations when in-house specialists spend most of their time awaiting requests or they cannot get their work...
26.09.2017
Microsoft Dynamics AX program decisions are constantly improving. At first, innovations come to European companies, and only after that to Russian enterprises.We aspire to be one step ahead in this...
28.08.2017
Notes of the summit and of Dynamics market in Russia. Neti has been specializing in AX development since 2003. Our sphere of interest is the cutting-edge MS Dynamics technology. We find, study...

Subscribe for blog updates

Get updated with our blog new articles via your email!


Subscribe now