HowTo:Use a Data Policy to Mask Outgoing Data

From LongJump Support Wiki
Revision as of 22:05, 4 June 2013 by imported>Aeric
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Warn.png

DEPRECATED: The events this functionality depends on have been deprecated because, when used injudiciously, they impose a heavy system load. This material is retained for legacy applications only.

For:   Designers
Level: Advanced
Time: 15 minutes

See more:
    ◾ HowTo Guides


This data policy action is built for the Sample Order Processing System. It is designed to be run on the Orders object, which has a field named credit_card_number.

The goal is to mask the customer's credit number, so that only the last 4 digits are displayed on screen. To do that, when the data policy is created in the GUI, the following triggers are chosen:

  • On View - When a record is retrieved by the GUI or by an API.
  • List View - When a search has generated a list of records that will be displayed in a grid in the GUI, or returned to a program as a response to an API call.
Note:
For the List View trigger, the policy_action constant is "on_search" (CONSTANTS.POLICY.ACTION.ON_SEARCH). For the On View trigger, it is "on_view" (CONSTANTS.POLICY.ACTION.ON_VIEW).

The code checks to see which event triggered the action, and does slightly different things in each case to mask the credit card data.

To set up the data policy:

  1. Create a data policy:
    • Activation Trigger: Action Based
    • Activation Sequence: After Triggering Actions
    • Triggering Criteria: On View and List View
  2. Add Action: Execute Java Method
  3. Select the mask_ccn() method in the OrderPolicies class shown below.
package com.platform.demo.pgms;

import java.util.*;
import java.util.Map.Entry;

import com.platform.api.*;

/**
 * Define data policy actions for Order objects. Remember: Multiple actions can
 * be executed as part of a data policy, so you don't need to do too much in
 * any one action.
 */
public class OrderPolicies
{
    // An object-specfic identifier for a field we're interested in. 
    // In this case: The credit card number field.
    String ccn_field = "credit_card_number";     // Field name, from the GUI
    
    static final String SEARCH_RESULTS = CONSTANTS.SEARCH.SEARCH_RESULTS;
    static final String RECORD_RESULT  = CONSTANTS.RECORD.RESULT;
        
    /** 
     * Mask the credit card number, showing only the last 4 digits.
     * Called when retrieving order information.
     */
    public void mask_ccn(Parameters requestParams) 
    {
        //Functions.debug("In mask_cnn");
        if ("on_search".equals(requestParams.get("policy_action"))) {
            // The policy is being executed as a result of search (list display)
            // A list of search results (displayed records) are in the parameter
            // map. Each record to be displayed is in that list. Modifying the
            // record data changes the values displayed for that record.
 
            //Functions.debug("Masking CCN in a List");
            ArrayList<HashMap> recordList = 
               (ArrayList) requestParams.getObject(SEARCH_RESULTS);
            if (recordList != null && recordList.size() > 0) {
                // each element in the array list is a map that contains the
                // field requested in search result
                for (HashMap record : recordList) {
                    mask_ccn(record);
                }
            }
        }

        if ("on_view".equals(requestParams.get("policy_action"))) {
            // The policy is being executed as a result of view (record view)
            // The parameter map contains record values.
            // Modifying the record changes the values returned.
            
            //Functions.debug("Masking CCN in a Record");
            HashMap record = (HashMap) requestParams.getObject(RECORD_RESULT);
            mask_ccn(record);
        }
    }
    
    /**
     * The workhorse method. Replace the SS# data in the record with 
     * a masked-out version.
     */
    public void mask_ccn(HashMap record) 
    {
       if (record.get(ccn_field) == null) {
           // A given records-list view might not include the credit card
           // number field. In that case, there is nothing to mask.
           return;
       }
       String ccn = (String) record.get(ccn_field);
        if (ccn != null && ccn.length() == 16) {
            //Functions.debug("Masking. ccn="+ccn);
            //Format is xxxxNNNNyyyyMMMM
            String subpart = ccn.substring(12);
            record.put(ccn_field, "xxxxxxxxxxxx" + subpart);
            
            //To mask a social security number:
            //  // Format is xxx-xxx-xxxx.
            //  String subpart = ssn.substring(7);
            //  record.put(ssn_field, "xxx-xx-" + subpart);
        }
        else {
            Functions.debug("Invalid credit crd#: "+ccn);
            // To ensure this never happens, run a data policy on add and 
            // update to check the format and throw an exception to abort
            // the transaction. (In future, it may be possible to invoke a
            // class method for validation, the same as for a data policy.)
            record.put(ccn_field, "Invalid credit card# format: " + ccn);                
        }        
    }
    //...
}

Notepad.png

Note: Selecting List View in the GUI causes a parameters object to be delivered to the method that contains the keyword SEARCH_RESULTS. That keyword applies to records returned in API-based searches, as well as those that were initiated from the GUI to generate a list view.

Learn More: