Skip to content

Commit 5323993

Browse files
perf: Optimize page embedding mechanism
1 parent b8e9da1 commit 5323993

File tree

7 files changed

+104
-36
lines changed

7 files changed

+104
-36
lines changed

backend/apps/system/middleware/auth.py

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from apps.system.models.system_model import AssistantModel
99
from common.core.db import engine
1010
from apps.system.crud.assistant import get_assistant_info, get_assistant_user
11-
from apps.system.crud.user import get_user_info
11+
from apps.system.crud.user import get_user_by_account, get_user_info
1212
from apps.system.schemas.system_schema import AssistantHeader, UserInfoDTO
1313
from common.core import security
1414
from common.core.config import settings
@@ -34,7 +34,7 @@ async def dispatch(self, request, call_next):
3434
trans = await get_i18n(request)
3535
#if assistantToken and assistantToken.lower().startswith("assistant "):
3636
if assistantToken:
37-
validator: tuple[any] = await self.validateAssistant(assistantToken)
37+
validator: tuple[any] = await self.validateAssistant(assistantToken, trans)
3838
if validator[0]:
3939
request.state.current_user = validator[1]
4040
request.state.assistant = validator[2]
@@ -87,14 +87,17 @@ async def validateToken(self, token: Optional[str], trans: I18n):
8787
return False, e
8888

8989

90-
async def validateAssistant(self, assistantToken: Optional[str]) -> tuple[any]:
90+
async def validateAssistant(self, assistantToken: Optional[str], trans: I18n) -> tuple[any]:
9191
if not assistantToken:
9292
return False, f"Miss Token[{settings.TOKEN_KEY}]!"
9393
schema, param = get_authorization_scheme_param(assistantToken)
94-
if schema.lower() != "assistant":
95-
return False, f"Token schema error!"
9694

97-
try:
95+
96+
try:
97+
if schema.lower() == 'embedded':
98+
return await self.validateEmbedded(param, trans)
99+
if schema.lower() != "assistant":
100+
return False, f"Token schema error!"
98101
payload = jwt.decode(
99102
param, settings.SECRET_KEY, algorithms=[security.ALGORITHM]
100103
)
@@ -112,4 +115,45 @@ async def validateAssistant(self, assistantToken: Optional[str]) -> tuple[any]:
112115
except Exception as e:
113116
SQLBotLogUtil.exception(f"Assistant validation error: {str(e)}")
114117
# Return False and the exception message
118+
return False, e
119+
120+
async def validateEmbedded(self, param: str, trans: I18n) -> tuple[any]:
121+
try:
122+
""" payload = jwt.decode(
123+
param, settings.SECRET_KEY, algorithms=[security.ALGORITHM]
124+
) """
125+
payload: dict = jwt.decode(
126+
param,
127+
options={"verify_signature": False, "verify_exp": False},
128+
algorithms=[security.ALGORITHM]
129+
)
130+
if not payload['embeddedId']:
131+
return False, f"Miss embeddedId payload error!"
132+
if not payload['account']:
133+
return False, f"Miss account payload error!"
134+
embeddedId = payload['embeddedId']
135+
account = payload['account']
136+
with Session(engine) as session:
137+
""" session_user = await get_user_info(session = session, user_id = token_data.id)
138+
session_user = UserInfoDTO.model_validate(session_user) """
139+
session_user = get_user_by_account(session = session, account=account)
140+
if not session_user:
141+
message = trans('i18n_not_exist', msg = trans('i18n_user.account'))
142+
raise Exception(message)
143+
session_user = await get_user_info(session = session, user_id = session_user.id)
144+
145+
session_user = UserInfoDTO.model_validate(session_user)
146+
if session_user.status != 1:
147+
message = trans('i18n_login.user_disable', msg = trans('i18n_concat_admin'))
148+
raise Exception(message)
149+
if not session_user.oid or session_user.oid == 0:
150+
message = trans('i18n_login.no_associated_ws', msg = trans('i18n_concat_admin'))
151+
raise Exception(message)
152+
assistant_info = await get_assistant_info(session=session, assistant_id=embeddedId)
153+
assistant_info = AssistantModel.model_validate(assistant_info)
154+
assistant_info = AssistantHeader.model_validate(assistant_info.model_dump(exclude_unset=True))
155+
return True, session_user, assistant_info
156+
except Exception as e:
157+
SQLBotLogUtil.exception(f"Embedded validation error: {str(e)}")
158+
# Return False and the exception message
115159
return False, e

