Use FMA Features for per-user licensing
- In salesforce, access is controlled through Permission sets.
- LMO org can assign how many feature-specific licenses are assigned using an FMA Integer parameter,
- Currently there is no standard way to limit license specific permission set assignments
here is the approach I would take to breeze this gap
- Create an Integer FMA parameter and permission set combination for each feature.
- Assign seats for Features in LMO using FMA parameter
- An apex class which will check if the logged-in user
- has permission set assigned
- Current users permission set assignment is among the first num_SeatsPermX permission set assignment
- When app code needs feature it calls
CurrentUser.hasAccess(new Feature('FeatureX', 'FeatureXPermissionSet'))
.
This will allow the LMO org to control how many users have access to a specific feature, Even if the subscriber tries to assign permission sets to users more than assigned seats any user who has been assigned permission set after the seats are filled will not have access to the feature
To improve performance we can leverage Platform Cache and store computed feature access in the cache.
Here is the sample code
public with sharing class CurrentUser {
public static Boolean hasAccess(Feature feature) {
Set<Id> assignedUsers = new Set<Id>();
for(PermissionSetAssignment permissionSetAssignment : [SELECT Id, AssigneeId
FROM PermissionSetAssignment
WHERE PermissionSetId = :feature.permissionSetId
ORDER By SystemModstamp
LIMIT :feature.seats]) {
assignedUsers.add(permissionSetAssignment.AssigneeId);
}
return assignedUsers.contains(UserInfo.getUserId());
}
}
public with sharing class Feature {
public Id permissionSetId { get; private set; }
public Integer seats { get; private set; }
public Feature(String featureName, String permissionSetName) {
permissionSetId = [SELECT Id FROM PermissionSet WHERE Name = :permissionSetName].Id;
seats = System.FeatureManagement.checkPackageIntegerValue(featureName);
}
}
if(!CurrentUser.hasAccess(new Feature('FeatureX', 'FeatureXPermissionSet'))) {
throw new FeatureAccessException('You do not have access to this feature');
}