Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class GroupProcessing extends ObjectProcessing {

private final static String GROUPS = "/groups";
private final static String USERS = "/users";
private final static String ROLE_ASSIGNMENT = "/roleManagement/directory/roleAssignments";

private static final String ATTR_ALLOWEXTERNALSENDERS = "allowExternalSenders";
private static final String ATTR_AUTOSUBSCRIBENEWMEMBERS = "autoSubscribeNewMembers";
Expand All @@ -47,10 +48,13 @@ public class GroupProcessing extends ObjectProcessing {
private static final String ATTR_ISASSIGNABLETOROLE = "isAssignableToRole";
private static final String ATTR_MEMBERS = "members";
private static final String ATTR_OWNERS = "owners";
private static final String ATTR_MEMBER_OF_ROLE = "memberOfRole";


protected static final Set<String> EXCLUDE_ATTRS_OF_GROUP = Stream.of(
ATTR_MEMBERS,
ATTR_OWNERS
ATTR_OWNERS,
ATTR_MEMBER_OF_ROLE
).collect(Collectors.toSet());

protected static final Set<String> UPDATABLE_MULTIPLE_VALUE_ATTRS_OF_GROUP = Stream.of(
Expand Down Expand Up @@ -192,6 +196,12 @@ protected ObjectClassInfo objectClassInfo() {
attrOwners.setType(String.class).setCreateable(true).setUpdateable(true).setReadable(true).setMultiValued(true).setReturnedByDefault(false);
groupObjClassBuilder.addAttributeInfo(attrOwners.build());

AttributeInfoBuilder attrRoleMembers = new AttributeInfoBuilder(ATTR_MEMBER_OF_ROLE);
attrRoleMembers.setRequired(false).setType(String.class).setMultiValued(true)
.setCreateable(false).setUpdateable(false).setReadable(true)
.setReturnedByDefault(false);
groupObjClassBuilder.addAttributeInfo(attrRoleMembers.build());

return groupObjClassBuilder.build();
}

Expand Down Expand Up @@ -589,6 +599,24 @@ private JSONObject saturateGroupOwnership(JSONObject group) {
return group;
}

/**
* Query a group's roles, add them to the group's JSON attributes (multivalue)
*
* @param group Group to query for (JSON object resulting from previous API call)
* @return Original JSON, enriched with roles information
*/
private JSONObject saturateGroupRoleMembership(JSONObject group) {
final GraphEndpoint endpoint = getGraphEndpoint();
final String uid = group.getString(ATTR_ID);

LOG.info("[GET] - saturateRoleMembership(), for group with UID: {0}", uid);

final String customQuery = "$expand=roleDefinition&$select=roleDefinitionId&$filter=principalId eq '" + uid + "'";
final JSONArray groupMembership = endpoint.executeListRequest(ROLE_ASSIGNMENT, customQuery, null, true);
group.put(ATTR_MEMBER_OF_ROLE, getJSONArray(groupMembership, "roleDefinitionId"));
return group;
}

/**
* Adds group accounts to the group JSON Object. Decides upon members or owners based on @param isMembers.
* @param group Original group object to extend with owners or members account ids
Expand Down Expand Up @@ -628,10 +656,15 @@ protected boolean handleJSONObject(OperationOptions options, JSONObject group, R
group = saturateGroupOwnership(group);
}

if (shouldSaturate(options, ObjectClass.GROUP_NAME, ATTR_MEMBER_OF_ROLE)) {
group = saturateGroupRoleMembership(group);
}

ConnectorObjectBuilder builder = convertGroupJSONObjectToConnectorObject(group);

incompleteIfNecessary(options, ObjectClass.GROUP_NAME, ATTR_MEMBERS, builder);
incompleteIfNecessary(options, ObjectClass.GROUP_NAME, ATTR_OWNERS, builder);
incompleteIfNecessary(options, ObjectClass.GROUP_NAME, ATTR_MEMBER_OF_ROLE, builder);

final ConnectorObject connectorObject = builder.build();
LOG.ok("handleJSONObject, group: {0}, \n\tconnectorObject: {1}", group.get("id"), connectorObject);
Expand Down Expand Up @@ -671,6 +704,7 @@ private ConnectorObjectBuilder convertGroupJSONObjectToConnectorObject(JSONObjec

getMultiIfExists(group, ATTR_MEMBERS, builder);
getMultiIfExists(group, ATTR_OWNERS, builder);
getMultiIfExists(group, ATTR_MEMBER_OF_ROLE, builder);

return builder;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ public interface ObjectConstants {
String ATTR_UNSEENCOUNT = "unseenCount";
String ATTR_VISIBILITY = "visibility";
String ATTR_OWNERS = "owners";
String ATTR_MEMBER_OF_ROLE = "memberOfRole";

// Role

Expand All @@ -128,5 +129,4 @@ public interface ObjectConstants {
String ATTR_INHERIT_PERMISSIONS_FROM_ODATA_CONTEXT = "inheritsPermissionsFrom@odata.context";
String ATTR_INHERIT_PERMISSIONS_FROM = "inheritsPermissionsFrom";
String ATTR_INHERIT_PERMISSIONS_FROM_ALL = ATTR_INHERIT_PERMISSIONS_FROM + "." + ATTR_ID;

}
Original file line number Diff line number Diff line change
Expand Up @@ -379,4 +379,39 @@ public void CreateSecurityGroupTest() {
connector.delete(objectClassGroup, groupUid, options);
connector.dispose();
}

@Test(priority = 31)
public void GetGroupRoleMembershipTest() {
MSGraphConnector connector = new MSGraphConnector();
MSGraphConfiguration conf = getConfiguration();

Map<String, Object> operationOptions = new HashMap<>();
operationOptions.put("ALLOW_PARTIAL_ATTRIBUTE_VALUES", false);
operationOptions.put(OperationOptions.OP_ATTRIBUTES_TO_GET, new String[]{ ATTR_MEMBER_OF_ROLE });
operationOptions.put(OperationOptions.OP_PAGED_RESULTS_OFFSET, 1);
operationOptions.put(OperationOptions.OP_PAGE_SIZE, 100);
OperationOptions options = new OperationOptions(operationOptions);

final ArrayList<ConnectorObject> resultsGroup = new ArrayList<>();
SearchResultsHandler handlerGroup = new SearchResultsHandler() {

@Override
public boolean handle(ConnectorObject connectorObject) {
resultsGroup.add(connectorObject);
return true;
}

@Override
public void handleResult(SearchResult result) {
}
};
connector.init(conf);
connector.executeQuery(ObjectClass.GROUP, null, handlerGroup, options);

msGraphConnector.dispose();

if (resultsGroup.size() < 100) {
throw new InvalidAttributeValueException("Non exist 100 groups.");
}
}
}