1

I'm trying to check whether a user exporting a report has a certain Custom Permission for a Transaction Security Condition Class.

I created the Custom Permission, created a Permission Set, enabled the Custom Permission in the Permission Set, and assigned the Permission Set to a user. I'm then using this code to check whether the user exporting the report has the correct Custom Permission when they attempt to export a report.

// check if user has Export_Reports custom permission
        @Testvisible
        Boolean hasExportPermissions = FeatureManagement.checkPermission('Export_Reports');
        System.debug(LoggingLevel.INFO, '>>> hasExportPermissions: ' + hasExportPermissions); 

However, I've tried exports with several different users, some with and some without the permission set that has the Custom Permission enabled, and this System.debug always returns false.

The full code of the class is below:

global class BlockLargeDataExportEventConditionPERM implements TxnSecurity.EventCondition {
    public boolean evaluate(SObject event) {
        switch on event{
            when ReportEvent reportEvent {
                return evaluate(reportEvent);
            }
            when null {
                // Don't take policy action when event is null
                return false;
            }
            when else{
                // Don't take policy action when event is not handled
                return false;
            }
        }
    }
    
    
    /**
     * Handle evaluating ReportEvent
     */
    @Testvisible
    private boolean evaluate(ReportEvent reportEvent){
        // get profile
        Profile profile = [SELECT Name FROM Profile WHERE Id IN
                            (SELECT profileId FROM User WHERE Id = :reportEvent.UserId)];
        System.debug(LoggingLevel.INFO, '>>> profile' + profile);
        
        // check if user has Export_Reports custom permission
        @Testvisible
        Boolean hasExportPermissions = FeatureManagement.checkPermission('Export_Reports');
        System.debug(LoggingLevel.INFO, '>>> hasExportPermissions: ' + hasExportPermissions); 
        
        // Take policy action only if the user profile is not 'System Administrator' 
        // AND user does not have 'Export_Reports' custom permission 
        // AND RowsProcessed greater than 250.
        if (!profile.Name.contains('System Administrator')
            && !hasExportpermissions
            && reportEvent.Operation.equals ('ReportExported')
            && reportEvent.RowsProcessed > 250) {
            return true;
        }
        return false;
    }
}

I can't figure out why it's not working, and not sure where to even begin debugging this. I have tried deleting and recreating the Custom Permission and re-enabling it on the Permission Set, I have verified that the user attempting the export has the Permission Set Assignment, but `hasExportPermissions' is still returning false.

Any ideas about how else I might troubleshoot this?

2
  • FeatureManagement.checkPermissions runs in the context of the running user - which as you noted in a previous question, is Automated Process user - you'll need to query to determine this for the reportEvent.userId
    – cropredy
    Commented Oct 12, 2022 at 23:22
  • @cropredy ahhh that makes sense. Do you know how I would do this? I understand how to reference the :reportEvent.userId variable but not how to tell FeatureManagement.checkPermission to check the permissions of that user instead. Is that even possible? Or do I need to revert back to the previous code that was checking which permission sets were assigned to user exporting the report?
    – rg_
    Commented Oct 13, 2022 at 15:36

1 Answer 1

3

Since you are doing this in the context of executing a Transaction Security Policy, the running user is Automated Process so using FeatureManagement.checkPermission applies to Automated Process, not reportEvent.userId.

Fortunately, there is simple SOQL to do this in this answer which I've adapted for you:

...
if (new Map<Id,User> (getUsersWithCustomPermission('Export_Reports')
     .containsKey(reportEvent.UserId) {
     .. is good to go
}
else {
     .. sorry, you can't do this operation
}

public static List<User> getUsersWithCustomPermission(String name)
{
    Set<Id> permissionSetIds = new Set<Id>();
    for (SetupEntityAccess access : [
        SELECT ParentId 
        FROM SetupEntityAccess 
        WHERE SetupEntityId IN (
            SELECT Id 
            FROM CustomPermission 
            WHERE DeveloperName = :name
        )
    ]) {
        permissionSetIds.add(access.ParentId);
    }
    return permissionSetIds.isEmpty() ? new List<User>() : [
        SELECT Username FROM User WHERE Id IN (
            SELECT AssigneeId FROM PermissionSetAssignment
            WHERE PermissionSetId IN :permissionSetIds
        )
    ];
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .