mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
App connection updates
This commit is contained in:
@@ -2632,6 +2632,9 @@ export const SecretScanningDataSources = {
|
|||||||
CONFIG: {
|
CONFIG: {
|
||||||
GITHUB: {
|
GITHUB: {
|
||||||
includeRepos: 'The repositories to include when scanning. Defaults to all repositories (["*"]).'
|
includeRepos: 'The repositories to include when scanning. Defaults to all repositories (["*"]).'
|
||||||
|
},
|
||||||
|
BITBUCKET: {
|
||||||
|
includeRepos: 'The repositories to include when scanning. Defaults to all repositories (["*"]).'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import { readLimit } from "@app/server/config/rateLimiter";
|
||||||
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
|
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
|
||||||
import {
|
import {
|
||||||
CreateBitBucketConnectionSchema,
|
CreateBitBucketConnectionSchema,
|
||||||
SanitizedBitBucketConnectionSchema,
|
SanitizedBitBucketConnectionSchema,
|
||||||
UpdateBitBucketConnectionSchema
|
UpdateBitBucketConnectionSchema
|
||||||
} from "@app/services/app-connection/bitbucket";
|
} from "@app/services/app-connection/bitbucket";
|
||||||
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
import { registerAppConnectionEndpoints } from "./app-connection-endpoints";
|
import { registerAppConnectionEndpoints } from "./app-connection-endpoints";
|
||||||
|
|
||||||
@@ -15,4 +20,32 @@ export const registerBitBucketConnectionRouter = async (server: FastifyZodProvid
|
|||||||
createSchema: CreateBitBucketConnectionSchema,
|
createSchema: CreateBitBucketConnectionSchema,
|
||||||
updateSchema: UpdateBitBucketConnectionSchema
|
updateSchema: UpdateBitBucketConnectionSchema
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// The below endpoints are not exposed and for Infisical App use
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
method: "GET",
|
||||||
|
url: `/:connectionId/repositories`,
|
||||||
|
config: {
|
||||||
|
rateLimit: readLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
params: z.object({
|
||||||
|
connectionId: z.string().uuid()
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
repositories: z.object({ id: z.string(), name: z.string() }).array()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const { connectionId } = req.params;
|
||||||
|
|
||||||
|
const repositories = await server.services.appConnection.bitbucket.listRepositories(connectionId, req.permission);
|
||||||
|
|
||||||
|
return { repositories };
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ import { AxiosError } from "axios";
|
|||||||
import { request } from "@app/lib/config/request";
|
import { request } from "@app/lib/config/request";
|
||||||
import { BadRequestError } from "@app/lib/errors";
|
import { BadRequestError } from "@app/lib/errors";
|
||||||
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
|
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
|
||||||
|
import { IntegrationUrls } from "@app/services/integration-auth/integration-list";
|
||||||
|
|
||||||
import { BitBucketConnectionMethod } from "./bitbucket-connection-enums";
|
import { BitBucketConnectionMethod } from "./bitbucket-connection-enums";
|
||||||
import { TBitBucketConnectionConfig } from "./bitbucket-connection-types";
|
import { TBitBucketConnection, TBitBucketConnectionConfig, TBitBucketRepo } from "./bitbucket-connection-types";
|
||||||
|
|
||||||
export const getBitBucketConnectionListItem = () => {
|
export const getBitBucketConnectionListItem = () => {
|
||||||
return {
|
return {
|
||||||
@@ -15,16 +16,16 @@ export const getBitBucketConnectionListItem = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const validateBitBucketConnectionCredentials = async (config: TBitBucketConnectionConfig) => {
|
export const getBitBucketUser = async ({ email, apiToken }: { email: string; apiToken: string }) => {
|
||||||
const { email, apiToken } = config.credentials;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await request.get("https://api.bitbucket.org/2.0/user", {
|
const { data } = await request.get<{ username: string }>(`${IntegrationUrls.BITBUCKET_API_URL}/2.0/user`, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Basic ${Buffer.from(`${email}:${apiToken}`).toString("base64")}`,
|
Authorization: `Basic ${Buffer.from(`${email}:${apiToken}`).toString("base64")}`,
|
||||||
Accept: "application/json"
|
Accept: "application/json"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
if (error instanceof AxiosError) {
|
if (error instanceof AxiosError) {
|
||||||
throw new BadRequestError({
|
throw new BadRequestError({
|
||||||
@@ -35,6 +36,26 @@ export const validateBitBucketConnectionCredentials = async (config: TBitBucketC
|
|||||||
message: "Unable to validate connection: verify credentials"
|
message: "Unable to validate connection: verify credentials"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const validateBitBucketConnectionCredentials = async (config: TBitBucketConnectionConfig) => {
|
||||||
|
await getBitBucketUser(config.credentials);
|
||||||
return config.credentials;
|
return config.credentials;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const listBitBucketRepositories = async (appConnection: TBitBucketConnection) => {
|
||||||
|
const { email, apiToken } = appConnection.credentials;
|
||||||
|
|
||||||
|
// TODO(andrey): Support pagination for cases where a token has access to over 100 repos
|
||||||
|
const { data } = await request.get<{ values: TBitBucketRepo[] }>(
|
||||||
|
`${IntegrationUrls.BITBUCKET_API_URL}/2.0/repositories?role=member&pagelen=100`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Basic ${Buffer.from(`${email}:${apiToken}`).toString("base64")}`,
|
||||||
|
Accept: "application/json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return data.values;
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { OrgServiceActor } from "@app/lib/types";
|
import { OrgServiceActor } from "@app/lib/types";
|
||||||
|
|
||||||
import { AppConnection } from "../app-connection-enums";
|
import { AppConnection } from "../app-connection-enums";
|
||||||
// import { listBitBucketVaults } from "./bitbucket-connection-fns";
|
import { listBitBucketRepositories } from "./bitbucket-connection-fns";
|
||||||
import { TBitBucketConnection } from "./bitbucket-connection-types";
|
import { TBitBucketConnection } from "./bitbucket-connection-types";
|
||||||
|
|
||||||
type TGetAppConnectionFunc = (
|
type TGetAppConnectionFunc = (
|
||||||
@@ -10,6 +10,17 @@ type TGetAppConnectionFunc = (
|
|||||||
actor: OrgServiceActor
|
actor: OrgServiceActor
|
||||||
) => Promise<TBitBucketConnection>;
|
) => Promise<TBitBucketConnection>;
|
||||||
|
|
||||||
export const bitBucketConnectionService = (_getAppConnection: TGetAppConnectionFunc) => {
|
export const bitBucketConnectionService = (getAppConnection: TGetAppConnectionFunc) => {
|
||||||
return {};
|
const listRepositories = async (connectionId: string, actor: OrgServiceActor) => {
|
||||||
|
const appConnection = await getAppConnection(AppConnection.BitBucket, connectionId, actor);
|
||||||
|
|
||||||
|
const repositories = await listBitBucketRepositories(appConnection);
|
||||||
|
|
||||||
|
// TODO(andrey): May need to change from slug to ID or something
|
||||||
|
return repositories.map((repo) => ({ id: repo.slug, name: repo.full_name }));
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
listRepositories
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,15 +24,7 @@ export type TBitBucketConnectionConfig = DiscriminativePick<
|
|||||||
orgId: string;
|
orgId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TBitBucketVault = {
|
export type TBitBucketRepo = {
|
||||||
id: string;
|
full_name: string; // workspace-slug/repo-slug
|
||||||
name: string;
|
slug: string;
|
||||||
type: string;
|
|
||||||
items: number;
|
|
||||||
|
|
||||||
attributeVersion: number;
|
|
||||||
contentVersion: number;
|
|
||||||
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ import {
|
|||||||
VercelConnectionMethod,
|
VercelConnectionMethod,
|
||||||
WindmillConnectionMethod
|
WindmillConnectionMethod
|
||||||
} from "@app/hooks/api/appConnections/types";
|
} from "@app/hooks/api/appConnections/types";
|
||||||
|
import { BitBucketConnectionMethod } from "@app/hooks/api/appConnections/types/bitbucket-connection";
|
||||||
import { HerokuConnectionMethod } from "@app/hooks/api/appConnections/types/heroku-connection";
|
import { HerokuConnectionMethod } from "@app/hooks/api/appConnections/types/heroku-connection";
|
||||||
import { OCIConnectionMethod } from "@app/hooks/api/appConnections/types/oci-connection";
|
import { OCIConnectionMethod } from "@app/hooks/api/appConnections/types/oci-connection";
|
||||||
import { RenderConnectionMethod } from "@app/hooks/api/appConnections/types/render-connection";
|
import { RenderConnectionMethod } from "@app/hooks/api/appConnections/types/render-connection";
|
||||||
import { BitBucketConnectionMethod } from "@app/hooks/api/appConnections/types/bitbucket-connection";
|
|
||||||
|
|
||||||
export const APP_CONNECTION_MAP: Record<
|
export const APP_CONNECTION_MAP: Record<
|
||||||
AppConnection,
|
AppConnection,
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { useQuery, UseQueryOptions } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
import { apiRequest } from "@app/config/request";
|
||||||
|
|
||||||
|
import { appConnectionKeys } from "../queries";
|
||||||
|
import { TBitBucketConnectionListRepositoriesResponse, TBitBucketRepo } from "./types";
|
||||||
|
|
||||||
|
const bitBucketConnectionKeys = {
|
||||||
|
all: [...appConnectionKeys.all, "bitbucket"] as const,
|
||||||
|
listRepos: (connectionId: string) =>
|
||||||
|
[...bitBucketConnectionKeys.all, "repos", connectionId] as const
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useBitBucketConnectionListRepositories = (
|
||||||
|
connectionId: string,
|
||||||
|
options?: Omit<
|
||||||
|
UseQueryOptions<
|
||||||
|
TBitBucketRepo[],
|
||||||
|
unknown,
|
||||||
|
TBitBucketRepo[],
|
||||||
|
ReturnType<typeof bitBucketConnectionKeys.listRepos>
|
||||||
|
>,
|
||||||
|
"queryKey" | "queryFn"
|
||||||
|
>
|
||||||
|
) => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: bitBucketConnectionKeys.listRepos(connectionId),
|
||||||
|
queryFn: async () => {
|
||||||
|
const { data } = await apiRequest.get<TBitBucketConnectionListRepositoriesResponse>(
|
||||||
|
`/api/v1/app-connections/bitbucket/${connectionId}/repositories`
|
||||||
|
);
|
||||||
|
|
||||||
|
return data.repositories;
|
||||||
|
},
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
export type TBitBucketRepo = {
|
||||||
|
id: string;
|
||||||
|
name: string; // workspace-slug/repo-slug
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TBitBucketConnectionListRepositoriesResponse = {
|
||||||
|
repositories: TBitBucketRepo[];
|
||||||
|
};
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ export * from "./azure-app-configuration-connection";
|
|||||||
export * from "./azure-client-secrets-connection";
|
export * from "./azure-client-secrets-connection";
|
||||||
export * from "./azure-devops-connection";
|
export * from "./azure-devops-connection";
|
||||||
export * from "./azure-key-vault-connection";
|
export * from "./azure-key-vault-connection";
|
||||||
|
export * from "./bitbucket-connection";
|
||||||
export * from "./camunda-connection";
|
export * from "./camunda-connection";
|
||||||
export * from "./cloudflare-connection";
|
export * from "./cloudflare-connection";
|
||||||
export * from "./databricks-connection";
|
export * from "./databricks-connection";
|
||||||
@@ -60,7 +61,6 @@ export * from "./teamcity-connection";
|
|||||||
export * from "./terraform-cloud-connection";
|
export * from "./terraform-cloud-connection";
|
||||||
export * from "./vercel-connection";
|
export * from "./vercel-connection";
|
||||||
export * from "./windmill-connection";
|
export * from "./windmill-connection";
|
||||||
export * from "./bitbucket-connection";
|
|
||||||
|
|
||||||
export type TAppConnection =
|
export type TAppConnection =
|
||||||
| TAwsConnection
|
| TAwsConnection
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { AzureAppConfigurationConnectionForm } from "./AzureAppConfigurationConn
|
|||||||
import { AzureClientSecretsConnectionForm } from "./AzureClientSecretsConnectionForm";
|
import { AzureClientSecretsConnectionForm } from "./AzureClientSecretsConnectionForm";
|
||||||
import { AzureDevOpsConnectionForm } from "./AzureDevOpsConnectionForm";
|
import { AzureDevOpsConnectionForm } from "./AzureDevOpsConnectionForm";
|
||||||
import { AzureKeyVaultConnectionForm } from "./AzureKeyVaultConnectionForm";
|
import { AzureKeyVaultConnectionForm } from "./AzureKeyVaultConnectionForm";
|
||||||
|
import { BitBucketConnectionForm } from "./BitBucketConnectionForm";
|
||||||
import { CamundaConnectionForm } from "./CamundaConnectionForm";
|
import { CamundaConnectionForm } from "./CamundaConnectionForm";
|
||||||
import { CloudflareConnectionForm } from "./CloudflareConnectionForm";
|
import { CloudflareConnectionForm } from "./CloudflareConnectionForm";
|
||||||
import { DatabricksConnectionForm } from "./DatabricksConnectionForm";
|
import { DatabricksConnectionForm } from "./DatabricksConnectionForm";
|
||||||
@@ -38,7 +39,6 @@ import { TeamCityConnectionForm } from "./TeamCityConnectionForm";
|
|||||||
import { TerraformCloudConnectionForm } from "./TerraformCloudConnectionForm";
|
import { TerraformCloudConnectionForm } from "./TerraformCloudConnectionForm";
|
||||||
import { VercelConnectionForm } from "./VercelConnectionForm";
|
import { VercelConnectionForm } from "./VercelConnectionForm";
|
||||||
import { WindmillConnectionForm } from "./WindmillConnectionForm";
|
import { WindmillConnectionForm } from "./WindmillConnectionForm";
|
||||||
import { BitBucketConnectionForm } from "./BitBucketConnectionForm";
|
|
||||||
|
|
||||||
type FormProps = {
|
type FormProps = {
|
||||||
onComplete: (appConnection: TAppConnection) => void;
|
onComplete: (appConnection: TAppConnection) => void;
|
||||||
|
|||||||
Reference in New Issue
Block a user