Merge pull request #6961 from gt-yogan/usernamespace
Adds Optional Namespacing for Users in the GitHubMultiOrg
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
---
|
||||
|
||||
Adds optional namespacing for users in the GitHub Multi Org Plugin
|
||||
Vendored
+7
@@ -163,6 +163,13 @@ export interface Config {
|
||||
* Defaults to org name if omitted.
|
||||
*/
|
||||
groupNamespace?: string;
|
||||
|
||||
/**
|
||||
* The namespace of the users created from this org.
|
||||
*
|
||||
* Defaults to empty string if omitted.
|
||||
*/
|
||||
userNamespace?: string;
|
||||
}>;
|
||||
};
|
||||
|
||||
|
||||
@@ -111,6 +111,7 @@ export class GithubMultiOrgReaderProcessor implements CatalogProcessor {
|
||||
client,
|
||||
orgConfig.name,
|
||||
tokenType,
|
||||
orgConfig.userNamespace,
|
||||
);
|
||||
const { groups, groupMemberUsers } = await getOrganizationTeams(
|
||||
client,
|
||||
@@ -123,15 +124,18 @@ export class GithubMultiOrgReaderProcessor implements CatalogProcessor {
|
||||
`Read ${users.length} GitHub users and ${groups.length} GitHub teams from ${orgConfig.name} in ${duration} seconds`,
|
||||
);
|
||||
|
||||
let prefix: string = orgConfig.userNamespace ?? '';
|
||||
if (prefix.length > 0) prefix += '/';
|
||||
|
||||
users.forEach(u => {
|
||||
if (!allUsersMap.has(u.metadata.name)) {
|
||||
allUsersMap.set(u.metadata.name, u);
|
||||
if (!allUsersMap.has(prefix + u.metadata.name)) {
|
||||
allUsersMap.set(prefix + u.metadata.name, u);
|
||||
}
|
||||
});
|
||||
|
||||
for (const [groupName, userNames] of groupMemberUsers.entries()) {
|
||||
for (const userName of userNames) {
|
||||
const user = allUsersMap.get(userName);
|
||||
const user = allUsersMap.get(prefix + userName);
|
||||
if (user && !user.spec.memberOf.includes(groupName)) {
|
||||
user.spec.memberOf.push(groupName);
|
||||
}
|
||||
|
||||
@@ -78,32 +78,48 @@ describe('config', () => {
|
||||
});
|
||||
|
||||
describe('readGithubMultiOrgConfig', () => {
|
||||
function config(orgs: { name: string; groupNamespace?: string }[]) {
|
||||
function config(
|
||||
orgs: { name: string; groupNamespace?: string; userNamespace?: string }[],
|
||||
) {
|
||||
return new ConfigReader({ orgs });
|
||||
}
|
||||
|
||||
it('reads org configs', () => {
|
||||
const output = readGithubMultiOrgConfig(
|
||||
config([
|
||||
{ name: 'foo', groupNamespace: 'apple' },
|
||||
{ name: 'bar', groupNamespace: 'Orange' },
|
||||
{ name: 'foo', groupNamespace: 'apple', userNamespace: 'red' },
|
||||
{ name: 'bar', groupNamespace: 'Orange', userNamespace: 'blue' },
|
||||
]),
|
||||
);
|
||||
|
||||
expect(output).toEqual([
|
||||
{ name: 'foo', groupNamespace: 'apple' },
|
||||
{ name: 'bar', groupNamespace: 'orange' },
|
||||
{ name: 'foo', groupNamespace: 'apple', userNamespace: 'red' },
|
||||
{ name: 'bar', groupNamespace: 'orange', userNamespace: 'blue' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('defaults groupNamespace to org name if undefined', () => {
|
||||
const output = readGithubMultiOrgConfig(
|
||||
config([
|
||||
{ name: 'foo', userNamespace: 'red' },
|
||||
{ name: 'bar', userNamespace: 'blue' },
|
||||
]),
|
||||
);
|
||||
|
||||
expect(output).toEqual([
|
||||
{ name: 'foo', groupNamespace: 'foo', userNamespace: 'red' },
|
||||
{ name: 'bar', groupNamespace: 'bar', userNamespace: 'blue' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('defaults userNamespace to undefined if unspecified', () => {
|
||||
const output = readGithubMultiOrgConfig(
|
||||
config([{ name: 'foo' }, { name: 'bar' }]),
|
||||
);
|
||||
|
||||
expect(output).toEqual([
|
||||
{ name: 'foo', groupNamespace: 'foo' },
|
||||
{ name: 'bar', groupNamespace: 'bar' },
|
||||
{ name: 'foo', groupNamespace: 'foo', userNamespace: undefined },
|
||||
{ name: 'bar', groupNamespace: 'bar', userNamespace: undefined },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -95,6 +95,10 @@ export type GithubMultiOrgConfig = Array<{
|
||||
* The namespace of the group created for this org.
|
||||
*/
|
||||
groupNamespace: string;
|
||||
/**
|
||||
* The namespace of the users created for this org. If not specified defaults to undefined.
|
||||
*/
|
||||
userNamespace: string | undefined;
|
||||
}>;
|
||||
|
||||
export function readGithubMultiOrgConfig(config: Config): GithubMultiOrgConfig {
|
||||
@@ -104,5 +108,6 @@ export function readGithubMultiOrgConfig(config: Config): GithubMultiOrgConfig {
|
||||
groupNamespace: (
|
||||
c.getOptionalString('groupNamespace') ?? c.getString('name')
|
||||
).toLowerCase(),
|
||||
userNamespace: c.getOptionalString('userNamespace') ?? undefined,
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ export async function getOrganizationUsers(
|
||||
client: typeof graphql,
|
||||
org: string,
|
||||
tokenType: GithubCredentialType,
|
||||
userNamespace?: string,
|
||||
): Promise<{ users: UserEntity[] }> {
|
||||
const query = `
|
||||
query users($org: String!, $email: Boolean!, $cursor: String) {
|
||||
@@ -117,6 +118,7 @@ export async function getOrganizationUsers(
|
||||
},
|
||||
};
|
||||
|
||||
if (userNamespace) entity.metadata.namespace = userNamespace;
|
||||
if (user.bio) entity.metadata.description = user.bio;
|
||||
if (user.name) entity.spec.profile!.displayName = user.name;
|
||||
if (user.email) entity.spec.profile!.email = user.email;
|
||||
|
||||
Reference in New Issue
Block a user