Setting access permissions with Auto Importer

When setting access permissions for users, it is best to do it in feed files from the company. The Auto Importer Processors create and update user accounts based on data from the company. You can include the access permissions in the data, and using the techniques described below, assign the permissions to the account. For a complete discussion of access permissions, see Roles, permissions, and capabilities.

There are two techniques for setting permissions with the importer:

  • Permission per role — Use this when there is a single permission in a single column, to be be assigned to a single role.

  • Permission list — Use this to set multiple permissions, to multiple roles, possibly based on unit groups or segments, or when some logic must be applied during the assignments.

Permission per role

When the incoming data feed includes a single permission for a single role in a column in the records, you can assign the permission directly with the import specification.

This specification sets permissions on the the role named "My Role". It takes the value of the "my_role_permissions" column and parses it as unit group identifiers.

<output-column-group pluginName="Account" recordUpdateMode="CREATE_AND_UPDATE">
  <output-column>
	<input-column heading="my_role_permissions" />
	<target-field fieldId="my_role_access" fieldName="My Role Access" requiredness="REQUIRED" type="ENUMERATED">
	  <unit-group-permission-field-parse-options rootIdentifier="All Individual Properties">
		<enumerated-field-parse-options mappingKey="IDENTIFIER"/>
	  </unit-group-permission-field-parse-options>
	</target-field>
  </output-column>
</output-column-group>

You can also do this for permissions by segments.

Permission list

Permission List is a special target field that allows the importer to set one or more permissions for the user. This is useful for companies and feeds that can have hundreds of role-permission and context-access combinations. When using the Permission List target, you have to include a set of parser options defined by a <unit-group-permission-field-parse-options> tag, and a <javascript-transformation> that uses the permission() function to create a permission entry in the records.

Here is a simple excerpt from an import specification that targets the Permission List (permission_list) field and assigns permissions and access to a role named "Admin". This importer gives the user access to the Addison unit group under the Admin role and Property Access permission context.

<output-column>
  <target-field fieldId="permission_list" fieldName="Permission List" requiredness="OPTIONAL" multiValuedMode="OVERWRITE" type="PERMISSION_LIST">
    <unit-group-permission-field-parse-options rootIdentifier="All Individual Properties" delimiter="|">
      <enumerated-field-parse-options mappingKey="IDENTIFIER" />
    </unit-group-permission-field-parse-options>
    <javascript-transform><![CDATA[
      permission({
        role: 'Admin',
        permissionContext: 'Property Access',
        access: 'Addison'
      });
      return permissions();
    ]]></javascript-transform>
  </target-field>
</output-column>
Note: When targeting Permission List, always include <unit-group-permission-field-parse-options>.

The permissions in the example above are assigned as literal values in the permission function. This means every user record that is imported gets the same values. More typically the feed file will include the values in other columns in the same record. To do that, preface the column name with 'record.', like this:

permission({
  role: record.role,
  permissionContext: record.permissionCtx,
  access: record.unitGroups
});
Tip: Use the hasContent() function to check if a record column is empty or not. See Examples, below, to demonstrate.

Permission function

The permission() function creates a permission entry that can be inserted into the Permission List target. It takes a set of arguments that define the access permissions for a role, and optionally for unit groups or segments for that role. It can also assign the role to user account record if the user does not already have the role.

permission({ 
    role: RoleName, 
    permissionContext: ContextName, 
    access: UnitGroup(s) or Segment(s),
    addRoleToUser: (true or ADD_ROLE_TO_USER_IF_MISSING) or (false or CHECK_USER_HAS_ROLE),
    surveyFieldId: fieldId
 })

For detailed information about the arguments, see Permission function arguments, below.

Compact form

The function accepts the argument names followed by a colon (:) then the value(s). Alternatively, you can also use the compact form which includes just the values.

permission({ RoleName, ContextName, UnitGroup(s) or Segment(s), Boolean, fieldId })
Important:

