Skip to content

Commit 37ec4e6

Browse files
committed
feat: datasource config add aes encrypt
1 parent 15f7a30 commit 37ec4e6

File tree

9 files changed

+104
-32
lines changed

9 files changed

+104
-32
lines changed

backend/apps/datasource/api/datasource.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ def datasource_list(session: SessionDep):
1010
return get_datasource_list(session=session)
1111

1212
@router.post("/check")
13-
def check(session: SessionDep, conf: DatasourceConf):
14-
return check_status(session, conf)
13+
def check(session: SessionDep, ds: CoreDatasource):
14+
return check_status(session, ds)
1515

1616
@router.post("/add", response_model=CoreDatasource)
1717
def add(session: SessionDep, ds: CoreDatasource):

backend/apps/datasource/crud/datasource.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@
33
import pyodbc
44
import datetime
55
from common.core.deps import SessionDep
6+
import json
7+
from ..utils.utils import aes_decrypt
8+
69

710
def get_datasource_list(session: SessionDep) -> CoreDatasource:
811
statement = select(CoreDatasource).order_by(CoreDatasource.create_time.desc())
912
datasource_list = session.exec(statement).fetchall()
1013
return datasource_list
1114

12-
def check_status(session: SessionDep, conf: DatasourceConf):
15+
def check_status(session: SessionDep, ds: CoreDatasource):
16+
conf = DatasourceConf(**json.loads(aes_decrypt(ds.configuration)))
1317
conn_str = (
1418
"DRIVER={MySQL ODBC 9.3 Unicode Driver};" # todo driver config
1519
f"SERVER={conf.host};"
@@ -32,20 +36,20 @@ def check_status(session: SessionDep, conf: DatasourceConf):
3236
conn.close()
3337

3438
def create_ds(session: SessionDep, ds: CoreDatasource):
39+
ds.create_time = datetime.datetime.now()
40+
ds.status = "Success" # todo check status
3541
record = CoreDatasource(**ds.model_dump())
36-
record.create_time = datetime.datetime.now()
37-
record.status = "Success" # todo check status
3842
session.add(record)
3943
session.commit()
40-
return record
44+
return ds
4145

4246
def update_ds(session: SessionDep, ds: CoreDatasource):
4347
ds.id = int(ds.id)
44-
term = session.exec(select(CoreDatasource).where(CoreDatasource.id == ds.id)).first()
48+
record = session.exec(select(CoreDatasource).where(CoreDatasource.id == ds.id)).first()
4549
update_data = ds.model_dump(exclude_unset=True)
4650
for field, value in update_data.items():
47-
setattr(term, field, value)
48-
session.add(term)
51+
setattr(record, field, value)
52+
session.add(record)
4953
session.commit()
5054
return ds
5155

backend/apps/datasource/utils/__init__.py

Whitespace-only changes.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from Crypto.Cipher import AES
2+
from Crypto.Util.Padding import unpad, pad
3+
import base64
4+
5+
key = b'SQLBot1234567890'
6+
7+
def aes_encrypt(data):
8+
data = bytes(data,'utf-8')
9+
cipher = AES.new(key, AES.MODE_ECB)
10+
data = pad(data, AES.block_size)
11+
encrypt = cipher.encrypt(data)
12+
return base64.b64encode(encrypt)
13+
14+
def aes_decrypt(encrypted_data):
15+
encrypted_data = base64.b64decode(encrypted_data)
16+
cipher = AES.new(key, AES.MODE_ECB)
17+
text = cipher.decrypt(encrypted_data)
18+
decrypted_text = unpad(text, AES.block_size)
19+
return decrypted_text.decode('utf-8')

backend/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ dependencies = [
1919
"sentry-sdk[fastapi]<2.0.0,>=1.40.6",
2020
"pyjwt<3.0.0,>=2.8.0",
2121
"pyodbc (>=5.2.0,<5.2.1)",
22+
"pycryptodome (>=3.22.0,<4.0.0)",
2223
]
2324
[[tool.uv.index]]
2425
url = "https://pypi.tuna.tsinghua.edu.cn/simple"

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"@vitejs/plugin-vue": "^5.2.2",
2020
"@vue/tsconfig": "^0.7.0",
2121
"axios": "^1.8.4",
22+
"crypto-js": "^4.2.0",
2223
"element-plus": "^2.9.7",
2324
"less": "^4.3.0",
2425
"pinia": "^3.0.2",

frontend/src/views/ds/form.vue

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,19 @@
2222
</el-select>
2323
</el-form-item>
2424
<el-form-item label="Host/Ip">
25-
<el-input v-model="form.host" />
25+
<el-input v-model="config.host" />
2626
</el-form-item>
2727
<el-form-item label="Port">
28-
<el-input v-model="form.port" />
28+
<el-input v-model="config.port" />
2929
</el-form-item>
3030
<el-form-item label="Username">
31-
<el-input v-model="form.username" />
31+
<el-input v-model="config.username" />
3232
</el-form-item>
3333
<el-form-item label="Password">
34-
<el-input v-model="form.password" />
34+
<el-input v-model="config.password" />
3535
</el-form-item>
3636
<el-form-item label="Database">
37-
<el-input v-model="form.database" />
37+
<el-input v-model="config.database" />
3838
</el-form-item>
3939

4040
<div style="display: flex;justify-content: flex-end;">
@@ -48,6 +48,7 @@
4848
<script lang="ts" setup>
4949
import { ref } from 'vue'
5050
import { datasourceApi } from '@/api/datasource'
51+
import { encrypted, decrypted } from './js/aes'
5152
5253
const emit = defineEmits(['refresh'])
5354
@@ -59,13 +60,15 @@ const form = ref<any>({
5960
name:'',
6061
description:'',
6162
type:'mysql',
63+
configuration: ''
64+
})
65+
const config = ref<any>({
6266
driver:'',
6367
host:'',
6468
port:0,
6569
username:'',
6670
password:'',
6771
database:'',
68-
configuration: ''
6972
})
7073
7174
const close = () => {
@@ -78,24 +81,43 @@ const open = (item: any) => {
7881
form.value.name = item.name
7982
form.value.description = item.description
8083
form.value.type = item.type
81-
const configuration = JSON.parse(item.configuration)
82-
form.value.host = configuration.host
83-
form.value.port = configuration.port
84-
form.value.username = configuration.username
85-
form.value.password = configuration.password
86-
form.value.database = configuration.database
84+
if(item.configuration) {
85+
const configuration = JSON.parse(decrypted(item.configuration))
86+
config.value.host = configuration.host
87+
config.value.port = configuration.port
88+
config.value.username = configuration.username
89+
config.value.password = configuration.password
90+
config.value.database = configuration.database
91+
}
92+
} else {
93+
form.value = {
94+
driver:'',
95+
host:'',
96+
port:0,
97+
username:'',
98+
password:'',
99+
database:'',
100+
}
101+
config.value = {
102+
driver:'',
103+
host:'',
104+
port:0,
105+
username:'',
106+
password:'',
107+
database:'',
108+
}
87109
}
88110
dialogVisible.value = true
89111
}
90112
91113
const save = () => {
92-
form.value.configuration = JSON.stringify({
93-
host:form.value.host,
94-
port:form.value.port,
95-
username:form.value.username,
96-
password:form.value.password,
97-
database:form.value.database
98-
})
114+
form.value.configuration = encrypted(JSON.stringify({
115+
host:config.value.host,
116+
port:config.value.port,
117+
username:config.value.username,
118+
password:config.value.password,
119+
database:config.value.database
120+
}))
99121
if (form.value.id) {
100122
datasourceApi.update(form.value).then((res) => {
101123
console.log(res)
@@ -112,6 +134,13 @@ const save = () => {
112134
}
113135
114136
const check = () => {
137+
form.value.configuration = encrypted(JSON.stringify({
138+
host:config.value.host,
139+
port:config.value.port,
140+
username:config.value.username,
141+
password:config.value.password,
142+
database:config.value.database
143+
}))
115144
datasourceApi.check(form.value).then((res: any) => {
116145
console.log(res)
117146
})
@@ -120,4 +149,4 @@ const check = () => {
120149
defineExpose({ open })
121150
</script>
122151
<style lang="less" scoped>
123-
</style>
152+
</style>./js/aes

frontend/src/views/ds/index.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
</el-input>
1515
</div>
1616

17-
<el-button type="primary" :icon="IconOpeAdd" @click="editDs()">Add Datasource</el-button>
17+
<el-button type="primary" :icon="IconOpeAdd" @click="editDs(undefined)">Add Datasource</el-button>
1818
</div>
1919

2020
<div class="connections-container">
@@ -28,7 +28,7 @@
2828
<div class="connection-details">
2929
<div class="connection-name">{{ ds.name }}</div>
3030
<div class="connection-type">{{ ds.type }}</div>
31-
<div class="connection-host">{{ ds.host }}</div>
31+
<div class="connection-host">{{ ds.description }}</div>
3232
<div class="connection-last">{{ datetimeFormat(ds.create_time) }}</div>
3333
</div>
3434
<div class="connection-status" :class="`${getStatus(ds.status)}`">{{ ds.status }}</div>
@@ -82,7 +82,7 @@ const list = () => {
8282
})
8383
}
8484
85-
const editDs = (item: any = {}) => {
85+
const editDs = (item: any) => {
8686
dsForm.value.open(item)
8787
}
8888

frontend/src/views/ds/js/aes.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import CryptoJS from 'crypto-js'
2+
3+
const key = CryptoJS.enc.Utf8.parse('SQLBot1234567890')
4+
5+
export const encrypted = (str:string) => {
6+
return CryptoJS.AES.encrypt(str, key, {
7+
mode: CryptoJS.mode.ECB,
8+
padding: CryptoJS.pad.Pkcs7
9+
}).toString()
10+
}
11+
12+
export const decrypted = (str:string) => {
13+
const bytes = CryptoJS.AES.decrypt(str, key, {
14+
mode: CryptoJS.mode.ECB,
15+
padding: CryptoJS.pad.Pkcs7
16+
})
17+
return bytes.toString(CryptoJS.enc.Utf8)
18+
}

0 commit comments

Comments
 (0)