backend/common/utils/whitelist.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@
2727
"/system/config/key",
2828
"/images/*",
2929
"/sse",
30-
"/system/appearance*",
30+
"/system/appearance/ui",
31+
"/system/appearance/picture/*",
3132
"/system/assistant/validator*",
3233
"/system/assistant/info/*",
3334
"/system/assistant/picture/*",
34-
"/system/embedded*",
3535
"/datasource/uploadExcel"
3636
]
3737

backend/pyproject.toml

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,28 +36,21 @@ dependencies = [
3636
"pyyaml (>=6.0.2,<7.0.0)",
3737
"fastapi-mcp (>=0.3.4,<0.4.0)",
3838
"tabulate>=0.9.0",
39-
"sqlbot-xpack>=0.0.3.19,<1.0.0",
4039
"fastapi-cache2>=0.2.2",
4140
"sqlparse>=0.5.3",
4241
"redis>=6.2.0",
4342
"xlsxwriter>=3.2.5",
4443
"python-calamine>=0.4.0",
4544
"xlrd>=2.0.2",
46-
"clickhouse-sqlalchemy>=0.3.2",
47-
"dmpython>=2.5.22",
45+
"sqlbot-xpack",
4846
]
4947
[[tool.uv.index]]
5048
name = "default"
5149
url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"
5250
default = true
5351

54-
[[tool.uv.index]]
55-
name = "testpypi"
56-
url = "https://test.pypi.org/simple"
57-
explicit = true
58-
5952
[tool.uv.sources]
60-
sqlbot-xpack = { index = "testpypi" }
53+
sqlbot-xpack = { path = "../../sqlbot-xpack/dist/sqlbot_xpack-0.0.3.19-cp311-cp311-macosx_11_0_arm64.whl" }
6154

