Implement group-based user retrieval for Gitlab based on additional configuration key 'restrictUsersToGroup'

Signed-off-by: Hghtwr <johannes.sonner@outlook.com>
This commit is contained in:
Hghtwr
2024-05-27 23:11:06 +02:00
committed by Johannes Sonner
parent 04c24e47e7
commit 115741c468
7 changed files with 64 additions and 10 deletions
+1
View File
@@ -94,6 +94,7 @@ typings/
# dotenv environment variables file
.env
.env.test
.envrc
# parcel-bundler cache (https://parceljs.org/)
.cache
+1 -1
View File
@@ -21,7 +21,7 @@ const backend = createBackend();
backend.add(import('@backstage/plugin-auth-backend'));
backend.add(import('./authModuleGithubProvider'));
backend.add(import('@backstage/plugin-auth-backend-module-guest-provider'));
backend.add(import('@backstage/plugin-catalog-backend-module-gitlab-org'));
backend.add(import('@backstage/plugin-app-backend/alpha'));
backend.add(import('@backstage/plugin-catalog-backend-module-unprocessed'));
backend.add(
@@ -23,6 +23,7 @@ import { LoggerService } from '@backstage/backend-plugin-api';
import {
GitLabDescendantGroupsResponse,
GitLabGroup,
GitlabGroupMember,
GitLabGroupMembersResponse,
GitLabProject,
GitLabUser,
@@ -114,8 +115,19 @@ export class GitLabClient {
return response;
}
async listGroupMembers(
groupPath: string,
options?: CommonListOptions,
): Promise<PagedResponse<GitLabUser>> {
return this.pagedRequest(
`/groups/${encodeURIComponent(groupPath)}/members/all`,
options,
);
}
async listUsers(
options?: UserListOptions,
global?: boolean,
): Promise<PagedResponse<GitLabUser>> {
return this.pagedRequest(`/users?`, {
...options,
@@ -128,6 +140,14 @@ export class GitLabClient {
groupPath: string,
options?: CommonListOptions,
): Promise<PagedResponse<GitLabUser>> {
return this.listGroupMembers(groupPath, {
...options,
show_seat_info: true,
}).then(resp => {
resp.items = resp.items.filter(user => user.is_using_seat);
return resp;
});
/*
return this.pagedRequest(
`/groups/${encodeURIComponent(groupPath)}/members/all`,
{
@@ -138,6 +158,7 @@ export class GitLabClient {
resp.items = resp.items.filter(user => user.is_using_seat);
return resp;
});
*/
}
async listGroups(
@@ -60,6 +60,7 @@ export type GitLabUser = {
avatar_url: string;
groups?: GitLabGroup[];
group_saml_identity?: GitLabGroupSamlIdentity;
is_using_seat?: boolean; // Only available in responses from the group members endpoint
};
/**
@@ -149,6 +150,13 @@ export type GitlabProviderConfig = {
* Accepts only groups under the provided path (which will be stripped)
*/
group: string;
/**
* If true, the provider will only ingest users that are part of the configured group.
* Only valid for self-hosted GitLab instances.
*/
restrictUsersToGroup?: boolean;
/**
* ???
*/
@@ -356,7 +356,24 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider {
let groups;
let users;
if (this.gitLabClient.isSelfManaged()) {
// Doesn't matter if we are on SaaS or not, we can either get the users from the defined group or from the root group.
if (this.gitLabClient.isSelfManaged() && this.config.restrictUsersToGroup) {
groups = (await this.gitLabClient.listDescendantGroups(this.config.group))
.items;
users = paginated<GitLabUser>(
options =>
this.gitLabClient.listGroupMembers(this.config.group, options),
{
page: 1,
per_page: 100,
},
);
}
if (
this.gitLabClient.isSelfManaged() &&
!this.config.restrictUsersToGroup
) {
groups = paginated<GitLabGroup>(
options => this.gitLabClient.listGroups(options),
{
@@ -365,19 +382,19 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider {
all_available: true,
},
);
users = paginated<GitLabUser>(
options => this.gitLabClient.listUsers(options),
{
page: 1,
per_page: 100,
active: true,
},
{ page: 1, per_page: 100, active: true },
);
} else {
}
// For SaaS, the only difference is the root group
if (!this.gitLabClient.isSelfManaged()) {
groups = (await this.gitLabClient.listDescendantGroups(this.config.group))
.items;
const rootGroup = this.config.group.split('/')[0];
const rootGroup = this.config.restrictUsersToGroup
? this.config.group
: this.config.group.split('/')[0];
users = paginated<GitLabUser>(
options => this.gitLabClient.listSaaSUsers(rootGroup, options),
{
@@ -61,6 +61,7 @@ describe('config', () => {
allowInherited: false,
schedule: undefined,
skipForkedRepos: false,
restrictUsersToGroup: false,
}),
);
});
@@ -99,6 +100,7 @@ describe('config', () => {
allowInherited: false,
schedule: undefined,
skipForkedRepos: false,
restrictUsersToGroup: false,
}),
);
});
@@ -137,6 +139,7 @@ describe('config', () => {
orgEnabled: false,
allowInherited: false,
schedule: undefined,
restrictUsersToGroup: false,
skipForkedRepos: true,
}),
);
@@ -178,6 +181,7 @@ describe('config', () => {
orgEnabled: false,
allowInherited: false,
skipForkedRepos: false,
restrictUsersToGroup: false,
schedule: {
frequency: Duration.fromISO('PT30M'),
timeout: {
@@ -51,6 +51,8 @@ function readGitlabConfig(id: string, config: Config): GitlabProviderConfig {
const schedule = config.has('schedule')
? readTaskScheduleDefinitionFromConfig(config.getConfig('schedule'))
: undefined;
const restrictUsersToGroup =
config.getOptionalBoolean('restrictUsersToGroup') ?? false;
return {
id,
@@ -66,6 +68,7 @@ function readGitlabConfig(id: string, config: Config): GitlabProviderConfig {
orgEnabled,
allowInherited,
skipForkedRepos,
restrictUsersToGroup,
};
}