From 5ee2eb1aa2758319dbeeef8ce0c7c41a47929c2e Mon Sep 17 00:00:00 2001 From: x032205 Date: Sat, 7 Jun 2025 00:07:34 -0400 Subject: [PATCH] feat(secret-rotation): Oracle DB --- .../oracledb-connection-router.ts | 17 ++ .../v2/secret-rotation-v2-routers/index.ts | 2 + .../oracledb-credentials-rotation-router.ts | 19 +++ .../secret-rotation-v2-router.ts | 2 + .../app-connections/oracledb/index.ts | 4 + .../oracledb/oracledb-connection-enums.ts | 3 + .../oracledb/oracledb-connection-fns.ts | 12 ++ .../oracledb/oracledb-connection-schemas.ts | 66 ++++++++ .../oracledb/oracledb-connection-types.ts | 17 ++ .../oracledb-credentials/index.ts | 3 + ...oracledb-credentials-rotation-constants.ts | 20 +++ .../oracledb-credentials-rotation-schemas.ts | 41 +++++ .../oracledb-credentials-rotation-types.ts | 18 ++ .../secret-rotation-v2-enums.ts | 1 + .../secret-rotation-v2-fns.ts | 2 + .../secret-rotation-v2-maps.ts | 2 + .../secret-rotation-v2-service.ts | 1 + .../secret-rotation-v2-types.ts | 10 ++ .../secret-rotation-v2-union-schema.ts | 2 + .../sql-credentials-rotation-types.ts | 4 +- .../secret-rotation-queue-fn.ts | 7 + .../secret-rotation/templates/types.ts | 3 +- .../app-connection-router.ts | 6 + .../routes/v1/app-connection-routers/index.ts | 2 + .../app-connection/app-connection-enums.ts | 1 + .../app-connection/app-connection-fns.ts | 5 + .../app-connection/app-connection-maps.ts | 2 + .../app-connection/app-connection-service.ts | 2 + .../app-connection/app-connection-types.ts | 16 +- .../shared/sql/sql-connection-fns.ts | 10 +- ...ewSecretRotationV2GeneratedCredentials.tsx | 1 + ...redentialsRotationGeneratedCredentials.tsx | 2 + .../SecretRotationV2ParametersFields.tsx | 1 + .../SecretRotationReviewFields.tsx | 1 + .../SecretRotationV2SecretsMappingFields.tsx | 1 + .../forms/schemas/index.ts | 3 + .../oracledb-credentials-rotation-schema.ts | 12 ++ frontend/src/helpers/appConnections.ts | 3 + frontend/src/helpers/secretRotationsV2.ts | 7 + .../src/hooks/api/appConnections/enums.ts | 1 + .../api/appConnections/types/app-options.ts | 6 + .../hooks/api/appConnections/types/index.ts | 4 + .../types/oracledb-connection.ts | 13 ++ .../src/hooks/api/secretRotationsV2/enums.ts | 1 + .../api/secretRotationsV2/types/index.ts | 8 + .../types/oracledb-credentials-rotation.ts | 17 ++ .../types/shared/sql-credentials-rotation.ts | 9 +- .../AppConnectionForm/AppConnectionForm.tsx | 5 + .../OracleDBConnectionForm.tsx | 155 ++++++++++++++++++ 49 files changed, 542 insertions(+), 8 deletions(-) create mode 100644 backend/src/ee/routes/v1/app-connection-routers/oracledb-connection-router.ts create mode 100644 backend/src/ee/routes/v2/secret-rotation-v2-routers/oracledb-credentials-rotation-router.ts create mode 100644 backend/src/ee/services/app-connections/oracledb/index.ts create mode 100644 backend/src/ee/services/app-connections/oracledb/oracledb-connection-enums.ts create mode 100644 backend/src/ee/services/app-connections/oracledb/oracledb-connection-fns.ts create mode 100644 backend/src/ee/services/app-connections/oracledb/oracledb-connection-schemas.ts create mode 100644 backend/src/ee/services/app-connections/oracledb/oracledb-connection-types.ts create mode 100644 backend/src/ee/services/secret-rotation-v2/oracledb-credentials/index.ts create mode 100644 backend/src/ee/services/secret-rotation-v2/oracledb-credentials/oracledb-credentials-rotation-constants.ts create mode 100644 backend/src/ee/services/secret-rotation-v2/oracledb-credentials/oracledb-credentials-rotation-schemas.ts create mode 100644 backend/src/ee/services/secret-rotation-v2/oracledb-credentials/oracledb-credentials-rotation-types.ts create mode 100644 frontend/src/components/secret-rotations-v2/forms/schemas/oracledb-credentials-rotation-schema.ts create mode 100644 frontend/src/hooks/api/appConnections/types/oracledb-connection.ts create mode 100644 frontend/src/hooks/api/secretRotationsV2/types/oracledb-credentials-rotation.ts create mode 100644 frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/OracleDBConnectionForm.tsx diff --git a/backend/src/ee/routes/v1/app-connection-routers/oracledb-connection-router.ts b/backend/src/ee/routes/v1/app-connection-routers/oracledb-connection-router.ts new file mode 100644 index 000000000..8a90fe9a7 --- /dev/null +++ b/backend/src/ee/routes/v1/app-connection-routers/oracledb-connection-router.ts @@ -0,0 +1,17 @@ +import { + CreateOracleDBConnectionSchema, + SanitizedOracleDBConnectionSchema, + UpdateOracleDBConnectionSchema +} from "@app/ee/services/app-connections/oracledb"; +import { registerAppConnectionEndpoints } from "@app/server/routes/v1/app-connection-routers/app-connection-endpoints"; +import { AppConnection } from "@app/services/app-connection/app-connection-enums"; + +export const registerOracleDBConnectionRouter = async (server: FastifyZodProvider) => { + registerAppConnectionEndpoints({ + app: AppConnection.OracleDB, + server, + sanitizedResponseSchema: SanitizedOracleDBConnectionSchema, + createSchema: CreateOracleDBConnectionSchema, + updateSchema: UpdateOracleDBConnectionSchema + }); +}; diff --git a/backend/src/ee/routes/v2/secret-rotation-v2-routers/index.ts b/backend/src/ee/routes/v2/secret-rotation-v2-routers/index.ts index c33609621..5d4ccc021 100644 --- a/backend/src/ee/routes/v2/secret-rotation-v2-routers/index.ts +++ b/backend/src/ee/routes/v2/secret-rotation-v2-routers/index.ts @@ -6,6 +6,7 @@ import { registerAzureClientSecretRotationRouter } from "./azure-client-secret-r import { registerLdapPasswordRotationRouter } from "./ldap-password-rotation-router"; import { registerMsSqlCredentialsRotationRouter } from "./mssql-credentials-rotation-router"; import { registerMySqlCredentialsRotationRouter } from "./mysql-credentials-rotation-router"; +import { registerOracleDBCredentialsRotationRouter } from "./oracledb-credentials-rotation-router"; import { registerPostgresCredentialsRotationRouter } from "./postgres-credentials-rotation-router"; export * from "./secret-rotation-v2-router"; @@ -17,6 +18,7 @@ export const SECRET_ROTATION_REGISTER_ROUTER_MAP: Record< [SecretRotation.PostgresCredentials]: registerPostgresCredentialsRotationRouter, [SecretRotation.MsSqlCredentials]: registerMsSqlCredentialsRotationRouter, [SecretRotation.MySqlCredentials]: registerMySqlCredentialsRotationRouter, + [SecretRotation.OracleDBCredentials]: registerOracleDBCredentialsRotationRouter, [SecretRotation.Auth0ClientSecret]: registerAuth0ClientSecretRotationRouter, [SecretRotation.AzureClientSecret]: registerAzureClientSecretRotationRouter, [SecretRotation.AwsIamUserSecret]: registerAwsIamUserSecretRotationRouter, diff --git a/backend/src/ee/routes/v2/secret-rotation-v2-routers/oracledb-credentials-rotation-router.ts b/backend/src/ee/routes/v2/secret-rotation-v2-routers/oracledb-credentials-rotation-router.ts new file mode 100644 index 000000000..b1721c59e --- /dev/null +++ b/backend/src/ee/routes/v2/secret-rotation-v2-routers/oracledb-credentials-rotation-router.ts @@ -0,0 +1,19 @@ +import { + CreateOracleDBCredentialsRotationSchema, + OracleDBCredentialsRotationSchema, + UpdateOracleDBCredentialsRotationSchema +} from "@app/ee/services/secret-rotation-v2/oracledb-credentials"; +import { SecretRotation } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-enums"; +import { SqlCredentialsRotationGeneratedCredentialsSchema } from "@app/ee/services/secret-rotation-v2/shared/sql-credentials"; + +import { registerSecretRotationEndpoints } from "./secret-rotation-v2-endpoints"; + +export const registerOracleDBCredentialsRotationRouter = async (server: FastifyZodProvider) => + registerSecretRotationEndpoints({ + type: SecretRotation.OracleDBCredentials, + server, + responseSchema: OracleDBCredentialsRotationSchema, + createSchema: CreateOracleDBCredentialsRotationSchema, + updateSchema: UpdateOracleDBCredentialsRotationSchema, + generatedCredentialsSchema: SqlCredentialsRotationGeneratedCredentialsSchema + }); diff --git a/backend/src/ee/routes/v2/secret-rotation-v2-routers/secret-rotation-v2-router.ts b/backend/src/ee/routes/v2/secret-rotation-v2-routers/secret-rotation-v2-router.ts index 5e3e09846..86768c3ad 100644 --- a/backend/src/ee/routes/v2/secret-rotation-v2-routers/secret-rotation-v2-router.ts +++ b/backend/src/ee/routes/v2/secret-rotation-v2-routers/secret-rotation-v2-router.ts @@ -7,6 +7,7 @@ import { AzureClientSecretRotationListItemSchema } from "@app/ee/services/secret import { LdapPasswordRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/ldap-password"; import { MsSqlCredentialsRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/mssql-credentials"; import { MySqlCredentialsRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/mysql-credentials"; +import { OracleDBCredentialsRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/oracledb-credentials"; import { PostgresCredentialsRotationListItemSchema } from "@app/ee/services/secret-rotation-v2/postgres-credentials"; import { SecretRotationV2Schema } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-union-schema"; import { ApiDocsTags, SecretRotations } from "@app/lib/api-docs"; @@ -18,6 +19,7 @@ const SecretRotationV2OptionsSchema = z.discriminatedUnion("type", [ PostgresCredentialsRotationListItemSchema, MsSqlCredentialsRotationListItemSchema, MySqlCredentialsRotationListItemSchema, + OracleDBCredentialsRotationListItemSchema, Auth0ClientSecretRotationListItemSchema, AzureClientSecretRotationListItemSchema, AwsIamUserSecretRotationListItemSchema, diff --git a/backend/src/ee/services/app-connections/oracledb/index.ts b/backend/src/ee/services/app-connections/oracledb/index.ts new file mode 100644 index 000000000..a9d29ab4b --- /dev/null +++ b/backend/src/ee/services/app-connections/oracledb/index.ts @@ -0,0 +1,4 @@ +export * from "./oracledb-connection-enums"; +export * from "./oracledb-connection-fns"; +export * from "./oracledb-connection-schemas"; +export * from "./oracledb-connection-types"; diff --git a/backend/src/ee/services/app-connections/oracledb/oracledb-connection-enums.ts b/backend/src/ee/services/app-connections/oracledb/oracledb-connection-enums.ts new file mode 100644 index 000000000..570e56f2c --- /dev/null +++ b/backend/src/ee/services/app-connections/oracledb/oracledb-connection-enums.ts @@ -0,0 +1,3 @@ +export enum OracleDBConnectionMethod { + UsernameAndPassword = "username-and-password" +} diff --git a/backend/src/ee/services/app-connections/oracledb/oracledb-connection-fns.ts b/backend/src/ee/services/app-connections/oracledb/oracledb-connection-fns.ts new file mode 100644 index 000000000..c1012ed6e --- /dev/null +++ b/backend/src/ee/services/app-connections/oracledb/oracledb-connection-fns.ts @@ -0,0 +1,12 @@ +import { AppConnection } from "@app/services/app-connection/app-connection-enums"; + +import { OracleDBConnectionMethod } from "./oracledb-connection-enums"; + +export const getOracleDBConnectionListItem = () => { + return { + name: "OracleDB" as const, + app: AppConnection.OracleDB as const, + methods: Object.values(OracleDBConnectionMethod) as [OracleDBConnectionMethod.UsernameAndPassword], + supportsPlatformManagement: true as const // TODO(andrey): Explore if possible + }; +}; diff --git a/backend/src/ee/services/app-connections/oracledb/oracledb-connection-schemas.ts b/backend/src/ee/services/app-connections/oracledb/oracledb-connection-schemas.ts new file mode 100644 index 000000000..50d261ffc --- /dev/null +++ b/backend/src/ee/services/app-connections/oracledb/oracledb-connection-schemas.ts @@ -0,0 +1,66 @@ +import z from "zod"; + +import { AppConnections } from "@app/lib/api-docs"; +import { AppConnection } from "@app/services/app-connection/app-connection-enums"; +import { + BaseAppConnectionSchema, + GenericCreateAppConnectionFieldsSchema, + GenericUpdateAppConnectionFieldsSchema +} from "@app/services/app-connection/app-connection-schemas"; +import { BaseSqlUsernameAndPasswordConnectionSchema } from "@app/services/app-connection/shared/sql"; + +import { OracleDBConnectionMethod } from "./oracledb-connection-enums"; + +export const OracleDBConnectionAccessTokenCredentialsSchema = BaseSqlUsernameAndPasswordConnectionSchema; + +const BaseOracleDBConnectionSchema = BaseAppConnectionSchema.extend({ app: z.literal(AppConnection.OracleDB) }); + +export const OracleDBConnectionSchema = BaseOracleDBConnectionSchema.extend({ + method: z.literal(OracleDBConnectionMethod.UsernameAndPassword), + credentials: OracleDBConnectionAccessTokenCredentialsSchema +}); + +export const SanitizedOracleDBConnectionSchema = z.discriminatedUnion("method", [ + BaseOracleDBConnectionSchema.extend({ + method: z.literal(OracleDBConnectionMethod.UsernameAndPassword), + credentials: OracleDBConnectionAccessTokenCredentialsSchema.pick({ + host: true, + database: true, + port: true, + username: true, + sslEnabled: true, + sslRejectUnauthorized: true, + sslCertificate: true + }) + }) +]); + +export const ValidateOracleDBConnectionCredentialsSchema = z.discriminatedUnion("method", [ + z.object({ + method: z + .literal(OracleDBConnectionMethod.UsernameAndPassword) + .describe(AppConnections.CREATE(AppConnection.OracleDB).method), + credentials: OracleDBConnectionAccessTokenCredentialsSchema.describe( + AppConnections.CREATE(AppConnection.OracleDB).credentials + ) + }) +]); + +export const CreateOracleDBConnectionSchema = ValidateOracleDBConnectionCredentialsSchema.and( + GenericCreateAppConnectionFieldsSchema(AppConnection.OracleDB, { supportsPlatformManagedCredentials: true }) +); + +export const UpdateOracleDBConnectionSchema = z + .object({ + credentials: OracleDBConnectionAccessTokenCredentialsSchema.optional().describe( + AppConnections.UPDATE(AppConnection.OracleDB).credentials + ) + }) + .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.OracleDB, { supportsPlatformManagedCredentials: true })); + +export const OracleDBConnectionListItemSchema = z.object({ + name: z.literal("OracleDB"), + app: z.literal(AppConnection.OracleDB), + methods: z.nativeEnum(OracleDBConnectionMethod).array(), + supportsPlatformManagement: z.literal(true) +}); diff --git a/backend/src/ee/services/app-connections/oracledb/oracledb-connection-types.ts b/backend/src/ee/services/app-connections/oracledb/oracledb-connection-types.ts new file mode 100644 index 000000000..cffed12da --- /dev/null +++ b/backend/src/ee/services/app-connections/oracledb/oracledb-connection-types.ts @@ -0,0 +1,17 @@ +import z from "zod"; + +import { AppConnection } from "@app/services/app-connection/app-connection-enums"; + +import { + CreateOracleDBConnectionSchema, + OracleDBConnectionSchema, + ValidateOracleDBConnectionCredentialsSchema +} from "./oracledb-connection-schemas"; + +export type TOracleDBConnection = z.infer; + +export type TOracleDBConnectionInput = z.infer & { + app: AppConnection.OracleDB; +}; + +export type TValidateOracleDBConnectionCredentialsSchema = typeof ValidateOracleDBConnectionCredentialsSchema; diff --git a/backend/src/ee/services/secret-rotation-v2/oracledb-credentials/index.ts b/backend/src/ee/services/secret-rotation-v2/oracledb-credentials/index.ts new file mode 100644 index 000000000..2902d780d --- /dev/null +++ b/backend/src/ee/services/secret-rotation-v2/oracledb-credentials/index.ts @@ -0,0 +1,3 @@ +export * from "./oracledb-credentials-rotation-constants"; +export * from "./oracledb-credentials-rotation-schemas"; +export * from "./oracledb-credentials-rotation-types"; diff --git a/backend/src/ee/services/secret-rotation-v2/oracledb-credentials/oracledb-credentials-rotation-constants.ts b/backend/src/ee/services/secret-rotation-v2/oracledb-credentials/oracledb-credentials-rotation-constants.ts new file mode 100644 index 000000000..9b7436989 --- /dev/null +++ b/backend/src/ee/services/secret-rotation-v2/oracledb-credentials/oracledb-credentials-rotation-constants.ts @@ -0,0 +1,20 @@ +import { SecretRotation } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-enums"; +import { TSecretRotationV2ListItem } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-types"; +import { AppConnection } from "@app/services/app-connection/app-connection-enums"; + +export const ORACLEDB_CREDENTIALS_ROTATION_LIST_OPTION: TSecretRotationV2ListItem = { + name: "OracleDB Credentials", + type: SecretRotation.OracleDBCredentials, + connection: AppConnection.OracleDB, + template: { + createUserStatement: `-- create user +CREATE USER "infisical_user" IDENTIFIED BY "temporary_password"; + +-- grant all privileges +GRANT ALL PRIVILEGES TO "infisical_user";`, + secretsMapping: { + username: "ORACLEDB_USERNAME", + password: "ORACLEDB_PASSWORD" + } + } +}; diff --git a/backend/src/ee/services/secret-rotation-v2/oracledb-credentials/oracledb-credentials-rotation-schemas.ts b/backend/src/ee/services/secret-rotation-v2/oracledb-credentials/oracledb-credentials-rotation-schemas.ts new file mode 100644 index 000000000..267098e9c --- /dev/null +++ b/backend/src/ee/services/secret-rotation-v2/oracledb-credentials/oracledb-credentials-rotation-schemas.ts @@ -0,0 +1,41 @@ +import { z } from "zod"; + +import { SecretRotation } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-enums"; +import { + BaseCreateSecretRotationSchema, + BaseSecretRotationSchema, + BaseUpdateSecretRotationSchema +} from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-schemas"; +import { + SqlCredentialsRotationParametersSchema, + SqlCredentialsRotationSecretsMappingSchema, + SqlCredentialsRotationTemplateSchema +} from "@app/ee/services/secret-rotation-v2/shared/sql-credentials"; +import { AppConnection } from "@app/services/app-connection/app-connection-enums"; + +export const OracleDBCredentialsRotationSchema = BaseSecretRotationSchema(SecretRotation.OracleDBCredentials).extend({ + type: z.literal(SecretRotation.OracleDBCredentials), + parameters: SqlCredentialsRotationParametersSchema, + secretsMapping: SqlCredentialsRotationSecretsMappingSchema +}); + +export const CreateOracleDBCredentialsRotationSchema = BaseCreateSecretRotationSchema( + SecretRotation.OracleDBCredentials +).extend({ + parameters: SqlCredentialsRotationParametersSchema, + secretsMapping: SqlCredentialsRotationSecretsMappingSchema +}); + +export const UpdateOracleDBCredentialsRotationSchema = BaseUpdateSecretRotationSchema( + SecretRotation.OracleDBCredentials +).extend({ + parameters: SqlCredentialsRotationParametersSchema.optional(), + secretsMapping: SqlCredentialsRotationSecretsMappingSchema.optional() +}); + +export const OracleDBCredentialsRotationListItemSchema = z.object({ + name: z.literal("OracleDB Credentials"), + connection: z.literal(AppConnection.OracleDB), + type: z.literal(SecretRotation.OracleDBCredentials), + template: SqlCredentialsRotationTemplateSchema +}); diff --git a/backend/src/ee/services/secret-rotation-v2/oracledb-credentials/oracledb-credentials-rotation-types.ts b/backend/src/ee/services/secret-rotation-v2/oracledb-credentials/oracledb-credentials-rotation-types.ts new file mode 100644 index 000000000..d303eea62 --- /dev/null +++ b/backend/src/ee/services/secret-rotation-v2/oracledb-credentials/oracledb-credentials-rotation-types.ts @@ -0,0 +1,18 @@ +import { z } from "zod"; + +import { TOracleDBConnection } from "../../app-connections/oracledb"; +import { + CreateOracleDBCredentialsRotationSchema, + OracleDBCredentialsRotationListItemSchema, + OracleDBCredentialsRotationSchema +} from "./oracledb-credentials-rotation-schemas"; + +export type TOracleDBCredentialsRotation = z.infer; + +export type TOracleDBCredentialsRotationInput = z.infer; + +export type TOracleDBCredentialsRotationListItem = z.infer; + +export type TOracleDBCredentialsRotationWithConnection = TOracleDBCredentialsRotation & { + connection: TOracleDBConnection; +}; diff --git a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-enums.ts b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-enums.ts index a8c92e255..84dc30821 100644 --- a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-enums.ts +++ b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-enums.ts @@ -2,6 +2,7 @@ export enum SecretRotation { PostgresCredentials = "postgres-credentials", MsSqlCredentials = "mssql-credentials", MySqlCredentials = "mysql-credentials", + OracleDBCredentials = "oracledb-credentials", Auth0ClientSecret = "auth0-client-secret", AzureClientSecret = "azure-client-secret", AwsIamUserSecret = "aws-iam-user-secret", diff --git a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-fns.ts b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-fns.ts index ea1b99107..228c4c2a1 100644 --- a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-fns.ts +++ b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-fns.ts @@ -10,6 +10,7 @@ import { AZURE_CLIENT_SECRET_ROTATION_LIST_OPTION } from "./azure-client-secret" import { LDAP_PASSWORD_ROTATION_LIST_OPTION, TLdapPasswordRotation } from "./ldap-password"; import { MSSQL_CREDENTIALS_ROTATION_LIST_OPTION } from "./mssql-credentials"; import { MYSQL_CREDENTIALS_ROTATION_LIST_OPTION } from "./mysql-credentials"; +import { ORACLEDB_CREDENTIALS_ROTATION_LIST_OPTION } from "./oracledb-credentials"; import { POSTGRES_CREDENTIALS_ROTATION_LIST_OPTION } from "./postgres-credentials"; import { SecretRotation, SecretRotationStatus } from "./secret-rotation-v2-enums"; import { TSecretRotationV2ServiceFactoryDep } from "./secret-rotation-v2-service"; @@ -25,6 +26,7 @@ const SECRET_ROTATION_LIST_OPTIONS: Record = { [SecretRotation.PostgresCredentials]: "PostgreSQL Credentials", [SecretRotation.MsSqlCredentials]: "Microsoft SQL Server Credentials", [SecretRotation.MySqlCredentials]: "MySQL Credentials", + [SecretRotation.OracleDBCredentials]: "OracleDB Credentials", [SecretRotation.Auth0ClientSecret]: "Auth0 Client Secret", [SecretRotation.AzureClientSecret]: "Azure Client Secret", [SecretRotation.AwsIamUserSecret]: "AWS IAM User Secret", @@ -15,6 +16,7 @@ export const SECRET_ROTATION_CONNECTION_MAP: Record { getLdapConnectionListItem(), getTeamCityConnectionListItem(), getOCIConnectionListItem(), + getOracleDBConnectionListItem(), getOnePassConnectionListItem() ].sort((a, b) => a.name.localeCompare(b.name)); }; @@ -186,6 +188,7 @@ export const validateAppConnectionCredentials = async ( [AppConnection.LDAP]: validateLdapConnectionCredentials as TAppConnectionCredentialsValidator, [AppConnection.TeamCity]: validateTeamCityConnectionCredentials as TAppConnectionCredentialsValidator, [AppConnection.OCI]: validateOCIConnectionCredentials as TAppConnectionCredentialsValidator, + [AppConnection.OracleDB]: validateSqlConnectionCredentials as TAppConnectionCredentialsValidator, [AppConnection.OnePass]: validateOnePassConnectionCredentials as TAppConnectionCredentialsValidator }; @@ -221,6 +224,7 @@ export const getAppConnectionMethodName = (method: TAppConnection["method"]) => case PostgresConnectionMethod.UsernameAndPassword: case MsSqlConnectionMethod.UsernameAndPassword: case MySqlConnectionMethod.UsernameAndPassword: + case OracleDBConnectionMethod.UsernameAndPassword: return "Username & Password"; case WindmillConnectionMethod.AccessToken: case HCVaultConnectionMethod.AccessToken: @@ -284,6 +288,7 @@ export const TRANSITION_CONNECTION_CREDENTIALS_TO_PLATFORM: Record< [AppConnection.LDAP]: platformManagedCredentialsNotSupported, // we could support this in the future [AppConnection.TeamCity]: platformManagedCredentialsNotSupported, [AppConnection.OCI]: platformManagedCredentialsNotSupported, + [AppConnection.OracleDB]: platformManagedCredentialsNotSupported, // TODO(andrey): If managed credentials change this [AppConnection.OnePass]: platformManagedCredentialsNotSupported }; diff --git a/backend/src/services/app-connection/app-connection-maps.ts b/backend/src/services/app-connection/app-connection-maps.ts index 0042fdf42..398976c9c 100644 --- a/backend/src/services/app-connection/app-connection-maps.ts +++ b/backend/src/services/app-connection/app-connection-maps.ts @@ -22,6 +22,7 @@ export const APP_CONNECTION_NAME_MAP: Record = { [AppConnection.LDAP]: "LDAP", [AppConnection.TeamCity]: "TeamCity", [AppConnection.OCI]: "OCI", + [AppConnection.OracleDB]: "OracleDB", [AppConnection.OnePass]: "1Password" }; @@ -46,6 +47,7 @@ export const APP_CONNECTION_PLAN_MAP: Record>>; -export type TSqlConnection = TPostgresConnection | TMsSqlConnection | TMySqlConnection; +export type TSqlConnection = TPostgresConnection | TMsSqlConnection | TMySqlConnection | TOracleDBConnection; export type TAppConnectionInput = { id: string } & ( | TAwsConnectionInput @@ -176,10 +182,15 @@ export type TAppConnectionInput = { id: string } & ( | TLdapConnectionInput | TTeamCityConnectionInput | TOCIConnectionInput + | TOracleDBConnectionInput | TOnePassConnectionInput ); -export type TSqlConnectionInput = TPostgresConnectionInput | TMsSqlConnectionInput | TMySqlConnectionInput; +export type TSqlConnectionInput = + | TPostgresConnectionInput + | TMsSqlConnectionInput + | TMySqlConnectionInput + | TOracleDBConnectionInput; export type TCreateAppConnectionDTO = Pick< TAppConnectionInput, @@ -234,6 +245,7 @@ export type TValidateAppConnectionCredentialsSchema = | TValidateLdapConnectionCredentialsSchema | TValidateTeamCityConnectionCredentialsSchema | TValidateOCIConnectionCredentialsSchema + | TValidateOracleDBConnectionCredentialsSchema | TValidateOnePassConnectionCredentialsSchema; export type TListAwsConnectionKmsKeys = { diff --git a/backend/src/services/app-connection/shared/sql/sql-connection-fns.ts b/backend/src/services/app-connection/shared/sql/sql-connection-fns.ts index 7df1929ba..9a7f1d199 100644 --- a/backend/src/services/app-connection/shared/sql/sql-connection-fns.ts +++ b/backend/src/services/app-connection/shared/sql/sql-connection-fns.ts @@ -16,7 +16,8 @@ const EXTERNAL_REQUEST_TIMEOUT = 10 * 1000; const SQL_CONNECTION_CLIENT_MAP = { [AppConnection.Postgres]: "pg", [AppConnection.MsSql]: "mssql", - [AppConnection.MySql]: "mysql2" + [AppConnection.MySql]: "mysql2", + [AppConnection.OracleDB]: "oracledb" }; const getConnectionConfig = ({ @@ -57,6 +58,10 @@ const getConnectionConfig = ({ : false }; } + // TODO(andrey): Might be interesting for later + case AppConnection.OracleDB: { + return {}; + } default: throw new Error(`Unhandled SQL Connection Config: ${app as AppConnection}`); } @@ -114,7 +119,8 @@ export const SQL_CONNECTION_ALTER_LOGIN_STATEMENT: Record< > = { [AppConnection.Postgres]: ({ username, password }) => [`ALTER USER ?? WITH PASSWORD '${password}';`, [username]], [AppConnection.MsSql]: ({ username, password }) => [`ALTER LOGIN ?? WITH PASSWORD = '${password}';`, [username]], - [AppConnection.MySql]: ({ username, password }) => [`ALTER USER ??@'%' IDENTIFIED BY '${password}';`, [username]] + [AppConnection.MySql]: ({ username, password }) => [`ALTER USER ??@'%' IDENTIFIED BY '${password}';`, [username]], + [AppConnection.OracleDB]: ({ username, password }) => [`ALTER USER ?? IDENTIFIED BY "${password}"`, [username]] }; export const transferSqlConnectionCredentialsToPlatform = async ( diff --git a/frontend/src/components/secret-rotations-v2/ViewSecretRotationV2GeneratedCredentials/ViewSecretRotationV2GeneratedCredentials.tsx b/frontend/src/components/secret-rotations-v2/ViewSecretRotationV2GeneratedCredentials/ViewSecretRotationV2GeneratedCredentials.tsx index 969c4a049..c81eb9920 100644 --- a/frontend/src/components/secret-rotations-v2/ViewSecretRotationV2GeneratedCredentials/ViewSecretRotationV2GeneratedCredentials.tsx +++ b/frontend/src/components/secret-rotations-v2/ViewSecretRotationV2GeneratedCredentials/ViewSecretRotationV2GeneratedCredentials.tsx @@ -64,6 +64,7 @@ const Content = ({ secretRotation }: ContentProps) => { case SecretRotation.PostgresCredentials: case SecretRotation.MySqlCredentials: case SecretRotation.MsSqlCredentials: + case SecretRotation.OracleDBCredentials: Component = ( = { [SecretRotation.PostgresCredentials]: SqlCredentialsRotationParametersFields, [SecretRotation.MsSqlCredentials]: SqlCredentialsRotationParametersFields, [SecretRotation.MySqlCredentials]: SqlCredentialsRotationParametersFields, + [SecretRotation.OracleDBCredentials]: SqlCredentialsRotationParametersFields, [SecretRotation.Auth0ClientSecret]: Auth0ClientSecretRotationParametersFields, [SecretRotation.AzureClientSecret]: AzureClientSecretRotationParametersFields, [SecretRotation.LdapPassword]: LdapPasswordRotationParametersFields, diff --git a/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ReviewFields/SecretRotationReviewFields.tsx b/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ReviewFields/SecretRotationReviewFields.tsx index 98367eed3..17cc34f27 100644 --- a/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ReviewFields/SecretRotationReviewFields.tsx +++ b/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2ReviewFields/SecretRotationReviewFields.tsx @@ -16,6 +16,7 @@ const COMPONENT_MAP: Record = { [SecretRotation.PostgresCredentials]: SqlCredentialsRotationReviewFields, [SecretRotation.MsSqlCredentials]: SqlCredentialsRotationReviewFields, [SecretRotation.MySqlCredentials]: SqlCredentialsRotationReviewFields, + [SecretRotation.OracleDBCredentials]: SqlCredentialsRotationReviewFields, [SecretRotation.Auth0ClientSecret]: Auth0ClientSecretRotationReviewFields, [SecretRotation.AzureClientSecret]: AzureClientSecretRotationReviewFields, [SecretRotation.LdapPassword]: LdapPasswordRotationReviewFields, diff --git a/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2SecretsMappingFields/SecretRotationV2SecretsMappingFields.tsx b/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2SecretsMappingFields/SecretRotationV2SecretsMappingFields.tsx index f77dc99e5..428a99161 100644 --- a/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2SecretsMappingFields/SecretRotationV2SecretsMappingFields.tsx +++ b/frontend/src/components/secret-rotations-v2/forms/SecretRotationV2SecretsMappingFields/SecretRotationV2SecretsMappingFields.tsx @@ -13,6 +13,7 @@ const COMPONENT_MAP: Record = { [SecretRotation.PostgresCredentials]: SqlCredentialsRotationSecretsMappingFields, [SecretRotation.MsSqlCredentials]: SqlCredentialsRotationSecretsMappingFields, [SecretRotation.MySqlCredentials]: SqlCredentialsRotationSecretsMappingFields, + [SecretRotation.OracleDBCredentials]: SqlCredentialsRotationSecretsMappingFields, [SecretRotation.Auth0ClientSecret]: Auth0ClientSecretRotationSecretsMappingFields, [SecretRotation.AzureClientSecret]: AzureClientSecretRotationSecretsMappingFields, [SecretRotation.LdapPassword]: LdapPasswordRotationSecretsMappingFields, diff --git a/frontend/src/components/secret-rotations-v2/forms/schemas/index.ts b/frontend/src/components/secret-rotations-v2/forms/schemas/index.ts index 6d6fc64e2..77151bf1e 100644 --- a/frontend/src/components/secret-rotations-v2/forms/schemas/index.ts +++ b/frontend/src/components/secret-rotations-v2/forms/schemas/index.ts @@ -10,6 +10,8 @@ import { PostgresCredentialsRotationSchema } from "@app/components/secret-rotati import { SecretRotation } from "@app/hooks/api/secretRotationsV2"; import { LdapPasswordRotationMethod } from "@app/hooks/api/secretRotationsV2/types/ldap-password-rotation"; +import { OracleDBCredentialsRotationSchema } from "./oracledb-credentials-rotation-schema"; + export const SecretRotationV2FormSchema = (isUpdate: boolean) => z .intersection( @@ -19,6 +21,7 @@ export const SecretRotationV2FormSchema = (isUpdate: boolean) => PostgresCredentialsRotationSchema, MsSqlCredentialsRotationSchema, MySqlCredentialsRotationSchema, + OracleDBCredentialsRotationSchema, LdapPasswordRotationSchema, AwsIamUserSecretRotationSchema ]), diff --git a/frontend/src/components/secret-rotations-v2/forms/schemas/oracledb-credentials-rotation-schema.ts b/frontend/src/components/secret-rotations-v2/forms/schemas/oracledb-credentials-rotation-schema.ts new file mode 100644 index 000000000..98574e0a6 --- /dev/null +++ b/frontend/src/components/secret-rotations-v2/forms/schemas/oracledb-credentials-rotation-schema.ts @@ -0,0 +1,12 @@ +import { z } from "zod"; + +import { BaseSecretRotationSchema } from "@app/components/secret-rotations-v2/forms/schemas/base-secret-rotation-v2-schema"; +import { SqlCredentialsRotationSchema } from "@app/components/secret-rotations-v2/forms/schemas/shared"; +import { SecretRotation } from "@app/hooks/api/secretRotationsV2"; + +export const OracleDBCredentialsRotationSchema = z + .object({ + type: z.literal(SecretRotation.OracleDBCredentials) + }) + .merge(SqlCredentialsRotationSchema) + .merge(BaseSecretRotationSchema); diff --git a/frontend/src/helpers/appConnections.ts b/frontend/src/helpers/appConnections.ts index 54210438a..376a1e814 100644 --- a/frontend/src/helpers/appConnections.ts +++ b/frontend/src/helpers/appConnections.ts @@ -27,6 +27,7 @@ import { MsSqlConnectionMethod, MySqlConnectionMethod, OnePassConnectionMethod, + OracleDBConnectionMethod, PostgresConnectionMethod, TAppConnection, TeamCityConnectionMethod, @@ -67,6 +68,7 @@ export const APP_CONNECTION_MAP: Record< [AppConnection.Postgres]: { name: "PostgreSQL", image: "Postgres.png" }, [AppConnection.MsSql]: { name: "Microsoft SQL Server", image: "MsSql.png" }, [AppConnection.MySql]: { name: "MySQL", image: "MySql.png" }, + [AppConnection.OracleDB]: { name: "OracleDB", image: "Oracle.png" }, [AppConnection.Camunda]: { name: "Camunda", image: "Camunda.png" }, [AppConnection.Windmill]: { name: "Windmill", image: "Windmill.png" }, [AppConnection.Auth0]: { name: "Auth0", image: "Auth0.png", size: 40 }, @@ -106,6 +108,7 @@ export const getAppConnectionMethodDetails = (method: TAppConnection["method"]) case PostgresConnectionMethod.UsernameAndPassword: case MsSqlConnectionMethod.UsernameAndPassword: case MySqlConnectionMethod.UsernameAndPassword: + case OracleDBConnectionMethod.UsernameAndPassword: return { name: "Username & Password", icon: faLock }; case HCVaultConnectionMethod.AccessToken: case TeamCityConnectionMethod.AccessToken: diff --git a/frontend/src/helpers/secretRotationsV2.ts b/frontend/src/helpers/secretRotationsV2.ts index a654a1782..6e484881d 100644 --- a/frontend/src/helpers/secretRotationsV2.ts +++ b/frontend/src/helpers/secretRotationsV2.ts @@ -20,6 +20,11 @@ export const SECRET_ROTATION_MAP: Record< image: "MySql.png", size: 50 }, + [SecretRotation.OracleDBCredentials]: { + name: "OracleDB Credentials", + image: "Oracle.png", + size: 50 + }, [SecretRotation.Auth0ClientSecret]: { name: "Auth0 Client Secret", image: "Auth0.png", @@ -46,6 +51,7 @@ export const SECRET_ROTATION_CONNECTION_MAP: Record = { [SecretRotation.PostgresCredentials]: true, [SecretRotation.MsSqlCredentials]: true, [SecretRotation.MySqlCredentials]: true, + [SecretRotation.OracleDBCredentials]: true, [SecretRotation.Auth0ClientSecret]: false, [SecretRotation.AzureClientSecret]: true, [SecretRotation.LdapPassword]: false, diff --git a/frontend/src/hooks/api/appConnections/enums.ts b/frontend/src/hooks/api/appConnections/enums.ts index 6ed986453..30959ba5a 100644 --- a/frontend/src/hooks/api/appConnections/enums.ts +++ b/frontend/src/hooks/api/appConnections/enums.ts @@ -13,6 +13,7 @@ export enum AppConnection { Postgres = "postgres", MsSql = "mssql", MySql = "mysql", + OracleDB = "oracledb", Camunda = "camunda", Windmill = "windmill", Auth0 = "auth0", diff --git a/frontend/src/hooks/api/appConnections/types/app-options.ts b/frontend/src/hooks/api/appConnections/types/app-options.ts index 9725e1a9c..402843b4d 100644 --- a/frontend/src/hooks/api/appConnections/types/app-options.ts +++ b/frontend/src/hooks/api/appConnections/types/app-options.ts @@ -69,6 +69,10 @@ export type TMySqlConnectionOption = TAppConnectionOptionBase & { app: AppConnection.MySql; }; +export type TOracleDBConnectionOption = TAppConnectionOptionBase & { + app: AppConnection.OracleDB; +}; + export type TCamundaConnectionOption = TAppConnectionOptionBase & { app: AppConnection.Camunda; }; @@ -115,6 +119,7 @@ export type TAppConnectionOption = | TPostgresConnectionOption | TMsSqlConnectionOption | TMySqlConnectionOption + | TOracleDBConnectionOption | TCamundaConnectionOption | TWindmillConnectionOption | TAuth0ConnectionOption @@ -138,6 +143,7 @@ export type TAppConnectionOptionMap = { [AppConnection.Postgres]: TPostgresConnectionOption; [AppConnection.MsSql]: TMsSqlConnectionOption; [AppConnection.MySql]: TMySqlConnectionOption; + [AppConnection.OracleDB]: TOracleDBConnectionOption; [AppConnection.Camunda]: TCamundaConnectionOption; [AppConnection.Windmill]: TWindmillConnectionOption; [AppConnection.Auth0]: TAuth0ConnectionOption; diff --git a/frontend/src/hooks/api/appConnections/types/index.ts b/frontend/src/hooks/api/appConnections/types/index.ts index e88a59bf1..e0c06c9e3 100644 --- a/frontend/src/hooks/api/appConnections/types/index.ts +++ b/frontend/src/hooks/api/appConnections/types/index.ts @@ -17,6 +17,7 @@ import { TLdapConnection } from "./ldap-connection"; import { TMsSqlConnection } from "./mssql-connection"; import { TMySqlConnection } from "./mysql-connection"; import { TOCIConnection } from "./oci-connection"; +import { TOracleDBConnection } from "./oracledb-connection"; import { TPostgresConnection } from "./postgres-connection"; import { TTeamCityConnection } from "./teamcity-connection"; import { TTerraformCloudConnection } from "./terraform-cloud-connection"; @@ -40,6 +41,7 @@ export * from "./ldap-connection"; export * from "./mssql-connection"; export * from "./mysql-connection"; export * from "./oci-connection"; +export * from "./oracledb-connection"; export * from "./postgres-connection"; export * from "./teamcity-connection"; export * from "./terraform-cloud-connection"; @@ -61,6 +63,7 @@ export type TAppConnection = | TPostgresConnection | TMsSqlConnection | TMySqlConnection + | TOracleDBConnection | TCamundaConnection | TWindmillConnection | TAuth0Connection @@ -110,6 +113,7 @@ export type TAppConnectionMap = { [AppConnection.Postgres]: TPostgresConnection; [AppConnection.MsSql]: TMsSqlConnection; [AppConnection.MySql]: TMySqlConnection; + [AppConnection.OracleDB]: TOracleDBConnection; [AppConnection.Camunda]: TCamundaConnection; [AppConnection.Windmill]: TWindmillConnection; [AppConnection.Auth0]: TAuth0Connection; diff --git a/frontend/src/hooks/api/appConnections/types/oracledb-connection.ts b/frontend/src/hooks/api/appConnections/types/oracledb-connection.ts new file mode 100644 index 000000000..ba500ad04 --- /dev/null +++ b/frontend/src/hooks/api/appConnections/types/oracledb-connection.ts @@ -0,0 +1,13 @@ +import { AppConnection } from "@app/hooks/api/appConnections/enums"; +import { TRootAppConnection } from "@app/hooks/api/appConnections/types/root-connection"; + +import { TBaseSqlConnectionCredentials } from "./shared"; + +export enum OracleDBConnectionMethod { + UsernameAndPassword = "username-and-password" +} + +export type TOracleDBConnection = TRootAppConnection & { app: AppConnection.OracleDB } & { + method: OracleDBConnectionMethod.UsernameAndPassword; + credentials: TBaseSqlConnectionCredentials; +}; diff --git a/frontend/src/hooks/api/secretRotationsV2/enums.ts b/frontend/src/hooks/api/secretRotationsV2/enums.ts index 5daab0d9a..bb2765ffd 100644 --- a/frontend/src/hooks/api/secretRotationsV2/enums.ts +++ b/frontend/src/hooks/api/secretRotationsV2/enums.ts @@ -2,6 +2,7 @@ export enum SecretRotation { PostgresCredentials = "postgres-credentials", MsSqlCredentials = "mssql-credentials", MySqlCredentials = "mysql-credentials", + OracleDBCredentials = "oracledb-credentials", Auth0ClientSecret = "auth0-client-secret", AzureClientSecret = "azure-client-secret", LdapPassword = "ldap-password", diff --git a/frontend/src/hooks/api/secretRotationsV2/types/index.ts b/frontend/src/hooks/api/secretRotationsV2/types/index.ts index 6f1a82c68..e4b3b6ee1 100644 --- a/frontend/src/hooks/api/secretRotationsV2/types/index.ts +++ b/frontend/src/hooks/api/secretRotationsV2/types/index.ts @@ -35,11 +35,16 @@ import { TMySqlCredentialsRotation, TMySqlCredentialsRotationGeneratedCredentialsResponse } from "./mysql-credentials-rotation"; +import { + TOracleDBCredentialsRotation, + TOracleDBCredentialsRotationGeneratedCredentialsResponse +} from "./oracledb-credentials-rotation"; export type TSecretRotationV2 = ( | TPostgresCredentialsRotation | TMsSqlCredentialsRotation | TMySqlCredentialsRotation + | TOracleDBCredentialsRotation | TAuth0ClientSecretRotation | TAzureClientSecretRotation | TLdapPasswordRotation @@ -63,6 +68,7 @@ export type TViewSecretRotationGeneratedCredentialsResponse = | TPostgresCredentialsRotationGeneratedCredentialsResponse | TMsSqlCredentialsRotationGeneratedCredentialsResponse | TMySqlCredentialsRotationGeneratedCredentialsResponse + | TOracleDBCredentialsRotationGeneratedCredentialsResponse | TAuth0ClientSecretRotationGeneratedCredentialsResponse | TAzureClientSecretRotationGeneratedCredentialsResponse | TLdapPasswordRotationGeneratedCredentialsResponse @@ -113,6 +119,7 @@ export type TSecretRotationOptionMap = { [SecretRotation.PostgresCredentials]: TSqlCredentialsRotationOption; [SecretRotation.MsSqlCredentials]: TSqlCredentialsRotationOption; [SecretRotation.MySqlCredentials]: TSqlCredentialsRotationOption; + [SecretRotation.OracleDBCredentials]: TSqlCredentialsRotationOption; [SecretRotation.Auth0ClientSecret]: TAuth0ClientSecretRotationOption; [SecretRotation.AzureClientSecret]: TAzureClientSecretRotationOption; [SecretRotation.LdapPassword]: TLdapPasswordRotationOption; @@ -123,6 +130,7 @@ export type TSecretRotationGeneratedCredentialsResponseMap = { [SecretRotation.PostgresCredentials]: TPostgresCredentialsRotationGeneratedCredentialsResponse; [SecretRotation.MsSqlCredentials]: TMsSqlCredentialsRotationGeneratedCredentialsResponse; [SecretRotation.MySqlCredentials]: TMySqlCredentialsRotationGeneratedCredentialsResponse; + [SecretRotation.OracleDBCredentials]: TOracleDBCredentialsRotationGeneratedCredentialsResponse; [SecretRotation.Auth0ClientSecret]: TAuth0ClientSecretRotationGeneratedCredentialsResponse; [SecretRotation.AzureClientSecret]: TAzureClientSecretRotationGeneratedCredentialsResponse; [SecretRotation.LdapPassword]: TLdapPasswordRotationGeneratedCredentialsResponse; diff --git a/frontend/src/hooks/api/secretRotationsV2/types/oracledb-credentials-rotation.ts b/frontend/src/hooks/api/secretRotationsV2/types/oracledb-credentials-rotation.ts new file mode 100644 index 000000000..80b9d7899 --- /dev/null +++ b/frontend/src/hooks/api/secretRotationsV2/types/oracledb-credentials-rotation.ts @@ -0,0 +1,17 @@ +import { SecretRotation } from "@app/hooks/api/secretRotationsV2"; +import { + TSecretRotationV2Base, + TSecretRotationV2GeneratedCredentialsResponseBase, + TSqlCredentialsRotationGeneratedCredentials, + TSqlCredentialsRotationProperties +} from "@app/hooks/api/secretRotationsV2/types/shared"; + +export type TOracleDBCredentialsRotation = TSecretRotationV2Base & { + type: SecretRotation.OracleDBCredentials; +} & TSqlCredentialsRotationProperties; + +export type TOracleDBCredentialsRotationGeneratedCredentialsResponse = + TSecretRotationV2GeneratedCredentialsResponseBase< + SecretRotation.OracleDBCredentials, + TSqlCredentialsRotationGeneratedCredentials + >; diff --git a/frontend/src/hooks/api/secretRotationsV2/types/shared/sql-credentials-rotation.ts b/frontend/src/hooks/api/secretRotationsV2/types/shared/sql-credentials-rotation.ts index 3be6679f0..a24242510 100644 --- a/frontend/src/hooks/api/secretRotationsV2/types/shared/sql-credentials-rotation.ts +++ b/frontend/src/hooks/api/secretRotationsV2/types/shared/sql-credentials-rotation.ts @@ -17,8 +17,13 @@ export type TSqlCredentialsRotationOption = { type: | SecretRotation.PostgresCredentials | SecretRotation.MsSqlCredentials - | SecretRotation.MySqlCredentials; - connection: AppConnection.Postgres | AppConnection.MsSql | AppConnection.MySql; + | SecretRotation.MySqlCredentials + | SecretRotation.OracleDBCredentials; + connection: + | AppConnection.Postgres + | AppConnection.MsSql + | AppConnection.MySql + | AppConnection.OracleDB; template: { secretsMapping: TSqlCredentialsRotationProperties["secretsMapping"]; createUserStatement: string; diff --git a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/AppConnectionForm.tsx b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/AppConnectionForm.tsx index 999d4b884..bb73f3798 100644 --- a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/AppConnectionForm.tsx +++ b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/AppConnectionForm.tsx @@ -26,6 +26,7 @@ import { LdapConnectionForm } from "./LdapConnectionForm"; import { MsSqlConnectionForm } from "./MsSqlConnectionForm"; import { MySqlConnectionForm } from "./MySqlConnectionForm"; import { OCIConnectionForm } from "./OCIConnectionForm"; +import { OracleDBConnectionForm } from "./OracleDBConnectionForm"; import { PostgresConnectionForm } from "./PostgresConnectionForm"; import { TeamCityConnectionForm } from "./TeamCityConnectionForm"; import { TerraformCloudConnectionForm } from "./TerraformCloudConnectionForm"; @@ -95,6 +96,8 @@ const CreateForm = ({ app, onComplete }: CreateFormProps) => { return ; case AppConnection.MySql: return ; + case AppConnection.OracleDB: + return ; case AppConnection.Camunda: return ; case AppConnection.AzureClientSecrets: @@ -175,6 +178,8 @@ const UpdateForm = ({ appConnection, onComplete }: UpdateFormProps) => { return ; case AppConnection.MySql: return ; + case AppConnection.OracleDB: + return ; case AppConnection.Camunda: return ; case AppConnection.AzureClientSecrets: diff --git a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/OracleDBConnectionForm.tsx b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/OracleDBConnectionForm.tsx new file mode 100644 index 000000000..a6cca6a23 --- /dev/null +++ b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/OracleDBConnectionForm.tsx @@ -0,0 +1,155 @@ +import { useState } from "react"; +import { Controller, FormProvider, useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { z } from "zod"; + +import { Button, FormControl, ModalClose, Select, SelectItem } from "@app/components/v2"; +import { APP_CONNECTION_MAP, getAppConnectionMethodDetails } from "@app/helpers/appConnections"; +import { OracleDBConnectionMethod, TOracleDBConnection } from "@app/hooks/api/appConnections"; +import { AppConnection } from "@app/hooks/api/appConnections/enums"; +import { PlatformManagedConfirmationModal } from "@app/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/shared/PlatformManagedConfirmationModal"; + +import { + genericAppConnectionFieldsSchema, + GenericAppConnectionsFields +} from "./GenericAppConnectionFields"; +import { + BaseSqlUsernameAndPasswordConnectionSchema, + PlatformManagedNoticeBanner, + SqlConnectionFields +} from "./shared"; + +type Props = { + appConnection?: TOracleDBConnection; + onSubmit: (formData: FormData) => Promise; +}; + +const rootSchema = genericAppConnectionFieldsSchema.extend({ + app: z.literal(AppConnection.OracleDB), + isPlatformManagedCredentials: z.boolean().optional() +}); + +const formSchema = z.discriminatedUnion("method", [ + rootSchema.extend({ + method: z.literal(OracleDBConnectionMethod.UsernameAndPassword), + credentials: BaseSqlUsernameAndPasswordConnectionSchema + }) +]); + +type FormData = z.infer; + +export const OracleDBConnectionForm = ({ appConnection, onSubmit }: Props) => { + const isUpdate = Boolean(appConnection); + const [showConfirmation, setShowConfirmation] = useState(false); + const [selectedTabIndex, setSelectedTabIndex] = useState(0); + + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: appConnection ?? { + app: AppConnection.OracleDB, + method: OracleDBConnectionMethod.UsernameAndPassword, + credentials: { + host: "", + port: 1521, + database: "FREEPDB1", + username: "", // Typically pdbadmin or ADMIN + password: "", + sslEnabled: true, + sslRejectUnauthorized: true, + sslCertificate: undefined + } + } + }); + + const { + handleSubmit, + control, + formState: { isSubmitting, isDirty } + } = form; + + const isPlatformManagedCredentials = appConnection?.isPlatformManagedCredentials ?? false; + + const confirmSubmit = async (formData: FormData) => { + if (formData.isPlatformManagedCredentials) { + setShowConfirmation(true); + return; + } + + await onSubmit(formData); + }; + + return ( + +
{ + setSelectedTabIndex(0); + handleSubmit(confirmSubmit)(e); + }} + > + {!isUpdate && } + ( + + + + )} + /> + + {isPlatformManagedCredentials ? ( + + ) : ( +
+ + + + +
+ )} + + handleSubmit(onSubmit)()} + onOpenChange={setShowConfirmation} + isOpen={showConfirmation} + /> +
+ ); +};