Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support PostgreSQL connection with SSL #1243 #1244

Merged
merged 52 commits into from
Mar 14, 2025
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
bbb2e66
docs(disclaimer): remove disclaimer
LinkinStars Jan 13, 2025
5886c1e
build(release): remove DISCLAIMER file from release assets
LinkinStars Jan 13, 2025
0fd7e81
build(ci): update action upload-artifact to v4
LinkinStars Feb 6, 2025
17f8895
front end and backend added for the feature
unical1988 Feb 6, 2025
4680ad4
added visual components and linked to the backend, TODO: testing
unical1988 Feb 7, 2025
90af293
added changeCallback for select component, TODO: testing
unical1988 Feb 7, 2025
2a5710f
fixed select component, TODO: testing
unical1988 Feb 7, 2025
e40e299
checkbox and select are in two seperated form groups, TODO: testing
unical1988 Feb 8, 2025
e058e76
Select now in react bootstrap format, TODO: testing
unical1988 Feb 8, 2025
3948f70
check in checkbox not radio now in react bootstrap, TODO: testing
unical1988 Feb 8, 2025
aaf9bb6
chcked var removed, TODO: testing
unical1988 Feb 8, 2025
8b56599
few other frontend fixes, TODO: testing
unical1988 Feb 8, 2025
ed7b120
few other frontend fixes, TODO: testing
unical1988 Feb 8, 2025
919c87b
few other frontend fixes: select options population error fixed and s…
unical1988 Feb 8, 2025
98b5f80
few other frontend fixes: added three input text fields for the ssl f…
unical1988 Feb 9, 2025
58e6b2a
added postgres files to the backend
unical1988 Feb 9, 2025
59f0496
removed unused files
unical1988 Feb 10, 2025
e302026
added translations for simplified chinese and american languages
unical1988 Feb 10, 2025
f165177
added ssl_mode var to backend
unical1988 Feb 11, 2025
066a0d4
ssl_enabled is boolean
unical1988 Feb 14, 2025
86c270e
ssl_modes include verify-all
unical1988 Feb 14, 2025
5a8118d
small marging for label of ssl checkbox
unical1988 Feb 14, 2025
6ee1cdb
ssl_modes include verify-all 2
unical1988 Feb 14, 2025
550d1d8
checkValidated logic check
unical1988 Feb 19, 2025
61070b1
checkValidated logic check: now working
unical1988 Feb 19, 2025
0a2fd3e
ssl mode name corrected
unical1988 Feb 24, 2025
cab4102
bug of database checked ok
unical1988 Feb 24, 2025
f12bf74
bug of database checked ok
unical1988 Feb 24, 2025
cf3f468
prettier enabled
unical1988 Feb 24, 2025
52b00ef
file paths check bug set
unical1988 Feb 24, 2025
c36b80f
file paths check bug set
unical1988 Feb 24, 2025
e67a45f
file paths check bug set 2
unical1988 Feb 24, 2025
e23d10f
file paths check bug set 2
unical1988 Feb 24, 2025
725c6fd
prettier enabled
unical1988 Feb 24, 2025
286bd4b
SSL file paths fixed
unical1988 Feb 25, 2025
c17a136
SSLMode with certificates, OK
unical1988 Feb 25, 2025
b276c51
config file bug fixed
unical1988 Feb 26, 2025
51156a8
format of second step index and removal of ui compile file
unical1988 Feb 27, 2025
fcb541f
format of install index file
unical1988 Feb 27, 2025
ca94415
Changed Checkbox to Switch
unical1988 Feb 28, 2025
8aa2243
Checksum Logic adjusted to check for certifs only if ssl_enabled is true
unical1988 Feb 28, 2025
082a39e
ErrorMsg displays on validation fail for certif files
unical1988 Feb 28, 2025
5a73a91
ErrorMsg displays on validation fail for certif files (seperate error…
unical1988 Feb 28, 2025
d64d14c
ErrorMsg displays on validation fail for certif files (seperate error…
unical1988 Feb 28, 2025
fbf65dd
added postgres db check for checksum logic
unical1988 Mar 4, 2025
e5778c1
added form label for ssl_enabled
unical1988 Mar 5, 2025
d8ba161
UI exception fixed with 3 form groups instead
unical1988 Mar 5, 2025
e419bbf
re-initialize relevant values after switching ssl_enabled
unical1988 Mar 5, 2025
9cff793
dynamic label for switch button added
unical1988 Mar 6, 2025
55baf9a
dynamic label for switch button added with translations
unical1988 Mar 6, 2025
a6cf7b4
removed className from inner Form.Groups and changed label to ENable SSL
unical1988 Mar 7, 2025
f11ec86
adjusted backend logic with customized messages when certifs not prov…
unical1988 Mar 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-binary-for-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:
args: release --clean --skip=validate
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: answer
path: ./dist/*
2 changes: 0 additions & 2 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ archives:
dst: NOTICE
- src: "docs/release/licenses/*"
dst: licenses/
- src: "DISCLAIMER"
dst: DISCLAIMER
wrap_in_directory: true
checksum:
name_template: 'checksums.txt'
Expand Down
10 changes: 0 additions & 10 deletions DISCLAIMER

This file was deleted.

6 changes: 6 additions & 0 deletions configs/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ data:
connection: "/data/sqlite3/answer.db"
cache:
file_path: "/data/cache/cache.db"
ssl:
enabled: "no"
mode: "require"
cert_file: "/data/cache/ssl/certs/server-ca.pem"
key_file: "/data/cache/ssl/certs/client-cert.pem"
pem_file: "/data/cache/ssl/certs/client-key.pem"
i18n:
bundle_dir: "/data/i18n"
swaggerui:
Expand Down
13 changes: 13 additions & 0 deletions i18n/en_US.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1637,6 +1637,19 @@ ui:
label: Database file
placeholder: /data/answer.db
msg: Database file cannot be empty.
ssl_enabled:
label: SSL On/Off
ssl_mode:
label: SSL Mode
key_file:
placeholder: Key file path
msg: Path to file cannot be empty
cert_file:
placeholder: Cert file path
msg: Path to file cannot be empty
pem_file:
placeholder: Pem file path
msg: Path to file cannot be empty
config_yaml:
title: Create config.yaml
label: The config.yaml file created.
Expand Down
13 changes: 13 additions & 0 deletions i18n/zh_CN.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1603,6 +1603,19 @@ ui:
label: 数据库文件
placeholder: /data/answer.db
msg: 数据库文件不能为空。
ssl_enabled:
label: SSL 开/关
ssl_mode:
label: SSL 模式
key_file:
placeholder: Key 文件路径
msg: 文件路径不能为空
cert_file:
placeholder: Cert 文件路径
msg: 文件路径不能为空
pem_file:
placeholder: Pem 文件路径
msg: 文件路径不能为空
config_yaml:
title: 创建 config.yaml
label: 已创建 config.yaml 文件。
Expand Down
37 changes: 29 additions & 8 deletions internal/install/install_req.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ package install

import (
"fmt"
"log"
"net/url"
"os"
"strings"

"github.com/apache/answer/internal/base/reason"
Expand All @@ -40,12 +42,17 @@ type CheckConfigFileResp struct {

// CheckDatabaseReq check database
type CheckDatabaseReq struct {
DbType string `validate:"required,oneof=postgres sqlite3 mysql" json:"db_type"`
DbUsername string `json:"db_username"`
DbPassword string `json:"db_password"`
DbHost string `json:"db_host"`
DbName string `json:"db_name"`
DbFile string `json:"db_file"`
DbType string `validate:"required,oneof=postgres sqlite3 mysql" json:"db_type"`
DbUsername string `json:"db_username"`
DbPassword string `json:"db_password"`
DbHost string `json:"db_host"`
DbName string `json:"db_name"`
DbFile string `json:"db_file"`
Ssl bool `json:"ssl_enabled"`
SslMode string `json:"ssl_mode"`
SslCrt string `json:"pem_file"`
SslKey string `json:"key_file"`
SslCrtClient string `json:"cert_file"`
}

// GetConnection get connection string
Expand All @@ -59,8 +66,22 @@ func (r *CheckDatabaseReq) GetConnection() string {
}
if r.DbType == string(schemas.POSTGRES) {
host, port := parsePgSQLHostPort(r.DbHost)
return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
host, port, r.DbUsername, r.DbPassword, r.DbName)
if !r.Ssl {
return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
host, port, r.DbUsername, r.DbPassword, r.DbName)
} else if r.SslMode == "require" {
return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
host, port, r.DbUsername, r.DbPassword, r.DbName, r.SslMode)
} else if r.SslMode == "verify-ca" || r.SslMode == "verify-full" {
_, err_server_ca := os.Stat(r.SslCrt)
_, err_client_cert := os.Stat(r.SslKey)
_, err_client_key := os.Stat(r.SslCrtClient)
if err_server_ca == nil || err_client_cert == nil || err_client_key == nil {
return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s sslrootcert=%s sslcert=%s sslkey=%s",
host, port, r.DbUsername, r.DbPassword, r.DbName, r.SslMode, r.SslCrt, r.SslCrtClient, r.SslKey)
}
log.Fatal("Certificate not Found !!")
}
}
return ""
}
Expand Down
3 changes: 2 additions & 1 deletion internal/service/question_common/question.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/apache/answer/internal/service/siteinfo_common"
"math"
"strings"
"time"

"github.com/apache/answer/internal/service/siteinfo_common"

"github.com/apache/answer/internal/base/constant"
"github.com/apache/answer/internal/base/data"
"github.com/apache/answer/internal/base/handler"
Expand Down
168 changes: 163 additions & 5 deletions ui/src/pages/Install/components/SecondStep/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

import { FC, FormEvent } from 'react';
import { Form, Button } from 'react-bootstrap';
import { Form, Button, InputGroup } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';

import Progress from '../Progress';
Expand Down Expand Up @@ -46,13 +46,36 @@ const sqlData = [
},
];

const sslModes = [
{
value: 'require',
},
{
value: 'verify-ca',
},
{
value: 'verify-full',
},
];

const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
const { t } = useTranslation('translation', { keyPrefix: 'install' });

const checkValidated = (): boolean => {
let bol = true;
const { db_type, db_username, db_password, db_host, db_name, db_file } =
data;
const {
db_type,
db_username,
db_password,
db_host,
db_name,
db_file,
ssl_enabled,
ssl_mode,
key_file,
cert_file,
pem_file,
} = data;

if (db_type.value !== 'sqlite3') {
if (!db_username.value) {
Expand Down Expand Up @@ -81,7 +104,47 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
errorMsg: t('db_host.msg'),
};
}

if (!ssl_enabled.value) {
bol = true;
data.ssl_enabled = {
value: false,
isInvalid: true,
errorMsg: t('ssl_enabled.msg'),
};
} else if (!ssl_mode.value) {
bol = true;
data.ssl_mode = {
value: 'require',
isInvalid: true,
errorMsg: '',
};
}
if (ssl_mode.value === 'verify-ca' || ssl_mode.value === 'verify-full') {
if (!key_file.value) {
bol = false;
data.key_file = {
value: '',
isInvalid: true,
errorMsg: t('key_file.msg'),
};
}
if (!pem_file.value) {
bol = false;
data.pem_file = {
value: '',
isInvalid: true,
errorMsg: t('pem_file.msg'),
};
}
if (!cert_file.value) {
bol = false;
data.cert_file = {
value: '',
isInvalid: true,
errorMsg: t('cert_file.msg'),
};
}
}
if (!db_name.value) {
bol = false;
data.db_name = {
Expand Down Expand Up @@ -179,12 +242,107 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => {
});
}}
/>

<Form.Control.Feedback type="invalid">
{data.db_password.errorMsg}
</Form.Control.Feedback>
</Form.Group>
{data.db_type.value === 'postgres' && (
<Form.Group
controlId="ssl_enabled"
className="conditional-checkbox">
<Form.Check type="checkbox" id="sslEnabled">
<Form.Check.Input
value={data.ssl_enabled.value}
type="checkbox"
onChange={(e) => {
changeCallback({
ssl_enabled: {
value: e.target.checked,
isInvalid: false,
errorMsg: '',
},
});
}}
/>
<Form.Label className="ms-1" htmlFor="ssl_enabled">
{t('ssl_enabled.label')}
</Form.Label>
</Form.Check>
</Form.Group>
)}
{data.db_type.value === 'postgres' && data.ssl_enabled.value && (
<Form.Group controlId="sslmodeOptionsDropdown" className="mb-3">
<Form.Label>{t('ssl_mode.label')}</Form.Label>
<Form.Select
value={data.ssl_mode.value}
onChange={(e) => {
changeCallback({
ssl_mode: {
value: e.target.value,
isInvalid: false,
errorMsg: '',
},
});
}}>
{sslModes.map((item) => {
return <option value={item.value}>{item.value}</option>;
})}
</Form.Select>
</Form.Group>
)}
{data.db_type.value === 'postgres' &&
data.ssl_enabled.value &&
(data.ssl_mode.value === 'verify-ca' ||
data.ssl_mode.value === 'verify-full') && (
<InputGroup className="mb-3">
<Form.Control
placeholder={t('key_file.placeholder')}
aria-label="key_file"
aria-describedby="basic-addon1"
// value={data.key_file.value}
onChange={(e) => {
changeCallback({
key_file: {
value: e.target.value,
isInvalid: false,
errorMsg: '',
},
});
}}
/>
<Form.Control
placeholder={t('cert_file.placeholder')}
aria-label="cert_file"
aria-describedby="basic-addon1"
// value={data.cert_file.value}
onChange={(e) => {
changeCallback({
cert_file: {
value: e.target.value,
isInvalid: false,
errorMsg: '',
},
});
}}
/>

<Form.Control
placeholder={t('pem_file.placeholder')}
aria-label="pem_file"
aria-describedby="basic-addon1"
// value={data.pem_file.value }
onChange={(e) => {
changeCallback({
pem_file: {
value: e.target.value,
isInvalid: false,
errorMsg: '',
},
});
}}
/>
</InputGroup>
)}
<Form.Group controlId="db_host" className="mb-3">
<Form.Label>{t('db_host.label')}</Form.Label>
<Form.Control
Expand Down
Loading