From d5baadcb499c121fe954e893dcfa275813432e64 Mon Sep 17 00:00:00 2001 From: disheng Date: Sun, 29 Dec 2024 12:56:13 +0800 Subject: [PATCH 01/13] Added SSL connection info for MySQL --- wren-ui/src/apollo/server/dataSource.ts | 17 +++++++++++-- .../server/repositories/projectRepository.ts | 4 +++ .../setup/dataSources/MySQLProperties.tsx | 25 ++++++++++++++++++- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/wren-ui/src/apollo/server/dataSource.ts b/wren-ui/src/apollo/server/dataSource.ts index 6d2370dce5..3c78f18b33 100644 --- a/wren-ui/src/apollo/server/dataSource.ts +++ b/wren-ui/src/apollo/server/dataSource.ts @@ -119,9 +119,22 @@ const dataSource = { DataSourceName.MYSQL, connectionInfo, ); - const { host, port, database, user, password } = + const { host, port, database, user, password, ssl, ...sslConfig } = decryptedConnectionInfo as MYSQL_CONNECTION_INFO; - return { host, port, database, user, password }; + return { + host, + port, + database, + user, + password, + ...(ssl && { + kwargs: { + ssl_ca: sslConfig.certAuthority, + ssl_key: sslConfig.clientKey, + ssl_cert: sslConfig.clientCert + }, + }), + }; }, } as IDataSourceConnectionInfo< MYSQL_CONNECTION_INFO, diff --git a/wren-ui/src/apollo/server/repositories/projectRepository.ts b/wren-ui/src/apollo/server/repositories/projectRepository.ts index f20d765afd..cbcd1a2b70 100644 --- a/wren-ui/src/apollo/server/repositories/projectRepository.ts +++ b/wren-ui/src/apollo/server/repositories/projectRepository.ts @@ -30,6 +30,10 @@ export interface MYSQL_CONNECTION_INFO { user: string; password: string; database: string; + ssl: boolean; + certAuthority?: string; // SSL cert authority file + clientKey?: string; // SSL client key file + clientCert?: string; // SSL client cert file } export interface MS_SQL_CONNECTION_INFO { diff --git a/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx b/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx index 1669883295..1d6d24a7b6 100644 --- a/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx +++ b/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx @@ -1,4 +1,5 @@ -import { Form, Input } from 'antd'; +import { useState } from 'react'; +import { Form, Input, Switch } from 'antd'; import { ERROR_TEXTS } from '@/utils/error'; import { FORM_MODE } from '@/utils/enum'; import { hostValidator } from '@/utils/validator'; @@ -10,6 +11,7 @@ interface Props { export default function MySQLProperties(props: Props) { const { mode } = props; const isEditMode = mode === FORM_MODE.EDIT; + const [sslActive, setSslActive] = useState(false); return ( <> + + + + + + + + + + + + ); } From e52ba387bf7f58c438ef38f0ac918b29a8666caa Mon Sep 17 00:00:00 2001 From: disheng Date: Tue, 31 Dec 2024 23:22:45 +0800 Subject: [PATCH 02/13] Replaced SSL toggle with selection menu --- .../setup/dataSources/MySQLProperties.tsx | 50 +++++++++++-------- wren-ui/src/components/pages/setup/utils.tsx | 6 +++ 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx b/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx index 1d6d24a7b6..60153e19a6 100644 --- a/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx +++ b/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx @@ -1,8 +1,9 @@ import { useState } from 'react'; -import { Form, Input, Switch } from 'antd'; +import { Form, Input, Select } from 'antd'; import { ERROR_TEXTS } from '@/utils/error'; import { FORM_MODE } from '@/utils/enum'; import { hostValidator } from '@/utils/validator'; +import { SupportedSSLMode } from '../utils'; interface Props { mode?: FORM_MODE; @@ -11,7 +12,8 @@ interface Props { export default function MySQLProperties(props: Props) { const { mode } = props; const isEditMode = mode === FORM_MODE.EDIT; - const [sslActive, setSslActive] = useState(false); + const [sslMode, setSSLMode] = useState(SupportedSSLMode.DISABLE); + const onSSLModeChange = (value: string) => setSSLMode(value) return ( <> - - - - - - - - - - - + + + + } ); } diff --git a/wren-ui/src/components/pages/setup/utils.tsx b/wren-ui/src/components/pages/setup/utils.tsx index 91fd60c831..16aa8adb04 100644 --- a/wren-ui/src/components/pages/setup/utils.tsx +++ b/wren-ui/src/components/pages/setup/utils.tsx @@ -29,6 +29,12 @@ type SetupStep = { maxWidth?: number; }; +export enum SupportedSSLMode { + DISABLE = 'Disable', + REQUIRE = 'Require', + VERIFY_CA = 'Verify CA', +} + export type ButtonOption = { label: string; logo?: string; From bb6c6c40d53ed36103642fbb6379083f721d3913 Mon Sep 17 00:00:00 2001 From: disheng Date: Wed, 1 Jan 2025 16:01:07 +0800 Subject: [PATCH 03/13] Placed ssl mode enum under utils folder --- wren-ui/src/components/pages/setup/utils.tsx | 6 ------ wren-ui/src/utils/enum/index.ts | 1 + wren-ui/src/utils/enum/sslMode.ts | 5 +++++ 3 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 wren-ui/src/utils/enum/sslMode.ts diff --git a/wren-ui/src/components/pages/setup/utils.tsx b/wren-ui/src/components/pages/setup/utils.tsx index 16aa8adb04..91fd60c831 100644 --- a/wren-ui/src/components/pages/setup/utils.tsx +++ b/wren-ui/src/components/pages/setup/utils.tsx @@ -29,12 +29,6 @@ type SetupStep = { maxWidth?: number; }; -export enum SupportedSSLMode { - DISABLE = 'Disable', - REQUIRE = 'Require', - VERIFY_CA = 'Verify CA', -} - export type ButtonOption = { label: string; logo?: string; diff --git a/wren-ui/src/utils/enum/index.ts b/wren-ui/src/utils/enum/index.ts index a6dcc5b9d5..44c0bbdc3a 100644 --- a/wren-ui/src/utils/enum/index.ts +++ b/wren-ui/src/utils/enum/index.ts @@ -7,3 +7,4 @@ export * from './path'; export * from './diagram'; export * from './home'; export * from './settings'; +export * from './sslMode'; diff --git a/wren-ui/src/utils/enum/sslMode.ts b/wren-ui/src/utils/enum/sslMode.ts new file mode 100644 index 0000000000..0a7b678637 --- /dev/null +++ b/wren-ui/src/utils/enum/sslMode.ts @@ -0,0 +1,5 @@ +export enum SUPPORTED_SSL_MODE { + DISABLE = 'Disable', + REQUIRE = 'Require', + VERIFY_CA = 'Verify CA', +} \ No newline at end of file From 9286f321ef45e54f0a817c08c97aecfde168da7f Mon Sep 17 00:00:00 2001 From: disheng Date: Fri, 3 Jan 2025 08:54:11 +0800 Subject: [PATCH 04/13] Added SSL error text --- wren-ui/src/utils/error/dictionary.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wren-ui/src/utils/error/dictionary.ts b/wren-ui/src/utils/error/dictionary.ts index 2eb26293d4..ee70ce30c4 100644 --- a/wren-ui/src/utils/error/dictionary.ts +++ b/wren-ui/src/utils/error/dictionary.ts @@ -49,6 +49,9 @@ export const ERROR_TEXTS = { ACCOUNT: { REQUIRED: 'Please input account.', }, + SSL_CERT: { + REQUIRED: 'Please upload SSL cert file.', + }, }, ADD_RELATION: { FROM_FIELD: { From 5b187310defa6141d46c2f0a8adeca442bd78ba4 Mon Sep 17 00:00:00 2001 From: disheng Date: Fri, 3 Jan 2025 08:54:47 +0800 Subject: [PATCH 05/13] Renamed SSL mode enum --- wren-ui/src/utils/enum/sslMode.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wren-ui/src/utils/enum/sslMode.ts b/wren-ui/src/utils/enum/sslMode.ts index 0a7b678637..cf9f161c7d 100644 --- a/wren-ui/src/utils/enum/sslMode.ts +++ b/wren-ui/src/utils/enum/sslMode.ts @@ -1,4 +1,4 @@ -export enum SUPPORTED_SSL_MODE { +export enum SSL_MODE { DISABLE = 'Disable', REQUIRE = 'Require', VERIFY_CA = 'Verify CA', From ceaaedc116ac13dd72f04abdf610b486d3ccc579 Mon Sep 17 00:00:00 2001 From: disheng Date: Fri, 3 Jan 2025 08:56:01 +0800 Subject: [PATCH 06/13] Implemented first draft for MySQL SSL feature --- wren-ui/src/apollo/server/dataSource.ts | 11 +++----- .../server/repositories/projectRepository.ts | 6 ++--- .../setup/dataSources/MySQLProperties.tsx | 25 +++++++++++-------- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/wren-ui/src/apollo/server/dataSource.ts b/wren-ui/src/apollo/server/dataSource.ts index 3c78f18b33..470b01eab1 100644 --- a/wren-ui/src/apollo/server/dataSource.ts +++ b/wren-ui/src/apollo/server/dataSource.ts @@ -119,7 +119,7 @@ const dataSource = { DataSourceName.MYSQL, connectionInfo, ); - const { host, port, database, user, password, ssl, ...sslConfig } = + const { host, port, database, user, password, ...ssl } = decryptedConnectionInfo as MYSQL_CONNECTION_INFO; return { host, @@ -127,13 +127,8 @@ const dataSource = { database, user, password, - ...(ssl && { - kwargs: { - ssl_ca: sslConfig.certAuthority, - ssl_key: sslConfig.clientKey, - ssl_cert: sslConfig.clientCert - }, - }), + sslMode: ssl.sslMode, + ...(ssl.sslCA && { sslCA: ssl.sslCA }), }; }, } as IDataSourceConnectionInfo< diff --git a/wren-ui/src/apollo/server/repositories/projectRepository.ts b/wren-ui/src/apollo/server/repositories/projectRepository.ts index cbcd1a2b70..8ad15cc095 100644 --- a/wren-ui/src/apollo/server/repositories/projectRepository.ts +++ b/wren-ui/src/apollo/server/repositories/projectRepository.ts @@ -30,10 +30,8 @@ export interface MYSQL_CONNECTION_INFO { user: string; password: string; database: string; - ssl: boolean; - certAuthority?: string; // SSL cert authority file - clientKey?: string; // SSL client key file - clientCert?: string; // SSL client cert file + sslMode: string; + sslCA?: string; } export interface MS_SQL_CONNECTION_INFO { diff --git a/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx b/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx index 60153e19a6..2c3375fe54 100644 --- a/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx +++ b/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx @@ -1,9 +1,8 @@ import { useState } from 'react'; import { Form, Input, Select } from 'antd'; import { ERROR_TEXTS } from '@/utils/error'; -import { FORM_MODE } from '@/utils/enum'; +import { FORM_MODE, SSL_MODE } from '@/utils/enum'; import { hostValidator } from '@/utils/validator'; -import { SupportedSSLMode } from '../utils'; interface Props { mode?: FORM_MODE; @@ -12,7 +11,7 @@ interface Props { export default function MySQLProperties(props: Props) { const { mode } = props; const isEditMode = mode === FORM_MODE.EDIT; - const [sslMode, setSSLMode] = useState(SupportedSSLMode.DISABLE); + const [sslMode, setSSLMode] = useState(SSL_MODE.DISABLE); const onSSLModeChange = (value: string) => setSSLMode(value) return ( <> @@ -93,24 +92,30 @@ export default function MySQLProperties(props: Props) { > - + Date: Fri, 3 Jan 2025 12:34:20 +0800 Subject: [PATCH 07/13] Replaced input field with upload component --- .../setup/dataSources/MySQLProperties.tsx | 65 +++++++++++++++++-- 1 file changed, 58 insertions(+), 7 deletions(-) diff --git a/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx b/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx index 2c3375fe54..23dd860901 100644 --- a/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx +++ b/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx @@ -1,5 +1,7 @@ -import { useState } from 'react'; -import { Form, Input, Select } from 'antd'; +import { useEffect, useState } from 'react'; +import { Form, Input, Select, Button, Upload } from 'antd'; +import UploadOutlined from '@ant-design/icons/UploadOutlined'; +import { UploadFile } from 'antd/lib/upload/interface'; import { ERROR_TEXTS } from '@/utils/error'; import { FORM_MODE, SSL_MODE } from '@/utils/enum'; import { hostValidator } from '@/utils/validator'; @@ -8,6 +10,58 @@ interface Props { mode?: FORM_MODE; } +const UploadSSL = (props) => { + const { onChange, value } = props; + + const [fileList, setFileList] = useState([]); + + useEffect(() => { + if (!value) setFileList([]); + }, [value]); + + const readFileContent = (file: any, callback: (value: string) => void) => { + const reader = new FileReader(); + reader.onloadend = (_e) => { + const result = reader.result; + + if (result) { + const fileContent = String(result); + callback(fileContent); + } + }; + + reader.readAsText(file); + }; + + const onUploadChange = (info) => { + const { file, fileList } = info; + if (fileList.length) { + const uploadFile = fileList[0]; + readFileContent(file.originFileObj, (fileContent: string) => { + onChange && onChange(fileContent); + }); + setFileList([uploadFile]); + } + }; + + const onRemove = () => { + setFileList([]); + onChange && onChange(undefined); + }; + + return ( + + + + ); +}; + export default function MySQLProperties(props: Props) { const { mode } = props; const isEditMode = mode === FORM_MODE.EDIT; @@ -107,7 +161,7 @@ export default function MySQLProperties(props: Props) { { sslMode === SSL_MODE.VERIFY_CA && - + } From 9a78f619c38e5bd601fa3017d0ade51c0531a1a2 Mon Sep 17 00:00:00 2001 From: disheng Date: Fri, 3 Jan 2025 12:36:43 +0800 Subject: [PATCH 08/13] Encode SSL CA with base64 --- wren-ui/src/apollo/server/dataSource.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/wren-ui/src/apollo/server/dataSource.ts b/wren-ui/src/apollo/server/dataSource.ts index 470b01eab1..4d7a2a6dc2 100644 --- a/wren-ui/src/apollo/server/dataSource.ts +++ b/wren-ui/src/apollo/server/dataSource.ts @@ -128,7 +128,11 @@ const dataSource = { user, password, sslMode: ssl.sslMode, - ...(ssl.sslCA && { sslCA: ssl.sslCA }), + ...(ssl.sslCA && { + sslCA: Buffer.from( + ssl.sslCA, + ).toString('base64') + }), }; }, } as IDataSourceConnectionInfo< From 2f5fd8f4f70ff78c97a9ded7040b7b478da82c21 Mon Sep 17 00:00:00 2001 From: disheng Date: Fri, 3 Jan 2025 22:33:27 +0800 Subject: [PATCH 09/13] Modified ibisAdaptor test for MySQL --- .../server/adaptors/tests/ibisAdaptor.test.ts | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/wren-ui/src/apollo/server/adaptors/tests/ibisAdaptor.test.ts b/wren-ui/src/apollo/server/adaptors/tests/ibisAdaptor.test.ts index 5f3d30a6b2..bcd0e7b4ee 100644 --- a/wren-ui/src/apollo/server/adaptors/tests/ibisAdaptor.test.ts +++ b/wren-ui/src/apollo/server/adaptors/tests/ibisAdaptor.test.ts @@ -6,7 +6,7 @@ import { IbisQueryResponse, ValidationRules, } from '../ibisAdaptor'; -import { DataSourceName } from '../../types'; +import { DataSourceName, SSLMode } from '../../types'; import { Manifest } from '../../mdl/type'; import { BIG_QUERY_CONNECTION_INFO, @@ -45,6 +45,8 @@ describe('IbisAdaptor', () => { database: 'my-database', user: 'my-user', password: 'my-password', + sslMode: SSLMode.VERIFY_CA, + sslCA: 'encrypted-certificate-string', }; const mockPostgresConnectionInfo: POSTGRES_CONNECTION_INFO = { @@ -175,17 +177,28 @@ describe('IbisAdaptor', () => { mockedAxios.post.mockResolvedValue(mockResponse); // mock decrypt method in Encryptor to return the same password mockedEncryptor.prototype.decrypt.mockReturnValue( - JSON.stringify({ password: mockMySQLConnectionInfo.password }), + JSON.stringify({ + password: mockMySQLConnectionInfo.password, + ...(mockMySQLConnectionInfo.sslCA && { sslCA: mockMySQLConnectionInfo.sslCA }) + }), ); const result = await ibisAdaptor.getConstraints( DataSourceName.MYSQL, mockMySQLConnectionInfo, ); - const expectConnectionInfo = Object.entries(mockMySQLConnectionInfo).reduce( - (acc, [key, value]) => ((acc[snakeCase(key)] = value), acc), - {}, - ); + const expectConnectionInfo = Object.entries( + mockMySQLConnectionInfo, + ).reduce((acc, [key, value]) => { + if (key === 'sslCA') { + acc['sslCA'] = Buffer + .from(mockMySQLConnectionInfo.sslCA) + .toString('base64'); + } else { + acc[key] = value; + } + return acc; + }, {}); expect(result).toEqual([]); expect(mockedAxios.post).toHaveBeenCalledWith( From 0a816746ad43a59fe5c6a24882650ec03b70f238 Mon Sep 17 00:00:00 2001 From: disheng Date: Fri, 3 Jan 2025 22:34:37 +0800 Subject: [PATCH 10/13] Added sslCA in sensitiveProps --- wren-ui/src/apollo/server/dataSource.ts | 2 +- wren-ui/src/apollo/server/types/index.ts | 1 + wren-ui/src/apollo/server/types/sslMode.ts | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 wren-ui/src/apollo/server/types/sslMode.ts diff --git a/wren-ui/src/apollo/server/dataSource.ts b/wren-ui/src/apollo/server/dataSource.ts index 4d7a2a6dc2..d574789273 100644 --- a/wren-ui/src/apollo/server/dataSource.ts +++ b/wren-ui/src/apollo/server/dataSource.ts @@ -113,7 +113,7 @@ const dataSource = { // mysql [DataSourceName.MYSQL]: { - sensitiveProps: ['password'], + sensitiveProps: ['password', 'sslCA'], toIbisConnectionInfo(connectionInfo) { const decryptedConnectionInfo = decryptConnectionInfo( DataSourceName.MYSQL, diff --git a/wren-ui/src/apollo/server/types/index.ts b/wren-ui/src/apollo/server/types/index.ts index 57569a2b7e..632d1681f5 100644 --- a/wren-ui/src/apollo/server/types/index.ts +++ b/wren-ui/src/apollo/server/types/index.ts @@ -4,3 +4,4 @@ export * from './manifest'; export * from './diagram'; export * from './metric'; export * from './context'; +export * from './sslMode'; diff --git a/wren-ui/src/apollo/server/types/sslMode.ts b/wren-ui/src/apollo/server/types/sslMode.ts new file mode 100644 index 0000000000..a448b99f74 --- /dev/null +++ b/wren-ui/src/apollo/server/types/sslMode.ts @@ -0,0 +1,5 @@ +export enum SSLMode { + DISABLE = 'Disable', + REQUIRE = 'Require', + VERIFY_CA = 'Verify CA', +} From a4a93193986569ec44c24f712de2c368a2d1bf5f Mon Sep 17 00:00:00 2001 From: disheng Date: Fri, 3 Jan 2025 23:56:26 +0800 Subject: [PATCH 11/13] Replaced sslMode type --- wren-ui/src/apollo/server/repositories/projectRepository.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wren-ui/src/apollo/server/repositories/projectRepository.ts b/wren-ui/src/apollo/server/repositories/projectRepository.ts index 8ad15cc095..b261ff7231 100644 --- a/wren-ui/src/apollo/server/repositories/projectRepository.ts +++ b/wren-ui/src/apollo/server/repositories/projectRepository.ts @@ -8,7 +8,7 @@ import { snakeCase, isEmpty, } from 'lodash'; -import { DataSourceName } from '@server/types'; +import { DataSourceName, SSLMode } from '@server/types'; export interface BIG_QUERY_CONNECTION_INFO { projectId: string; @@ -30,7 +30,7 @@ export interface MYSQL_CONNECTION_INFO { user: string; password: string; database: string; - sslMode: string; + sslMode: SSLMode; sslCA?: string; } From 8d1db640eb3db89e9b4019c9f4ffb92f80c71a7d Mon Sep 17 00:00:00 2001 From: disheng Date: Sat, 11 Jan 2025 21:59:17 +0800 Subject: [PATCH 12/13] Modify enum names --- wren-ui/src/apollo/server/types/sslMode.ts | 6 +++--- .../pages/setup/dataSources/MySQLProperties.tsx | 10 +++++----- wren-ui/src/utils/enum/sslMode.ts | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/wren-ui/src/apollo/server/types/sslMode.ts b/wren-ui/src/apollo/server/types/sslMode.ts index a448b99f74..5b78fa34de 100644 --- a/wren-ui/src/apollo/server/types/sslMode.ts +++ b/wren-ui/src/apollo/server/types/sslMode.ts @@ -1,5 +1,5 @@ export enum SSLMode { - DISABLE = 'Disable', - REQUIRE = 'Require', - VERIFY_CA = 'Verify CA', + DISABLED = 'disabled', + ENABLED = 'enabled', + VERIFY_CA = 'verify_ca', } diff --git a/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx b/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx index 23dd860901..bde490d7c7 100644 --- a/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx +++ b/wren-ui/src/components/pages/setup/dataSources/MySQLProperties.tsx @@ -65,7 +65,7 @@ const UploadSSL = (props) => { export default function MySQLProperties(props: Props) { const { mode } = props; const isEditMode = mode === FORM_MODE.EDIT; - const [sslMode, setSSLMode] = useState(SSL_MODE.DISABLE); + const [sslMode, setSSLMode] = useState(SSL_MODE.DISABLED); const onSSLModeChange = (value: string) => setSSLMode(value) return ( <> @@ -146,15 +146,15 @@ export default function MySQLProperties(props: Props) { > - + - +