Temporary disable the admin role

Lately I have been solving a lot of security related issues. To test these issues:

  • You create a new user with limited Roles
  • open a new session with this new user
  • and do your testing

But you could just make a job and run following code:

SecurityUtil::sysAdminMode(false);

an example :

Open a new workspace, assign the roles you want to test to your admin user. My admin user has 3 roles:

blog_roles_example

open a new developer workspace  to run the above code.

and again open a new workspace, you will now only have the accounts payable clerk role.

as you can see from the screenshots I no longer have access to other modules in AX.

blog_roles_example_2

blog_roles_example_3

When you are done with testing you can close the workspace again, go back to the developer workspace and reactivate the admin role.

SecurityUtil::sysAdminMode(true);

Note: Not only can you test stuff but you can also use the debugger.

Temporary disable the admin role

Using the SysLookMultiSelectCtrl

Hi,

I used the SysLookupMultiSelectControl a few times now and decided to blog about this new control.
First we will need to create a Query, mine is called demoCustQuery.

Then we create a table to store the selected data.

The selectedCustomer field is a container because the syslookupmultiselectctrl will return a container with the selected id’s and values.

Next I will create a new class to put the syslookupMultiselectControl logic in.

In the class declaration we define the syslookupMultiselectControl.

SysLookupMultiSelectCtrl msCtrl;

Create a constructor

public static demoCustMultiSelectCtrl construct(FormRun _frmRun, FormStringControl _namesCtrl, str _queryName, boolean _isMandatory = false, container _selectField = conNull())
{
    demoCustMultiSelectCtrl custMultiSelectCtrl;
    ;
    custMultiSelectCtrl = new demoCustMultiSelectCtrl();
    custMultiSelectCtrl.paramCustMultiSelectCtrl(SysLookupMultiSelectCtrl::construct(_frmRun,_namesCtrl,_queryName,_isMandatory,_selectField));

    return custMultiSelectCtrl;
}

Add a save method.

public void saveData(demoCustParameters  _demoCustParameters)
{
    ;
    ttsBegin;
    _demoCustParameters.selectForUpdate(true);
    _demoCustParameters.selectedCustomers = [msCtrl.get(), msCtrl.getSelectedFieldValues() ];
    _demoCustParameters.update();
    ttsCommit;
}

As you can see the selectedCustomers is a container of the selected ID’s and the selected fields.
Next add a load method.

public void loadData(container _data)
{
    ;
    msCtrl.set(_data);
}

then we will create the Form, name it demoCustParameters and add the demoCustomerParameters to the datasources. Allso add a string field to the form and put the autodeclaration to yes.

In the classDeclaration define a demoCustMultiSelectCtrl.

public class FormRun extends ObjectRun
{
    demoCustMultiSelectCtrl msCtrl;
}

In the init method of the form put the following code.

public void init()
{
    super();
    demoCustParameters::find();
    msCtrl = demoCustMultiSelectCtrl::construct(element, Customer, querystr(demoCustQuery));
}

And in the run method put following code.

public void run()
{
    super();
    msCtrl.loadData(demoCustomerParameters.selectedCustomers);
}

Override the modified method of the stringfield to force the write method of the datasource.

public boolean modified()
{
    boolean ret = super();
    ;
    demoCustomerParameters_ds.forceWrite(true);
    return ret;
}

After you selected some values and the modified method has fired you can see that the container field is filled in. The next time we open the form, our selected values will still be selected.

But what if we want to use these selected values in a query? The best way would be to save these values in a separate table.
So let’s create a new table to store these values.

Then create a new class for the syslookupMultiselectControl logic.

The code is allmost the same as the first class except for the load and save methods.

public void loadData()
{
    demoCustParametersSelectedValues demoCustParameters;
    container c,v;
    ;

    while select demoCustParameters
    {
        c += demoCustParameters.AccountNum;
        v += demoCustParameters.CustGroupId;
    }

    msCtrl.set([c,v]);

}
public void saveData()
{
    demoCustParametersSelectedValues demoCustParameters;
    container c,v;
    int i;
    ;

    ttsBegin;
    delete_from demoCustParameters;

    c = msCtrl.get();
    v = msCtrl.getSelectedFieldValues();

    for (i = 1; i <= conLen(c);i++)
    {
        demoCustParameters.clear();
        demoCustParameters.AccountNum = conPeek(c,i);
        demoCustParameters.CustGroupId = conPeek(v,i);
        demoCustParameters.insert();
    }
    ttsCommit;
}

And finnaly create a new form.

public class FormRun extends ObjectRun
{
    demoCustMultiSelectCtrlSelectedValues msCtrl;
}

In the init method use the constructor from the new class we created.

public void init()
{
    super();
    msCtrl = demoCustMultiSelectCtrlSelectedValues::construct(element, Customer, querystr(demoCustQuery));
}

The run method.

public void run()
{
    super();
    msCtrl.loadData();
}

And add the save method on the modified method of the field.

public boolean modified()
{
    boolean ret = super();
    ;
    msCtrl.saveData();
    return ret;
}

And that’s it. The selected values should be stored in a separate table now.
If any of you have any remarks feel free to comment.

Using the SysLookMultiSelectCtrl

Testing the code upgrade tool for AX 2012 part 3: Extending

Hello,

In the previous parts we covered the installation and how to use the code upgrade tool. Now we will extend the error rules with our own rules. I’ll be explaining this with very simple example. We will be writing a very simple rule that will check for a method called testmethod1 and change it to testmethod2.

to do this we have to add 2 global functions:

static void testmethod1(str test)
{
    info(test);
}
static void testmethod2(str test)
{
    info(test);
}

And a class where these functions will be called.

class subjectclass
{
}
public void testoutmethod()
{
    ;
    testmethod1("test");
}

Now we will create our own rule , first unzip the CodeUpgradeTool.Rules.Partner.zip This zip file contains a Visual Studio solution that contains an empty template.

Open the solution in Visual Studio and check that you have following references:

  • Microsoft.Dynamics.AX.Framework.Xlnt.XppParser
  • Microsoft.Dynamics.AX.Framework.Xlnt.XppParser.Pass2


Open up the TestRuleMutator and fill in the attributes


Next we must override the VisitFunctionCall method

protected override Evaluation VisitFunctionCall(object payload, FunctionCall functionCall)
{
return base.VisitFunctionCall(payload, functionCall);
}

Paste following code in this method. What this code does is it will take in the current function, check that is called testmethod1 and that it has 1 parameter then it will create a second method called testmethod2 and attach the same parameters to it.

Guard.ValidateIsNotNull(functionCall, @"functionCall");
// Make a copy of the incoming function:
var modifiedFunctionCall = base.VisitFunctionCall(payload, functionCall) as FunctionCall;
int count = 0;
//Check if the incoming method is called testmethod1 and that is has 1 parameter
if (modifiedFunctionCall.FunctionName.Compare("testmethod1") && modifiedFunctionCall.ActualParameters.Count() == 1)
{
    //Create a new function , name it testmethod2 and add the parameters
    var newFunctionCall = new FunctionCall { FunctionName = "testmethod2", ActualParameters = modifiedFunctionCall.ActualParameters};
    count = count + 1;
    this.AddCommentToClosestEnclosingNode(modifiedFunctionCall, functionCall + " TO " + newFunctionCall);
    this.DiagnosticsHandler.AddDiagnostic(count,
                                          this.GetType().Name,
                                          this.ClassName,
                                          this.MethodName,
                                          functionCall.Position,
                                          Severity.Warning,
                                          ErrorMsg.Error
                                          );
    return newFunctionCall;
}
return modifiedFunctionCall;

Next we build our solution and copy the DLL to the client/bin folder ( like we did in the first part). Then we can again load up the new rules in AX,check for code upgrade patterns and fix them.


This was a very simple example but Microsoft included the source for their original rules in the package(CodeUpgradeTool.Rules.zip). People who want to use this tool and write their own rules can check out these examples. There are lots of methods than can be overridden.

Some references:
http://technet.microsoft.com/en-us/library/hh535215.aspx
https://informationsource.dynamics.com/RFPServicesOnline/RFPSLHost.aspx#/View/ToolsDownload.xaml

In this part we extended the tool by creating our own rule. I hope this post ( and the previous posts) are helpfull to you.

Testing the code upgrade tool for AX 2012 part 3: Extending

Testing the code upgrade tool for AX 2012 part 2: using the tool

Hi,

In the previous part we covered the installation and setup of the code upgrade tool. In this part we will check for code upgrade problems on some projects that Microsoft included in the Package.

So first import:

  • SharedProject_CUT_MutatorDemoClasses.xpo
  • SharedProject_CUT_SweeperDemoClasses.xpo

When importing these projects don’t mind the errors J

After the import restart your client because otherwise the tool might not pick up the code upgrade errors.

