XPO

GDPR tool for Microsoft Dynamics AX 2012

The European Union has introduced strict data protection rules last month, for which companies had to become legally compliant to avoid fines. We have a set of patches to apply to get a GDPR tool for Microsoft Dynamics AX 2012, which has been released to assist us:

  • KB4056903 Privacy Policy update
  • KB4074643 DAPIA Security tool
  • KB4057507 SQM Data collection

The part relevant for us is the tool, which allows capturing which interactive users have logged on to AX, who are using a security role that may access sensitive information.

GDPR tool for Microsoft Dynamics AX 2012
User log for roles with sensitive information access
GDPR tool for Microsoft Dynamics AX 2012
Setup of roles with sensitive data access

Unfortunately Microsoft only provides a high-level guideline on what shall be included and provides very little tangible assistance. Due to this I have felt we needed some way to identify what security roles could really be accessing sensitive data, so I came up with an X++ job that does exactly this. You may pass in menu items for forms, reports and also tables that may access details such as Customers, Global Address Book, Vendors, Address and Contact details. The tool is using the Security framework to determine which roles can edit such data, but you may change filter criteria to also include View access.

static void WIK_GDPR_enable_roles(Args _args)
{
    #AOT
    
    // List of tables which might contain sensitive data
    container           tables = [
        [menuitemDisplayStr(CustTable), UtilElementType::DisplayTool]
        ,[menuitemDisplayStr(CustTableListPage), UtilElementType::DisplayTool]
        ,[menuitemDisplayStr(CustTableEdit), UtilElementType::DisplayTool]
        ,[menuitemDisplayStr(CustTableDetails), UtilElementType::DisplayTool]
        ,[menuitemDisplayStr(GlobalAddressBookListPage), UtilElementType::DisplayTool]
        ,[menuitemDisplayStr(DirPartyTable), UtilElementType::DisplayTool]
        ,[menuitemDisplayStr(DirPartyTableEdit), UtilElementType::DisplayTool]
        ];
    
    // Replace role settings?
    boolean                 update = NoYes::Yes;
    
    UtilElementType         objectType;
    str                     objectName;
    int                     i = 1;
    SysSecFlatDataTable     objects;
    SysSecFlatDataTable     allObjects;
    SysUserLogRoleSettings  roleSettings;
    SecurityRole            securityRole;
    
    allObjects.setTmp();
    
    while (i <= conLen(tables))
    {
        objectName = conPeek(conPeek(tables, i), 1);
        objectType = conPeek(conPeek(tables, i), 2);
        
        switch (objectType)
        {
            // Implemented from \Forms\SysSecObjectsInRole\init
            case UtilElementType::DisplayTool:
                SysSecObjectsFromEntryPoint::GenerateData(
                    SysSecObjectsAnalyzeType::SecViewRelatedRoles,
                    objectName,
                    enum2int(objectType));
                break;
                
            case UtilElementType::OutputTool:
                SysSecObjectsFromEntryPoint::GenerateData(
                    SysSecObjectsAnalyzeType::SecViewRelatedRoles,
                    objectName,
                    enum2int(objectType));
                break;
                
            case UtilElementType::ActionTool:
                SysSecObjectsFromEntryPoint::GenerateData(
                    SysSecObjectsAnalyzeType::SecViewRelatedRoles,
                    objectName,
                    enum2int(objectType));
                break;
                
            case UtilElementType::Table:
                SysSecObjectsFromSecurableObject::GenerateData(
                    objectName,
                    enum2int(objectType));
                break;
        }
            
        while select objects
        {
            allObjects.clear();
            buf2Buf(objects, allObjects);
            allObjects.doInsert();
        }
        
        i++;
    }
 
    if (update)
    {
        i = 0;
        ttsBegin;
        
        update_recordSet roleSettings
            setting HasAccessToSensitiveData = NoYes::No;
        
        // No join for Tmp object, must use nested loop
        while select allObjects
            group by Role//, IsOverride
            where allObjects.IsOverride    == NoYes::No
                && ((allObjects.AccessRight != AccessRight::View && allObjects.AccessRight != AccessRight::NoAccess)
                    && (allObjects.EntryPointAccess !=  AccessRight::View && allObjects.EntryPointAccess != AccessRight::NoAccess))
        {   
            select firstOnly forUpdate roleSettings
                join RecId from securityRole
                    where  securityRole.AotName      == allObjects.Role
                        && roleSettings.SecurityRole == securityRole.RecId;
            
            if (roleSettings)
            {
                roleSettings.HasAccessToSensitiveData = NoYes::Yes;
                roleSettings.doUpdate();
                i++;
            }
        }
        
        ttsCommit;
        
        info(strFmt('%1 security roles have been updated', i));
    }
 
    while select Role, RoleName
        from allObjects
        group by RoleName, Role//, AccessRight, EntryPointAccess
        where allObjects.IsOverride     == NoYes::No
            && ((allObjects.AccessRight != AccessRight::View && allObjects.AccessRight != AccessRight::NoAccess)
                && (allObjects.EntryPointAccess !=  AccessRight::View && allObjects.EntryPointAccess != AccessRight::NoAccess))
    {
        info(strFmt('%1 (%2)', allObjects.Role, allObjects.RoleName));
    }
}

