mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-09 00:40:45 +08:00
Block workspace directory picker unless super_admin.
Anonymous and normal users no longer open the OS folder dialog from the empty chat hero; only super_admin can pick/create directories. Host gates directoryPicker.pick/list/createDirectory and the client cancels directoryFlow when canCreateWorkspace is false. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
2cf253f6aa
commit
2072c10338
2 changed files with 102 additions and 12 deletions
|
|
@ -835,11 +835,30 @@ window.__ModuleLoader__.load({
|
|||
const origCall = rpc.call.bind(rpc)
|
||||
rpc.call = async function udsAuthRpcCall(channel, endpoint, payload, signal) {
|
||||
const result = await origCall(channel, endpoint, payload, signal)
|
||||
if (getEmpNo()) return result
|
||||
if (channel !== '/api') return result
|
||||
if (endpoint === 'session/list') return { ok: true, value: { items: [] } }
|
||||
if (endpoint === 'session/search') return { ok: true, value: { items: [], hasMore: false } }
|
||||
return result
|
||||
if (!getEmpNo()) {
|
||||
if (channel === '/api') {
|
||||
if (endpoint === 'session/list') return { ok: true, value: { items: [] } }
|
||||
if (endpoint === 'session/search') return { ok: true, value: { items: [], hasMore: false } }
|
||||
}
|
||||
}
|
||||
if (
|
||||
channel === '/api'
|
||||
&& (
|
||||
endpoint === 'directoryPicker/pick'
|
||||
|| endpoint === 'directoryPicker/list'
|
||||
|| endpoint === 'directoryPicker/createDirectory'
|
||||
)
|
||||
&& document.documentElement.getAttribute('data-uds-can-create-ws') !== '1'
|
||||
) {
|
||||
return {
|
||||
ok: false,
|
||||
error: {
|
||||
code: 'gateway/forbidden',
|
||||
message: getEmpNo() ? '只有超级管理员可以创建工作区' : '登录后才能使用工作区',
|
||||
},
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -882,6 +901,57 @@ window.__ModuleLoader__.load({
|
|||
}
|
||||
}, 'uds-auth: session-list-gate')
|
||||
|
||||
|
||||
ctx.effect(() => {
|
||||
let disposers = []
|
||||
const Gate = function UdsAuthDirectoryFlowGate(props) {
|
||||
React.useEffect(() => {
|
||||
if (props && props.open) {
|
||||
try { props.onCancel && props.onCancel() } catch { /* ignore */ }
|
||||
}
|
||||
}, [props && props.open])
|
||||
return null
|
||||
}
|
||||
const sync = async () => {
|
||||
let canCreate = false
|
||||
try {
|
||||
const me = await fetchJson('/uds-auth/api/me')
|
||||
canCreate = !!(me && me.data && me.data.permissions && me.data.permissions.canCreateWorkspace)
|
||||
} catch { canCreate = false }
|
||||
for (const d of disposers) {
|
||||
try { d() } catch { /* ignore */ }
|
||||
}
|
||||
disposers = []
|
||||
if (canCreate) return
|
||||
for (const slotName of [
|
||||
'sidebar.workspaces.directoryFlow',
|
||||
'conversation.hero.workspace.directoryFlow',
|
||||
]) {
|
||||
try {
|
||||
disposers.push(ctx.slots.register({
|
||||
name: slotName,
|
||||
id: 'uds-auth-dir-gate',
|
||||
order: 9999,
|
||||
}, Gate))
|
||||
} catch { /* slot may be undeclared briefly */ }
|
||||
}
|
||||
}
|
||||
sync()
|
||||
const timer = setInterval(sync, 15000)
|
||||
const onFocus = () => { sync() }
|
||||
const onAuth = () => { sync() }
|
||||
window.addEventListener('focus', onFocus)
|
||||
window.addEventListener('uds-auth-changed', onAuth)
|
||||
return () => {
|
||||
clearInterval(timer)
|
||||
window.removeEventListener('focus', onFocus)
|
||||
window.removeEventListener('uds-auth-changed', onAuth)
|
||||
for (const d of disposers) {
|
||||
try { d() } catch { /* ignore */ }
|
||||
}
|
||||
}
|
||||
}, 'uds-auth: directory-flow-gate')
|
||||
|
||||
// sidebar.footer.action; layout effect lays footArea as one row: Settings | UDS login
|
||||
ctx.slots.inject('sidebar.footer.action', () => ctx.slots.register({
|
||||
name: 'sidebar.footer.action',
|
||||
|
|
|
|||
|
|
@ -380,19 +380,39 @@ export function installDshAcl(ctx, {
|
|||
}
|
||||
})
|
||||
|
||||
// directory picker: block createDirectory for non-super
|
||||
// directory picker: only super_admin may pick/create dirs (others get auto workspaces)
|
||||
ctx.inject(['directoryPicker'], (dctx) => {
|
||||
const dp = dctx.directoryPicker
|
||||
if (!dp || dp.__udsAcl) return
|
||||
dp.__udsAcl = true
|
||||
|
||||
const assertCanCreateWorkspace = () => {
|
||||
const identity = getUserContext()
|
||||
if (!identity?.empNo) throwForbidden('登录后才能使用工作区')
|
||||
if (!identity?.permissions?.canCreateWorkspace) {
|
||||
throwForbidden('只有超级管理员可以创建工作区')
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof dp.pick === 'function') {
|
||||
const origPick = dp.pick.bind(dp)
|
||||
dp.pick = async (...args) => {
|
||||
assertCanCreateWorkspace()
|
||||
return origPick(...args)
|
||||
}
|
||||
}
|
||||
if (typeof dp.list === 'function') {
|
||||
const origList = dp.list.bind(dp)
|
||||
dp.list = async (...args) => {
|
||||
assertCanCreateWorkspace()
|
||||
return origList(...args)
|
||||
}
|
||||
}
|
||||
if (typeof dp.createDirectory === 'function') {
|
||||
const orig = dp.createDirectory.bind(dp)
|
||||
const origCreate = dp.createDirectory.bind(dp)
|
||||
dp.createDirectory = async (...args) => {
|
||||
const identity = getUserContext()
|
||||
if (!identity?.permissions?.canCreateWorkspace) {
|
||||
throwForbidden('只有超级管理员可以创建目录/工作区')
|
||||
}
|
||||
return orig(...args)
|
||||
assertCanCreateWorkspace()
|
||||
return origCreate(...args)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue