titatovenaar
titatovenaar

Reputation: 309

How to enable Security Logging AX2012 (SecurityTasks to SecurityRoles)

I want to log SecurityRole - SecurityTask changes, and since the EeUserRoleChangeLog logs UserSecurityRole changes (for Estonia, but commenting out language detection, it logs also for us here in Holland perfectly). I think that basis can be used to log those changes.

So I first created the table: EeRoleTaskChangeLog with the following fields: AddRemove EnumType: AddRemove ChangedBy EDT: UserID SecurityRole EDT: RefRecID SecurityTask EDT: RefRecId

I then noticed that within the class SysSecRole, User-Role changes logging is triggered within method removeFromSelectedUser. So whenever someone changes something from the AOT or the front-end, all these changes are then logged within the EeUserRoleChangeLog.

So I extended SysSecTask with the method removeFromSelectedRole:

public void removeFromSelectedRole() 
{
    RefRecId                    SecurityRole;       
    SysSecTreeTasks             taskTree;          
    SecurityRoleTaskGrant       SecurityRoleTaskGrant;  

    taskTree = tree as SysSecTreeTasks; 
    securityRole = taskTree.getSecurityRole(); 

    ttsbegin;

    EePersonalDataAccessLogging::logRoleTaskChange(recId, 0, securityRole, AddRemove::Remove);

    delete_from securityRoleTaskGrant where securityRoleTaskGrant.SecurityRole == securityRole && securityRoleTaskGrant.SecurityTask == recId;

    ttscommit;

    if (treeControl)
    {
        tree.deleteTreeItem(treeControl, idx);
    }
    }

However, it somehow doesn’t recognize the triggers and so it does not fill my table. I hoped to add a delete/insert trigger to the SecuryRoleTaskGrant systemtable, but this is completely closed, so I have no idea how or where this method can be triggered.

So then I thought as a ‘semi-working’ work around, let’s only log changes made in the front-end, since that already fixes the problem for the regular workers. So I decided to find a similar trigger within Forms, and I found the form SysSecUserAddRoles with method assignRolesToSelectedUser. This method has the following trigger:

    if (added)
    {
        EePersonalDataAccessLogging::logUserRoleChange(secRole.RecId,0, userId, AddRemove::Add);
    }

I decided to add this trigger to a Form that allows workers to change Task-Roles: SysSecRoleAddTasks method addTasksFromRole, and somehow this also does not seem to fix the problem. It doesn’t fill the table. I use the following code, and front-end changes are still not logged within my created EeRoleTaskChangeLog table.

public int addTasksFromRole(SecurityRole _role, boolean _recursive = false)
{
    SecurityRole childRole;
    SecuritySubRole subRole;
    SecurityTask task;
    SecurityRoleTaskGrant srtGrant;
    int nAdded = 0;
    RefRecId    securityRole;
    boolean             added;

    if (_role.RecId == targetRoleId)
    {
        return 0;
    }

    startLengthyOperation();
    while select task
    join SecurityRole, SecurityTask from srtGrant
    where  srtGrant.SecurityRole == _role.RecId
        && srtGrant.SecurityTask == task.RecId
    {
        nAdded += this.addTask(task);
    }

    if (_recursive)
    {
        while select childRole
        where childRole.RecId != targetRoleId
        join SecurityRole, SecuritySubRole from subRole
        where  subRole.SecuritySubRole == childRole.RecId
            && subRole.SecurityRole    == _role.RecId
        {
            this.addTasksFromRole(childRole, true);
        }
    }
    endLengthyOperation();

    if (added) //Added
            {
                EePersonalDataAccessLogging::logRoleTaskChange(securityTask.RecId,0, securityRole, AddRemove::Add);
            }

    return nAdded;
    }

Why doesn’t this trigger the logging? Do I need to provide any more information? The SysSecRoleAddTasks Form has also the addTask method, I tried it here as well, but this again doesn’t trigger the logtable to be filled.

public int addTask(SecurityTask _task, boolean _trialAdd = false)
{
    SecurityRoleTaskGrant srtGrant;
    int nAdded = 0;
    boolean             added; //Added
    RefRecId    securityRole; //Added

    select targetRole
    where targetRole.RecId == targetRoleId; // make sure in sync

    select forupdate srtGrant
    where  srtGrant.SecurityTask == _task.RecId
        && srtGrant.SecurityRole == targetRoleId;

    if (!srtGrant)
    {
        if (!_trialAdd)
        {
            ttsbegin;
            srtGrant.SecurityTask = _task.RecId;
            srtGrant.SecurityRole = targetRoleId;
            srtGrant.insert();
            nAdded++;

            myObjects.insert(_task.RecId, true);

            if (added) //Added
            {
                EePersonalDataAccessLogging::logRoleTaskChange(securityTask.RecId,0, securityRole, AddRemove::Add);
            }

            ttscommit;
        }
        else if (targetRoleId != 0)
        {
            nAdded++;
        }
        //info('Added task "' + _task.Name + '" (' + int2str(appl.ttsLevel()) + ')');
    }
    /*
    else
    {
        info('Not adding task "' + _task.Name + '"');
    } */

    return nAdded;
    }

Any suggestions?

Upvotes: 0

Views: 385

Answers (1)

Alex Kwitny
Alex Kwitny

Reputation: 11544

This question requires a lot of hands-on debugging I would think to solve, which I'm not sure many posters are going to do unfortunately. Have you tried just using the system's database log?

SecurityRole and SecurityTask are system tables, stored under \System Documentation\Tables\SecurityRole, so I didn't know where to find them in the DB log wizard, but I wrote a manual job that I think should work.

I've only tested it with UserInfo, which is another system table and it appears to have logged changes correctly.

static void AddTablesToDBLog(Args _args)
{    
    void logTable(TableId _tableId, DatabaseLogType _logType)
    {
        DatabaseLog dblog;

        dblog.logTable      = _tableId;
        dblog.logField      = 0;
        dblog.logType       = _logType;
        dblog.insert();
    }

    ttsBegin;
    logTable(tableNum(SecurityRole), DatabaseLogType::Insert);
    logTable(tableNum(SecurityRole), DatabaseLogType::Update);
    logTable(tableNum(SecurityRole), DatabaseLogType::Delete);

    logTable(tableNum(SecurityTask), DatabaseLogType::Insert);
    logTable(tableNum(SecurityTask), DatabaseLogType::Update);
    logTable(tableNum(SecurityTask), DatabaseLogType::Delete);
    ttsCommit;

    SysFlushDatabaseLogSetup::main();

    new MenuFunction(menuitemDisplayStr(SysDatabaseLogSetup), MenuItemType::Display).run(null);
    info("Done");
}

Upvotes: 2

Related Questions