Make userFilter and userGroupMemberFilter mutually exclusive
Signed-off-by: Mustansar Anwar ul Samad <mustansar.samad@gmail.com>
This commit is contained in:
committed by
blam
parent
ff7c6cec1a
commit
76599b5429
@@ -55,15 +55,20 @@ catalog:
|
||||
# Optional filter for user, see Microsoft Graph API for the syntax
|
||||
# See https://docs.microsoft.com/en-us/graph/api/resources/user?view=graph-rest-1.0#properties
|
||||
# and for the syntax https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter
|
||||
# This and userGroupMemberFilter are mutually exclusive, only one can be specified
|
||||
userFilter: accountEnabled eq true and userType eq 'member'
|
||||
# Optional filter for users, use group membership to get users
|
||||
# This appends the users to the list of users retrieved via userFilter
|
||||
# Optional filter for users, use group membership to get users.
|
||||
# This and userFilter are mutually exclusive, only one can be specified
|
||||
userGroupMemberFilter: "displayName eq 'Backstage Users'"
|
||||
# Optional filter for group, see Microsoft Graph API for the syntax
|
||||
# See https://docs.microsoft.com/en-us/graph/api/resources/group?view=graph-rest-1.0#properties
|
||||
groupFilter: securityEnabled eq false and mailEnabled eq true and groupTypes/any(c:c+eq+'Unified')
|
||||
```
|
||||
|
||||
`userFilter` and `userGroupMemberFilter` are mutually exclusive, only one can be provided. If both are provided, an error will be thrown.
|
||||
|
||||
By default, all users are loaded. If you want to filter users based on their attributes, use `userFilter`. `userGroupMemberFilter` can be used if you want to load users based on their group membership.
|
||||
|
||||
5. Add a location that ingests from Microsoft Graph:
|
||||
|
||||
```yaml
|
||||
|
||||
@@ -19,6 +19,7 @@ import merge from 'lodash/merge';
|
||||
import { GroupMember, MicrosoftGraphClient } from './client';
|
||||
import {
|
||||
readMicrosoftGraphGroups,
|
||||
readMicrosoftGraphOrg,
|
||||
readMicrosoftGraphOrganization,
|
||||
readMicrosoftGraphUsers,
|
||||
readMicrosoftGraphUsersInGroups,
|
||||
@@ -537,4 +538,132 @@ describe('read microsoft graph', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('readMicrosoftGraphOrg', () => {
|
||||
async function* getExampleUsers() {
|
||||
yield {
|
||||
id: 'userid',
|
||||
displayName: 'User Name',
|
||||
mail: 'user.name@example.com',
|
||||
};
|
||||
}
|
||||
|
||||
async function* getExampleGroups() {
|
||||
yield {
|
||||
id: 'groupid',
|
||||
displayName: 'Group Name',
|
||||
description: 'Group Description',
|
||||
mail: 'group@example.com',
|
||||
};
|
||||
}
|
||||
|
||||
async function* getExampleGroupMembers(): AsyncIterable<GroupMember> {
|
||||
yield {
|
||||
'@odata.type': '#microsoft.graph.group',
|
||||
id: 'childgroupid',
|
||||
};
|
||||
yield {
|
||||
'@odata.type': '#microsoft.graph.user',
|
||||
id: 'userid',
|
||||
};
|
||||
}
|
||||
|
||||
it('should read all users if no filter provided', async () => {
|
||||
client.getOrganization.mockResolvedValue({
|
||||
id: 'tenantid',
|
||||
displayName: 'Organization Name',
|
||||
});
|
||||
|
||||
client.getUsers.mockImplementation(getExampleUsers);
|
||||
client.getUserPhotoWithSizeLimit.mockResolvedValue(
|
||||
'data:image/jpeg;base64,...',
|
||||
);
|
||||
|
||||
client.getGroups.mockImplementation(getExampleGroups);
|
||||
client.getGroupMembers.mockImplementation(getExampleGroupMembers);
|
||||
client.getGroupPhotoWithSizeLimit.mockResolvedValue(
|
||||
'data:image/jpeg;base64,...',
|
||||
);
|
||||
|
||||
await readMicrosoftGraphOrg(client, 'tenantid', {
|
||||
logger: getVoidLogger(),
|
||||
groupFilter: 'securityEnabled eq false',
|
||||
});
|
||||
|
||||
expect(client.getUsers).toBeCalledTimes(1);
|
||||
expect(client.getUsers).toBeCalledWith({
|
||||
filter: undefined,
|
||||
});
|
||||
expect(client.getGroups).toBeCalledTimes(1);
|
||||
expect(client.getGroups).toBeCalledWith({
|
||||
filter: 'securityEnabled eq false',
|
||||
});
|
||||
});
|
||||
|
||||
it('should read users using userFilter', async () => {
|
||||
client.getOrganization.mockResolvedValue({
|
||||
id: 'tenantid',
|
||||
displayName: 'Organization Name',
|
||||
});
|
||||
|
||||
client.getUsers.mockImplementation(getExampleUsers);
|
||||
client.getUserPhotoWithSizeLimit.mockResolvedValue(
|
||||
'data:image/jpeg;base64,...',
|
||||
);
|
||||
|
||||
client.getGroups.mockImplementation(getExampleGroups);
|
||||
client.getGroupMembers.mockImplementation(getExampleGroupMembers);
|
||||
client.getGroupPhotoWithSizeLimit.mockResolvedValue(
|
||||
'data:image/jpeg;base64,...',
|
||||
);
|
||||
|
||||
await readMicrosoftGraphOrg(client, 'tenantid', {
|
||||
logger: getVoidLogger(),
|
||||
userFilter: 'accountEnabled eq true',
|
||||
groupFilter: 'securityEnabled eq false',
|
||||
});
|
||||
|
||||
expect(client.getUsers).toBeCalledTimes(1);
|
||||
expect(client.getUsers).toBeCalledWith({
|
||||
filter: 'accountEnabled eq true',
|
||||
});
|
||||
expect(client.getGroups).toBeCalledTimes(1);
|
||||
expect(client.getGroups).toBeCalledWith({
|
||||
filter: 'securityEnabled eq false',
|
||||
});
|
||||
});
|
||||
|
||||
it('should read users using userGroupMemberFilter', async () => {
|
||||
client.getOrganization.mockResolvedValue({
|
||||
id: 'tenantid',
|
||||
displayName: 'Organization Name',
|
||||
});
|
||||
|
||||
client.getUsers.mockImplementation(getExampleUsers);
|
||||
client.getUserPhotoWithSizeLimit.mockResolvedValue(
|
||||
'data:image/jpeg;base64,...',
|
||||
);
|
||||
|
||||
client.getGroups.mockImplementation(getExampleGroups);
|
||||
client.getGroupMembers.mockImplementation(getExampleGroupMembers);
|
||||
client.getGroupPhotoWithSizeLimit.mockResolvedValue(
|
||||
'data:image/jpeg;base64,...',
|
||||
);
|
||||
|
||||
await readMicrosoftGraphOrg(client, 'tenantid', {
|
||||
logger: getVoidLogger(),
|
||||
userGroupMemberFilter: 'name eq backstage-group',
|
||||
groupFilter: 'securityEnabled eq false',
|
||||
});
|
||||
|
||||
expect(client.getUsers).toBeCalledTimes(0);
|
||||
expect(client.getGroups).toBeCalledTimes(2);
|
||||
expect(client.getGroups).toBeCalledWith({
|
||||
filter: 'name eq backstage-group',
|
||||
});
|
||||
expect(client.getGroups).toBeCalledWith({
|
||||
filter: 'securityEnabled eq false',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -137,10 +137,6 @@ export async function readMicrosoftGraphUsersInGroups(
|
||||
}> {
|
||||
const users: UserEntity[] = [];
|
||||
|
||||
if (!options.userGroupMemberFilter) {
|
||||
return { users };
|
||||
}
|
||||
|
||||
const limiter = limiterFactory(10);
|
||||
|
||||
const transformer = options?.transformer ?? defaultUserTransformer;
|
||||
@@ -161,9 +157,7 @@ export async function readMicrosoftGraphUsersInGroups(
|
||||
}
|
||||
|
||||
if (member['@odata.type'] === '#microsoft.graph.user') {
|
||||
if (!groupMemberUsers.has(member.id)) {
|
||||
groupMemberUsers.add(member.id);
|
||||
}
|
||||
groupMemberUsers.add(member.id);
|
||||
}
|
||||
}
|
||||
}),
|
||||
@@ -484,23 +478,26 @@ export async function readMicrosoftGraphOrg(
|
||||
logger: Logger;
|
||||
},
|
||||
): Promise<{ users: UserEntity[]; groups: GroupEntity[] }> {
|
||||
const { users: usersInGroups } = await readMicrosoftGraphUsersInGroups(
|
||||
client,
|
||||
{
|
||||
userGroupMemberFilter: options.userGroupMemberFilter,
|
||||
const users: UserEntity[] = [];
|
||||
|
||||
if (options.userGroupMemberFilter) {
|
||||
const { users: usersInGroups } = await readMicrosoftGraphUsersInGroups(
|
||||
client,
|
||||
{
|
||||
userGroupMemberFilter: options.userGroupMemberFilter,
|
||||
transformer: options.userTransformer,
|
||||
logger: options.logger,
|
||||
},
|
||||
);
|
||||
users.push(...usersInGroups);
|
||||
} else {
|
||||
const { users: usersWithFilter } = await readMicrosoftGraphUsers(client, {
|
||||
userFilter: options.userFilter,
|
||||
transformer: options.userTransformer,
|
||||
logger: options.logger,
|
||||
},
|
||||
);
|
||||
|
||||
const { users: usersWithFilter } = await readMicrosoftGraphUsers(client, {
|
||||
userFilter: options.userFilter,
|
||||
transformer: options.userTransformer,
|
||||
logger: options.logger,
|
||||
});
|
||||
|
||||
const users: UserEntity[] = usersWithFilter.concat(usersInGroups);
|
||||
|
||||
});
|
||||
users.push(...usersWithFilter);
|
||||
}
|
||||
const { groups, rootGroup, groupMember, groupMemberOf } =
|
||||
await readMicrosoftGraphGroups(client, tenantId, {
|
||||
groupFilter: options?.groupFilter,
|
||||
|
||||
+6
@@ -90,6 +90,12 @@ export class MicrosoftGraphOrgReaderProcessor implements CatalogProcessor {
|
||||
);
|
||||
}
|
||||
|
||||
if (provider.userFilter && provider.userGroupMemberFilter) {
|
||||
throw new Error(
|
||||
`userFilter and userGroupMemberFilter are mutually exclusive, only one can be specified.`,
|
||||
);
|
||||
}
|
||||
|
||||
// Read out all of the raw data
|
||||
const startTimestamp = Date.now();
|
||||
this.logger.info('Reading Microsoft Graph users and groups');
|
||||
|
||||
Reference in New Issue
Block a user