From the page you cited:
When Salesforce turns on profile-based rollout of Chatter for your organization, the Enable Chatter permission is added to all of your existing user profiles and permissions sets. This permission is automatically enabled for all standard profiles. It is also automatically enabled for all custom profiles, if any of the following user-level permissions were already enabled, either manually or as part of a license:
- “Create and Own New Chatter Groups” (ChatterOwnGroups)
- “Create and Share Links to Chatter Files” (ChatterFileLink)
- “Invite Customers To Chatter” (ChatterInviteExternalUsers)
- “Manage Chatter Messages” (ManageChatterMessages)
- “Moderate Chatter” (ModerateChatter)
- “Moderate Chatter Feeds” (ModerateNetworkFeeds)
- “Use Case Feed” (ViewCaseInteraction)
- “View All Data” (ViewAllData)
ChatterEnabledforUser
will be enabled by Salesforce in the Profile of ALL Users who have any of the permissions enabled on the list above for them as part of a Standard or Custom Profile. As such, the additional permissions you're querying for are not necessary if you're trying to establish a baseline of who can access Chatter. This permission is added to ALL of your Standard profiles, Custom Profiles that contained one of the above permissions, and ALL permission sets when Salesforce turns on Chatter for you.
I'd think you'd want to know whether Chatter is enabled through a Profile as opposed to sharing through a permissionset. Consequently, I would add ProfileId
to your query. Since it sounds as though you're a profile based Org as opposed to using groups and permission sets, you could create another query on User
to select Id, Name where ProfileId in: list of ProfileId's returned in permission query
. You could also try building your query starting from User rather than from permissionsets. That might make it easier to get a single result based on profiles along with any permissionsets you may have.
In short: I managed to do this in Apex by using apex-mdapi AFTER I updated the code to support flowAccesses. - here's the github commit with changes needed to support it. This is the only way I can see to do this through Apex as you need to hit the Metadata API.
Very Long Version
I didn't see anything within SOQL or Tooling API that can be used. It seems like it's only available with the Metadata API based on the simple fact that you can retrieve this information with the following package.xml
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>test</members>
<name>PermissionSet</name>
</types>
<version>47.0</version>
</Package>
This returns the following
<?xml version="1.0" encoding="UTF-8"?>
<PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata">
<flowAccesses>
<enabled>true</enabled>
<flow>Test_Flow_Name</flow>
</flowAccesses>
<hasActivationRequired>false</hasActivationRequired>
<label>test</label>
<license>Salesforce</license>
</PermissionSet>
That leaves you with trying to use Apex and the Metadata API. This isn't a supported type for what Salesforce provides access to through Apex. Likewise, I don't see any mention of flow access in the Metadata API Developer Guide which puzzled me. However, they do list the other naming conventions for other "access" types:
PermissionSetApplicationVisibility[]
PermissionSetApexClassAccess[]
PermissionSetCustomMetadtaTypeAccess[]
etc.
So now I looked towards apex-mdapi which does allow you to interact with apex/Metadata API
You can see the code/github here and this is a helpful answer with links to many questions concerning it. I had to make edits to it since it hasn't been updated since flowAccesses
was brought into play. I used customMetadataTypeAccess
(which is also relatively new) as a test since that one is at least documented in the developer guide.
You can see my changes in my forked repo and the latest commits contains all the changes needed for this in particular. Based on the naming convention in the developer guide (and testing that PermissionSetCustomMetadataTypeAccess[]
worked first), I used PermissionSetFlowAccess[]
and the example of the returned retrieve file to populate what the field names would be. You can see that the name of the flow is stored in <flow></flow>
So now, going off all that above...
Depending on when/where your code is executing, you'd probably first want to get a list of permission sets assigned to the user using SOQL. From this, you can see the following should do the trick
SELECT PermissionSet.Name FROM PermissionSetAssignment WHERE AssigneeId = 'User Name here'
Once you have a list of permission set names, you can call the Metadata API through the MetadataService
you modified above to simply get those permission sets returned and loop through them to get a list of the Flows they have access to.
public class testmetadata {
public static MetadataService.MetadataPort createService()
{
MetadataService.MetadataPort service = new MetadataService.MetadataPort();
service.SessionHeader = new MetadataService.SessionHeader_element();
service.SessionHeader.sessionId = UserInfo.getSessionId();
return service;
}
public static void testPerm()
{
//presumably you'd pass this list based on the SOQL query
String[] permissionSetNames = new String[] {'test', 'test2', 'test3'};
String message = '';
MetadataService.MetadataPort service = createService();
List<MetadataService.PermissionSet> perm = (List<MetadataService.PermissionSet>) service.readMetadata('PermissionSet', permissionSetNames).getRecords();
//loop through returned permission sets based on the names assigned to user
for(MetadataService.PermissionSet permSet : perm){
message = permSet.fullName + ' with access to the following flow(s): ';
//loop through flows that are enabled for access in each perm set to display name
for(MetadataService.PermissionSetFlowAccess singleFlow : permSet.flowAccesses){
message += singleFlow.flow + ', ';
}
System.debug(message);
}
}
}
What I tested (using only 3 different flows):
- Created 3 permission sets - test1, test2, test3
- Gave test1 access to one flow
- Gave test2 access to 2 flows
- Gave test3 access to 3 flows
See the debug log returned below:
Update: Just to show that the assumptions I made above for the naming convention at least are now corroborated by info in the Metadata API WSDL. You can see the naming for Profile and Permission Set.
Best Answer
Yes, you can manage it. Just you need to follow these step.
Permission sets or enhanced profile user interface—In the Find Settings... box, enter the name of the tab you want and select it from the list, then click Edit.
Original profile user interface—Click Edit, then scroll to the Tab Settings section.
Specify the tab settings. You need to specify the setting available there. Click on the hyperlink, you will get to know more about that.
Click Save.
Reference:- View and Edit Tab Settings in Permission Sets and Profiles