Merge pull request #24524 from grantila/grantila/azure-ad-disabling-user-photos
Azure AD disabling user photos (fix) and handle huge organizations
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend-module-msgraph': patch
|
||||
---
|
||||
|
||||
Fixed disabling of user photo fetching. Previously, the config value wasn't propagated properly, so user photos was still being fetched despite disabled by config.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend-module-msgraph': patch
|
||||
---
|
||||
|
||||
Handle fetching huge amounts of users from Azure without crashing
|
||||
@@ -146,6 +146,18 @@ microsoftGraphOrg:
|
||||
search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")'
|
||||
```
|
||||
|
||||
### User photos
|
||||
|
||||
By default, the photos of users will be fetched and added to each user entity. For huge organizations this may be unfeasible, as it will take a _very_ long time, and can be disabled by setting `loadPhotos` to `false`:
|
||||
|
||||
```yaml
|
||||
microsoftGraphOrg:
|
||||
providerId:
|
||||
user:
|
||||
filter: ...
|
||||
loadPhotos: false
|
||||
```
|
||||
|
||||
## Customizing Transformation
|
||||
|
||||
Ingested entities can be customized by providing custom transformers.
|
||||
|
||||
@@ -54,6 +54,8 @@ catalog:
|
||||
# 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
|
||||
filter: accountEnabled eq true and userType eq 'member'
|
||||
# Set to false to not load user photos.
|
||||
loadPhotos: true
|
||||
# See https://docs.microsoft.com/en-us/graph/api/resources/schemaextension?view=graph-rest-1.0
|
||||
select: ['id', 'displayName', 'description']
|
||||
# Optional configuration block
|
||||
|
||||
@@ -955,6 +955,43 @@ describe('read microsoft graph', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should ignore loading photos if loadPhotos is false', async () => {
|
||||
client.getOrganization.mockResolvedValue(getExampleOrg());
|
||||
|
||||
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(),
|
||||
loadUserPhotos: false,
|
||||
});
|
||||
|
||||
expect(client.getUserPhotoWithSizeLimit).toHaveBeenCalledTimes(0);
|
||||
|
||||
expect(client.getUsers).toHaveBeenCalledTimes(1);
|
||||
expect(client.getUsers).toHaveBeenCalledWith(
|
||||
{
|
||||
top: 999,
|
||||
},
|
||||
undefined,
|
||||
);
|
||||
expect(client.getGroups).toHaveBeenCalledTimes(1);
|
||||
expect(client.getGroups).toHaveBeenCalledWith(
|
||||
{
|
||||
top: 999,
|
||||
},
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
||||
it('should read users with userSelect', async () => {
|
||||
client.getOrganization.mockResolvedValue({
|
||||
id: 'tenantid',
|
||||
@@ -1027,5 +1064,51 @@ describe('read microsoft graph', () => {
|
||||
);
|
||||
expect(client.getUserPhotoWithSizeLimit).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should handle loading huge amounts of users', async () => {
|
||||
client.getOrganization.mockResolvedValue(getExampleOrg());
|
||||
|
||||
const userCount = 200_000;
|
||||
|
||||
async function* getHugeAmountsOfExampleUsers() {
|
||||
for (let i = 0; i < userCount; ++i) {
|
||||
yield {
|
||||
id: `userid-${i}`,
|
||||
displayName: 'User Name',
|
||||
mail: 'user.name@example.com',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
client.getUsers.mockImplementation(getHugeAmountsOfExampleUsers);
|
||||
|
||||
client.getGroups.mockImplementation(getExampleGroups);
|
||||
client.getGroupMembers.mockImplementation(getExampleGroupMembers);
|
||||
client.getGroupPhotoWithSizeLimit.mockResolvedValue(
|
||||
'data:image/jpeg;base64,...',
|
||||
);
|
||||
|
||||
const { users } = await readMicrosoftGraphOrg(client, 'tenantid', {
|
||||
logger: getVoidLogger(),
|
||||
loadUserPhotos: false,
|
||||
});
|
||||
|
||||
expect(users.length).toBe(userCount);
|
||||
|
||||
expect(client.getUsers).toHaveBeenCalledTimes(1);
|
||||
expect(client.getUsers).toHaveBeenCalledWith(
|
||||
{
|
||||
top: 999,
|
||||
},
|
||||
undefined,
|
||||
);
|
||||
expect(client.getGroups).toHaveBeenCalledTimes(1);
|
||||
expect(client.getGroups).toHaveBeenCalledWith(
|
||||
{
|
||||
top: 999,
|
||||
},
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -384,7 +384,7 @@ export async function readMicrosoftGraphOrg(
|
||||
logger: LoggerService;
|
||||
},
|
||||
): Promise<{ users: UserEntity[]; groups: GroupEntity[] }> {
|
||||
const users: UserEntity[] = [];
|
||||
let users: UserEntity[] = [];
|
||||
|
||||
if (options.userGroupMemberFilter || options.userGroupMemberSearch) {
|
||||
const { users: usersInGroups } = await readMicrosoftGraphUsersInGroups(
|
||||
@@ -401,7 +401,7 @@ export async function readMicrosoftGraphOrg(
|
||||
logger: options.logger,
|
||||
},
|
||||
);
|
||||
users.push(...usersInGroups);
|
||||
users = usersInGroups;
|
||||
} else {
|
||||
const { users: usersWithFilter } = await readMicrosoftGraphUsers(client, {
|
||||
queryMode: options.queryMode,
|
||||
@@ -412,7 +412,7 @@ export async function readMicrosoftGraphOrg(
|
||||
transformer: options.userTransformer,
|
||||
logger: options.logger,
|
||||
});
|
||||
users.push(...usersWithFilter);
|
||||
users = usersWithFilter;
|
||||
}
|
||||
const { groups, rootGroup, groupMember, groupMemberOf } =
|
||||
await readMicrosoftGraphGroups(client, tenantId, {
|
||||
|
||||
+1
@@ -310,6 +310,7 @@ export class MicrosoftGraphOrgEntityProvider implements EntityProvider {
|
||||
userExpand: provider.userExpand,
|
||||
userFilter: provider.userFilter,
|
||||
userSelect: provider.userSelect,
|
||||
loadUserPhotos: provider.loadUserPhotos,
|
||||
userGroupMemberFilter: provider.userGroupMemberFilter,
|
||||
userGroupMemberSearch: provider.userGroupMemberSearch,
|
||||
groupExpand: provider.groupExpand,
|
||||
|
||||
+1
@@ -112,6 +112,7 @@ export class MicrosoftGraphOrgReaderProcessor implements CatalogProcessor {
|
||||
{
|
||||
userExpand: provider.userExpand,
|
||||
userFilter: provider.userFilter,
|
||||
loadUserPhotos: provider.loadUserPhotos,
|
||||
userGroupMemberFilter: provider.userGroupMemberFilter,
|
||||
userGroupMemberSearch: provider.userGroupMemberSearch,
|
||||
groupExpand: provider.groupExpand,
|
||||
|
||||
Reference in New Issue
Block a user