The XPO could be downloaded from GitHub.

https://github.com/DAXRunBase/AX-2012-R3/tree/master/GDPR%20security%20roles
By |2020-03-23T13:37:46+01:00June 29th, 2018|Categories: AX 2012|Tags: , , , , |4 Comments

Hardcoded label fix tool for AX 2012

It is a common problem that developers create the objects and code in the shortest time possible to meet a deadline, and that is when we meet with the hardcoded label problem, which is a Best Practice violation. Our environment had about 6000 hardcoded label values as well, and I was looking for a general solution to fix them, which resulted in creating a new tool.

This tool is heavily beta version, comes with no warranties, use it at your own risk.

Hardcoded label

The hardcoded label fix tool is version control compatible, and you should really use it through that, in case you would like to roll back a set of incorrect modifications easily.

Once you open the form, the Scan button will process your entire AOT on the current layer and model and stores TreeNode path, type, text and possible label matches. Processing can take up to several hours.

Then you could multi-select labels and press Commit to replace the values. For blank entries it tries to create a new label in the currently selected (must be checked out in advance!) label file and language. If there are multiple hits for the text, it is marked by 3 asterisks, and you need to pick one on the right pane to use. In case you want to have your own labels created anyway, you could erase the recommended @SYS* or whatever entries, save the record then commit for a new one.

Please note that due to the nature of AX DB being Case Insensitive, it is possible that a label is recommended which has a different case, like you get label for ‘a’ instead of ‘A’.

The project can be downloaded from the DAXRunBase GitHub.

By |2018-03-30T13:54:33+02:00March 30th, 2018|Categories: AX 2012|Tags: , , , , |1 Comment

Add call stack to InfoLog messages

The main communication channel for our ERP users in case we want to tell them something is via the InfoLog messages within Microsoft Dynamics AX. In case we get an error or a warning, the technical staff does not receive the details required to troubleshoot the issue much easier. In this post I would like to show you how to send the X++ or .Net CIL call stack to InfoLog messages.
Microsoft already has an article on this for AX 2009, but that was before the AX 2012 IL code execution for server-side code, so it needs slight adjustments.

https://blogs.msdn.microsoft.com/axsupport/2010/08/02/how-to-send-the-callstack-to-the-infolog/

My changes got the following improvements:

  • Can handle X++ and CIL execution.
  • Users only see the call stack when clicking the message line due to filling it with whitespace.
  • Specific users could be excluded from receiving the call stack, we are doing this for our service accounts such as the batch execution account. We are also excluding our eCommerce portal customers from seeing a call stack, which are the Claims-based users.
  • Current database server/name and user account is included in the message, in case we are storing the errors in the Event log and would like to know who had the problem.

Here is the example output:

call stack to InfoLog
(more…)
By |2020-03-23T13:50:07+01:00July 20th, 2017|Categories: AX 2012|Tags: , , , , , , |0 Comments

Working with Entity Store and DIXF in AX

There is an excellent tool available for advanced reporting and BI capabilities that partners and customers should start exploring. In this post I would like to show how to work with Entity Store and DIXF in AX, which has been published shortly after the Technical Conference held in Seattle last year: https://www.daxrunbase.com/2016/02/24/technical-conference-day-1/

Working with the Entity Store and DIXF in AX takes some time to set up, but once it is running, it is acting as an up-to-date Data Warehouse for you, where you could utilize advanced features such as Clustered Columnstore Indexes, and make truly amazing visualizations which will please the eyes of your managers whom loves KPIs, and will make your teams more productive by knowing what to look for.

You can find the Public PowerBI built for the stock and items at JJ Food Service as an example of what could be achieved for visualizations built on data that is coming out of your AX environment:

PowerBI

(more…)

By |2017-06-07T11:36:34+02:00June 7th, 2017|Categories: AX 2012|Tags: , , , , , , , , |4 Comments

Improved TFS Version Control tools

All companies should be using some form of Version Control nowadays, as Microsoft is also pushing us in that direction with Dynamics 365 for Operations already. The frameworks in AX are mostly open, ready for improvement – and there is a lot of room for that. You can find below some of my improved TFS Version Control tools below. If you have additional tools or ideas, feel free to share it.

  1. XPO Import dialog

    A new Check out button has been added, so when trying to import an object from XPO that is already under VCS, you do not have to navigate to the AOT, but can directly access it from here.
  2. Version Control Pending objects

    The Version Control Changes > Contents list already had an Open new window button for the currently selected objects, but it was missing from the Pending objects list – which is more frequently used -, until now.
  3. Version Control Check-in dialog

    IDs are now sorted in a descending order to have the most recent tasks on the top.
    I am now hiding the TFS entries in a Closed state by default and can be shown by a checkbox.
    Developers are typically working on Tasks, which was opened from a User Story using the Agile methodology setup in VCS, and check-ins are done against Tasks, so now I am hiding User Stories by default.

Please find attached the Improved TFS Version Control tools.

By |2017-05-20T10:08:38+02:00May 20th, 2017|Categories: AX 2012, TFS|Tags: , , , , , , |0 Comments
Go to Top