The CUT_MutatorDemoClasses project contains errors that the tool can identify and fix by its self. The CUT_SweeperDemoClasses project contains errors that the tool can identify but cannot fix by its self.

To check a project on code upgrade errors simply right-click the project à add-Ins à check code upgrade patterns.

When the tool is finished checking the code you will get an overview of all errors found. And it will say if it can automatically fix it or not.

If the error can be fixed automatically, just select it and click fix upgrade pattern. Here you can see the error and how it will be changed. click Fix method to solve the error.

In this part we covered the use of the Code upgrade tool. In the following part we will extend to tool so we can load up our own code upgrade rules.

Some references:

http://technet.microsoft.com/en-us/library/hh535215.aspx

https://informationsource.dynamics.com/RFPServicesOnline/RFPSLHost.aspx#/View/ToolsDownload.xaml

 

Testing the code upgrade tool for AX 2012 part 2: using the tool

Testing the code upgrade tool for AX 2012 part 1: installation

Hello,

I have been asked to try out the code upgrade tool from Microsoft to see if it’s useful for us in the future. The tool can be downloaded from the Microsoft information source:

https://informationsource.dynamics.com/RFPServicesOnline/RFPSLHost.aspx#/View/ToolsDownload.xaml

first we need to unzip the package, so run the CodeUpgradeService-0.8-Beta.exe

the Package contains the following items:

 

next we need to put following assembly’s in the our clientbin folder( C:Program Files (x86)Microsoft Dynamics AX60ClientBin)

  • Microsoft.Dynamics.AX.Framework.Xlnt.XppParser.dll
  • Microsoft.Dynamics.AX.Framework.Xlnt.XppParser.Pass2.dll
  • Microsoft.Dynamics.AX.Tools.CodeUpgradeTool.AssemblyReader.dll
  • Microsoft.Dynamics.AX.Tools.CodeUpgradeTool.Rules.dll

Then we need to install following models into our environment

  • XLNT Model.axmodel
  • CodeUpgrade Tool Model.axmodel

Install these models with your preferred method, I used axutil.

axutil import /file:"c:/temp/XLNT Model.axmodel" /conflict:push /verbose
axutil import /file:"c:/temp/CodeUpgrade Tool Model.axmodel" /conflict:push /verbose

When the models are imported restart your AOS and start your client you get the message that the model store has been is changed, just skip it.

Now create 2 projects by going to tools à model management à create project from model

And select our newly installed models.

Then compile the new projects , be sure to compile the XLNT project first and then the CodeUpgrade Tool project.

Now it’s time to load up the upgrade rules.

Go to Tools à Code upgrade à Import code upgrade rules.

 

Load the Microsoft.Dynamics.AX.Tools.CodeUpgradeTool.Rules.dll

And then restart your client again.

Finally go to tools à options à development tab à click code upgrade checks

And select all the nodes.

 

Now we have installed and set up the code upgrade tool.

Some references:

http://technet.microsoft.com/en-us/library/hh535215.aspx

https://informationsource.dynamics.com/RFPServicesOnline/RFPSLHost.aspx#/View/ToolsDownload.xaml

This was part 1 in testing out the the code upgrade tool. In the following parts we will test out the tool and extend it by creating new code upgrade rules.

Testing the code upgrade tool for AX 2012 part 1: installation

SQL 2008 tracing

Hello ,

Last week I had to find out which Tables and fields are used when running the Inventory Closing Procedure in AX2009.

So … we could dive into the code and start debugging things. But when I comes to something as complicated as the Inventory Closing Procedure it’s easy to miss important pieces of code when you are debugging.

That’s why I tried to do an SQL trace( for the first time!)

This is how I did it:

Connect to DB instance of your AX environment and start the SQL server profiler.

 

In the Trace properties, I chose save to file because later the files will be used by ClearTrace

Next I selected all Events on the events selection tab.

Click Run to start your trace.

Now go to AX and run the Inventory Closing Procedure. When the job is finished go back to the Profiler and stop the trace.

Next open up ClearTrace.

The first time you open Cleartrace you will need to set up a Database. When the database is created for the traces you can import the trace files.

This might take some time depending on the speed of your computer and the size of the trace files.

When the import is finished the program will give you an overview of the executed queries, how many times the queries where preformed , how many reads and writes, how long and how heavy it was for the CPU.

Some references:

To setup a trace

http://technet.microsoft.com/en-us/library/ms175047.aspx

cleartrace

performing Traces

http://programming4.us/database/2956.aspx

SQL 2008 tracing