6255
[tool.uv]
6356
dev-dependencies = [

frontend/src/stores/appearance.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ export const useAppearanceStore = defineStore('appearanceStore', {
252252
setLinkIcon()
253253
return
254254
}
255-
const resData = await request.get('/system/appearance')
255+
const resData = await request.get('/system/appearance/ui')
256256
this.loaded = true
257257
if (!resData?.length) {
258258
return

frontend/src/utils/request.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,19 @@ class HttpService {
8080
config.headers['X-SQLBOT-TOKEN'] = `Bearer ${token}`
8181
}
8282
if (assistantStore.getToken) {
83-
config.headers['X-SQLBOT-ASSISTANT-TOKEN'] = `Assistant ${assistantStore.getToken}`
83+
const prefix = assistantStore.getType === 4 ? 'Embedded ' : 'Assistant '
84+
config.headers['X-SQLBOT-ASSISTANT-TOKEN'] = `${prefix}${assistantStore.getToken}`
8485
if (config.headers['X-SQLBOT-TOKEN']) config.headers.delete('X-SQLBOT-TOKEN')
85-
if (assistantStore.getType && assistantStore.getCertificate) {
86+
if (
87+
assistantStore.getType &&
88+
!!(assistantStore.getType % 2) &&
89+
assistantStore.getCertificate
90+
) {
8691
config.headers['X-SQLBOT-ASSISTANT-CERTIFICATE'] = btoa(
8792
encodeURIComponent(assistantStore.getCertificate)
8893
)
8994
}
90-
if (!assistantStore.getType) {
95+
if (!assistantStore.getType || assistantStore.getType === 2) {
9196
config.headers['X-SQLBOT-ASSISTANT-ONLINE'] = assistantStore.getOnline
9297
}
9398
}
@@ -270,15 +275,20 @@ class HttpService {
270275
heads['X-SQLBOT-TOKEN'] = `Bearer ${token}`
271276
}
272277
if (assistantStore.getToken) {
273-
heads['X-SQLBOT-ASSISTANT-TOKEN'] = `Assistant ${assistantStore.getToken}`
278+
const prefix = assistantStore.getType === 4 ? 'Embedded ' : 'Assistant '
279+
heads['X-SQLBOT-ASSISTANT-TOKEN'] = `${prefix}${assistantStore.getToken}`
274280
if (heads['X-SQLBOT-TOKEN']) delete heads['X-SQLBOT-TOKEN']
275-
if (assistantStore.getType && assistantStore.getCertificate) {
281+
if (
282+
assistantStore.getType &&
283+
!!(assistantStore.getType % 2) &&
284+
assistantStore.getCertificate
285+
) {
276286
await assistantStore.refreshCertificate()
277287
heads['X-SQLBOT-ASSISTANT-CERTIFICATE'] = btoa(
278288
encodeURIComponent(assistantStore.getCertificate)
279289
)
280290
}
281-
if (!assistantStore.getType) {
291+
if (!assistantStore.getType || assistantStore.getType === 2) {
282292
heads['X-SQLBOT-ASSISTANT-ONLINE'] = assistantStore.getOnline
283293
}
284294
}

frontend/src/views/embedded/page.vue

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,22 @@ const validator = ref({
2222
token: '',
2323
})
2424
const loading = ref(true)
25-
const eventName = 'sqlbot_assistant_event'
25+
const eventName = 'sqlbot_embedded_event'
2626
const communicationCb = async (event: any) => {
2727
if (event.data?.eventName === eventName) {
2828
if (event.data?.messageId !== route.query.id) {
2929
return
3030
}
3131
if (event.data?.busi == 'certificate') {
32+
const type = parseInt(event.data['type'])
3233
const certificate = event.data['certificate']
33-
assistantStore.setType(1)
34+
assistantStore.setType(type || 3)
35+
if (type === 4) {
36+
assistantStore.setToken(certificate)
37+
assistantStore.setAssistant(true)
38+
loading.value = false
39+
return
40+
}
3441
assistantStore.setCertificate(certificate)
3542
assistantStore.resolveCertificate(certificate)
3643
}
@@ -55,13 +62,29 @@ const setFormatOnline = (text?: any) => {
5562
assistantStore.setOnline(false)
5663
}
5764
65+
const registerReady = (assistantId: any) => {
66+
window.addEventListener('message', communicationCb)
67+
const readyData = {
68+
eventName: 'sqlbot_embedded_event',
69+
busi: 'ready',
70+
ready: true,
71+
messageId: assistantId,
72+
}
73+
window.parent.postMessage(readyData, '*')
74+
}
75+
5876
onBeforeMount(async () => {
59-
debugger
6077
const assistantId = route.query.id
6178
if (!assistantId) {
6279
ElMessage.error('Miss embedded id, please check embedded url')
6380
return
6481
}
82+
const typeParam = route.query.type
83+
let assistantType = 2
84+
if (typeParam) {
85+
assistantType = parseInt(typeParam.toString())
86+
assistantStore.setType(assistantType)
87+
}
6588
const online = route.query.online
6689
setFormatOnline(online)
6790
@@ -72,6 +95,11 @@ onBeforeMount(async () => {
7295
const now = Date.now()
7396
assistantStore.setFlag(now)
7497
assistantStore.setId(assistantId?.toString() || '')
98+
if (assistantType === 4) {
99+
assistantStore.setAssistant(true)
100+
registerReady(assistantId)
101+
return
102+
}
75103
const param = {
76104
id: assistantId,
77105
virtual: assistantStore.getFlag,
@@ -82,14 +110,7 @@ onBeforeMount(async () => {
82110
assistantStore.setAssistant(true)
83111
loading.value = false
84112
85-
window.addEventListener('message', communicationCb)
86-
const readyData = {
87-
eventName: 'sqlbot_embedded_event',
88-
busi: 'ready',
89-
ready: true,
90-
messageId: assistantId,
91-
}
92-
window.parent.postMessage(readyData, '*')
113+
registerReady(assistantId)
93114
})
94115
95116
onBeforeUnmount(() => {

frontend/src/views/system/appearance/index.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ const buildParam = () => {
402402
return formData
403403
}
404404
const init = () => {
405-
const url = '/system/appearance'
405+
const url = '/system/appearance/ui'
406406
changedItemArray.value = []
407407
fileList.value = []
408408
request

0 commit comments

Comments
 (0)