When using the compact form, include the arguments in the order shown above. You must specify the role, permissionContext, and access arguments, and you can skip the remaining ones if you are not using them. Use null for any arguments you are not setting; do not skip them.

permission(record.role, null, record.access);
permission(record.role, record.permissionCtx, record.access, null, 'a_field_id');

Literal values

The argument values can be literal values to assign to every record.

permission({
  role: 'Admin',
  permissionContext: 'Property Access',
  access: 'Addison'
});

Values from the record

More typically the feed file includes the values provided in other columns in the same record. To use those values, preface the column name(s) with 'record.', like this:

permission({
  role: record.role,
  permissionContext: record.permissionCtx,
  access: record.unitGroups
});

Multiple permission assignments

To define permissions for multiple fields, use multiple permission() calls:

permission({
  role: record.role,
  permissionContext: record.permissionCtx,
  access: '1|2|3|4',
  surveyFieldId: 'a_field_id'
});
permission({
  role: record.role,
  permissionContext: record.permissionCtx,
  access: '1|2|3|4',
  surveyFieldId: 'a_another_field_id'
});

Permission function arguments

These are the arguments for the permission() function. They must be specified in this order.

role
(required) Role to assign the permission(s) to.
permissionContext
(optional) Permission context name. If no permission context is specified the one defined for the company is used.
access
(required) One or more of either unit groups or segments (not both) for the role. When there are multiple values, separate them using the delimiter specified in the parse options. For example, to use a '|' character when assigning unit groups:
permission({
  role: 'Admin',
  permissionContext: 'Property Access',
  access: 'Addison|Charlotte'
});
The parse options are defined in the <unit-group-permission-field-parse-options> tag with the mappingKey and delimiter attributes.
<unit-group-permission-field-parse-options rootIdentifier="All Individual Properties" delimiter="|">
  <enumerated-field-parse-options mappingKey="IDENTIFIER" />
</unit-group-permission-field-parse-options>

When assigning access to segments, you must include surveyFieldId to identify the field that defines the segments, and identify the segments in the field based on the sequence number of the segments in the field. For example, if "a_field_id" is an enumerated field with eight segments (enumerated items in the field), provide access to the first four segments like this:

permission({
  role: record.role,
  permissionContext: record.permissionCtx,
  access: '1|2|3|4',
  surveyFieldId: 'a_field_id'
});
addRoleToUser

(optional) Whether or not to add the role to the user account if it isn't already assigned to the account:

  • false or CHECK_USER_HAS_ROLE (default) — discard the record.

  • true or ADD_ROLE_TO_USER_IF_MISSING — add the role to the user, then add the permission to the role.

For example, to add the role:

permission({
  role: record.role,
  permissionContext: record.permissionCtx,
  access: record.unitGroups,
  addRoleToUser: ADD_ROLE_TO_USER_IF_MISSING
});
surveyFieldId

(optional) The field ID to apply a segment permission to. See access, above, for details.

Multiple permissions per user

The real power of setting the Permission List is the ability to specify multiple permissions during import. Consider this example feed file that includes values for some roles, but not others:

userIdprimaryRolesecondaryRole1secondaryRole2secondaryRoleN
john.jonesCorporateAccount ManagerBrand ManagerAdmin

In this case you want to do assign permissions to the named roles, but skip the empty columns. To do that, use the recordValues() function to parse through the all the named columns and get a list of non-empty ones, like this:

var roles = recordValues('primaryRole','secondaryRole1','secondaryRole2',…,'secondaryRoleN',)

The roles variable will now contain the list of non empty values:

'Corporate,Account Manager,Brand Manager,Admin'

Next, set the permissions for each of the collected roles:

roles.forEach(function(role){
  permission({
    role: role,
    access: 'aUnitGroup'
  });
});

Here is the complete example:

<javascript-transform><![CDATA[
  var roles = recordValues('primaryRole','secondaryRole1','secondaryRole2',…,'secondaryRoleN',)
  roles.forEach(function(role){
    permission({
      role: role,
      access: 'aUnitGroup'
    });
  });
  return permissions();
]]></javascript-transform>

