feat(secret-sync): rework GitLab secret-sync to add group variables

This commit is contained in:
carlosmonastyrski
2025-06-24 18:01:32 -03:00
parent 43e0d400f9
commit d4bf8a33dc
20 changed files with 504 additions and 460 deletions
@@ -145,7 +145,7 @@ export const GitLabConnectionForm = ({ appConnection, onSubmit: formSubmit }: Pr
oauthUrl.searchParams.set("client_id", oauthClientId);
oauthUrl.searchParams.set(
"redirect_uri",
`${window.location.origin}/integrations/gitlab/oauth2/callback`
`${window.location.origin}/organization/app-connections/gitlab/oauth/callback`
);
oauthUrl.searchParams.set("response_type", "code");
oauthUrl.searchParams.set("state", state);
@@ -11,12 +11,14 @@ import {
AzureDevOpsConnectionMethod,
AzureKeyVaultConnectionMethod,
GitHubConnectionMethod,
GitlabConnectionMethod,
TAzureAppConfigurationConnection,
TAzureClientSecretsConnection,
TAzureDevOpsConnection,
TAzureKeyVaultConnection,
TGitHubConnection,
TGitHubRadarConnection,
TGitlabConnection,
useCreateAppConnection,
useUpdateAppConnection
} from "@app/hooks/api/appConnections";
@@ -25,6 +27,7 @@ import { AppConnection } from "@app/hooks/api/appConnections/enums";
type BaseFormData = {
returnUrl?: string;
connectionId?: string;
isUpdate?: boolean;
};
type GithubFormData = BaseFormData & Pick<TGitHubConnection, "name" | "method" | "description">;
@@ -32,6 +35,8 @@ type GithubFormData = BaseFormData & Pick<TGitHubConnection, "name" | "method" |
type GithubRadarFormData = BaseFormData &
Pick<TGitHubRadarConnection, "name" | "method" | "description">;
type GitlabFormData = BaseFormData & Pick<TGitlabConnection, "name" | "method" | "description">;
type AzureKeyVaultFormData = BaseFormData &
Pick<TAzureKeyVaultConnection, "name" | "method" | "description"> &
Pick<TAzureKeyVaultConnection["credentials"], "tenantId">;
@@ -60,6 +65,7 @@ type AzureDevOpsFormData = BaseFormData &
type FormDataMap = {
[AppConnection.GitHub]: GithubFormData & { app: AppConnection.GitHub };
[AppConnection.GitHubRadar]: GithubRadarFormData & { app: AppConnection.GitHubRadar };
[AppConnection.Gitlab]: GitlabFormData & { app: AppConnection.Gitlab };
[AppConnection.AzureKeyVault]: AzureKeyVaultFormData & { app: AppConnection.AzureKeyVault };
[AppConnection.AzureAppConfiguration]: AzureAppConfigurationFormData & {
app: AppConnection.AzureAppConfiguration;
@@ -75,6 +81,7 @@ type FormDataMap = {
const formDataStorageFieldMap: Partial<Record<AppConnection, string>> = {
[AppConnection.GitHub]: "githubConnectionFormData",
[AppConnection.GitHubRadar]: "githubRadarConnectionFormData",
[AppConnection.Gitlab]: "gitlabConnectionFormData",
[AppConnection.AzureKeyVault]: "azureKeyVaultConnectionFormData",
[AppConnection.AzureAppConfiguration]: "azureAppConfigurationConnectionFormData",
[AppConnection.AzureClientSecrets]: "azureClientSecretsConnectionFormData",
@@ -133,6 +140,57 @@ export const OAuthCallbackPage = () => {
}
};
const handleGitlab = useCallback(async () => {
const formData = getFormData(AppConnection.Gitlab);
if (formData === null) return null;
clearState(AppConnection.Gitlab);
const { connectionId, name, description, returnUrl, isUpdate } = formData;
try {
if (isUpdate && connectionId) {
await updateAppConnection.mutateAsync({
app: AppConnection.Gitlab,
connectionId,
credentials: {
code: code as string
}
});
} else {
await createAppConnection.mutateAsync({
app: AppConnection.Gitlab,
name,
description,
method: GitlabConnectionMethod.OAuth,
credentials: {
code: code as string
}
});
}
navigate({
to: returnUrl ?? "/organization/app-connections"
});
return {
connectionId,
returnUrl,
appConnectionName: formData.app
};
} catch (err: any) {
createNotification({
title: `Failed to ${connectionId ? "update" : "add"} GitLab Connection`,
text: err?.message,
type: "error"
});
navigate({
to: returnUrl ?? "/organization/app-connections"
});
return null;
}
}, []);
const handleAzureKeyVault = useCallback(async () => {
const formData = getFormData(AppConnection.AzureKeyVault);
if (formData === null) return null;
@@ -458,11 +516,14 @@ export const OAuthCallbackPage = () => {
(async () => {
let data: { connectionId?: string; returnUrl?: string; appConnectionName?: string } | null =
null;
console.log("appConnection", appConnection);
if (appConnection === AppConnection.GitHub) {
data = await handleGithub();
} else if (appConnection === AppConnection.GitHubRadar) {
data = await handleGithubRadar();
} else if (appConnection === AppConnection.Gitlab) {
data = await handleGitlab();
} else if (appConnection === AppConnection.AzureKeyVault) {
data = await handleAzureKeyVault();
} else if (appConnection === AppConnection.AzureAppConfiguration) {
@@ -5,6 +5,7 @@ import {
GitHubSyncScope,
GitHubSyncVisibility
} from "@app/hooks/api/secretSyncs/types/github-sync";
import { GitlabSyncScope } from "@app/hooks/api/secretSyncs/types/gitlab-sync";
import { HumanitecSyncScope } from "@app/hooks/api/secretSyncs/types/humanitec-sync";
// This functional ensures parity across what is displayed in the destination column
@@ -129,8 +130,15 @@ export const getSecretSyncDestinationColValues = (secretSync: TSecretSync) => {
secondaryText = "App ID";
break;
case SecretSync.GitLab:
primaryText = destinationConfig.projectName;
secondaryText = destinationConfig.projectId;
if (destinationConfig.scope === GitlabSyncScope.Project) {
primaryText = destinationConfig.projectName;
secondaryText = destinationConfig.projectId;
} else if (destinationConfig.scope === GitlabSyncScope.Group) {
primaryText = destinationConfig.groupName;
secondaryText = destinationConfig.groupId;
} else {
throw new Error(`Unhandled GitLab Scope Destination Col Values ${destination}`);
}
break;
default:
throw new Error(`Unhandled Destination Col Values ${destination}`);
@@ -1,5 +1,5 @@
import { GenericFieldLabel } from "@app/components/secret-syncs";
import { TGitlabSync } from "@app/hooks/api/secretSyncs/types/gitlab-sync";
import { GitlabSyncScope, TGitlabSync } from "@app/hooks/api/secretSyncs/types/gitlab-sync";
type Props = {
secretSync: TGitlabSync;
@@ -8,8 +8,6 @@ type Props = {
export const GitLabSyncDestinationSection = ({ secretSync }: Props) => {
const {
destinationConfig: {
projectName,
projectId,
targetEnvironment,
shouldProtectSecrets,
shouldMaskSecrets,
@@ -19,8 +17,26 @@ export const GitLabSyncDestinationSection = ({ secretSync }: Props) => {
return (
<>
<GenericFieldLabel label="Project Name">{projectName}</GenericFieldLabel>
<GenericFieldLabel label="Project ID">{projectId}</GenericFieldLabel>
{secretSync.destinationConfig.scope === GitlabSyncScope.Project && (
<>
<GenericFieldLabel label="Project Name">
{secretSync.destinationConfig.projectName}
</GenericFieldLabel>
<GenericFieldLabel label="Project ID">
{secretSync.destinationConfig.projectId}
</GenericFieldLabel>
</>
)}
{secretSync.destinationConfig.scope === GitlabSyncScope.Group && (
<>
<GenericFieldLabel label="Group Name">
{secretSync.destinationConfig.groupName}
</GenericFieldLabel>
<GenericFieldLabel label="Group ID">
{secretSync.destinationConfig.groupId}
</GenericFieldLabel>
</>
)}
{targetEnvironment && (
<GenericFieldLabel label="Environment">{targetEnvironment}</GenericFieldLabel>
)}