Another common situation is to have multiple roles and multiple accesses, like this:

userIdprimaryRolesecondaryRole1secondaryRole2secondaryRoleNprimaryRoleAccesssecondaryRoleAccess1secondaryRoleAccess2secondaryRoleAccessN
john.jonesCorporateAccount ManagerBrand ManagerAdminAddisonBostonChelseaDallas

In this example there are Role-Unit Group pairs to be used for creating the permissions. To do this, first create the role-access pairs, and then go through each one, get the values from the record, check that they are both not empty and then create the permission. Like this:

var pairs = [
  ['primaryRole','primaryRoleAccess']
  ['secondaryRole1','secondaryRoleAccess1'],
  ['secondaryRole2','secondaryRoleAccess2'],
  ['secondaryRoleN','secondaryRoleAccessN']
];
var ROLE = 0;
var ACCESS = 1;
pairs.forEach(function(pair) {
  var role = record[pair[ROLE]];
  var access = record[pair[ACCESS]];
  if (hasContent(role) && hasContent(access)) {
    permission({
      role: role,
      access: access
    });
  }
});
return permissions();

Overwrite vs Append import modes

When importing the Permission List field only supports OVERRIDE and APPEND modes; REMOVE is not supported. (The mode refers exclusively to the access part of the permission.)

For example, consider this existing record:

UserIdRoleAccess (User Group)
john.jonesCorporateaUnitGroup

When the feed adds a permission to the same role but for a different unit group named "anotherUnitGroup":

  • OVERWRITE mode results in this:

    UserIdRoleAccess (User Group)
    john.jonesCorporateanotherUnitGroup
  • APPEND mode ends up like this:

    UserIdRoleAccess (User Group)
    john.jonesCorporateaUnitGroup,anotherUnitGroup

Examples

These are examples of setting multiple roles, and both unit group and segment level permission for each user user.

Role permissions from feed file

This is a very common assignment that sets the access permission for three roles (corporateAdmin, corporate, and frontline). The feed file includes three columns of "role permissions". If the record has data in any of those columns, those permissions are added to the that user's account for the associated role. If the user does not already have the role, it is added to the account.

<javascript-transform><![CDATA[
// Get the input value permissions for each role
var corporateAdmin = record.CORPORATE_ADMIN_PERMISSIONS;
var corporate = record.CORPORATE_PERMISSIONS;
var frontline = record.FRONTLINE_PERMISSIONS;
 
// If the input value has content, then add the role with the associated permissions
if (hasContent(corporateAdmin)) {
  permission("Corporate Admin", null, corporateAdmin, ADD_ROLE_TO_USER_IF_MISSING);
}
 
if (hasContent(corporate)) {
  permission("Corporate", null, corporate, ADD_ROLE_TO_USER_IF_MISSING);
}
 
if (hasContent(frontline)) {
  permission("Frontline", null, frontline, ADD_ROLE_TO_USER_IF_MISSING);
}
 
return permissions();
]]></javascript-transform>

Using org hierarchy

In this unit group permission example, there is a requirement to use the role's org hierarchy when assigning the access. This is achieved using orgHierarchyForRole('roleName').

var level = record['level'];
var some_restriction = upper(record['SOME_restriction']);
var rolesArray = recordValues('primary_role', 'secondary_role_1','secondary_role_2',...,'secondary_role_9');
rolesArray.forEach(function(role) {
  var roleName = role + " (" + level + ")";
  permission(roleName,'Orion Business',orgHierarchyForRole(roleName),true);
  var segment = "4|6|9|5|3|7|8|1|2";
  if (some_restriction == "YES" || some_restriction == "Y") {
    segment = "4|6|9|5|3|7|8";
  }
  permission(roleName,'Orion Business', segment, CHECK_USER_HAS_ROLE,"e_b2b_orion_owningarea_segment");
}));
return permissions();