Gate project override settings to owners and admins
Why: S9 acceptance finding 3 — the project settings modal exposed the host override settings (including the model/key group, masked) to plain project members; the duties data plane was already permission-enforced, but the host settings surface had no gate. Evidence: vitest 34 files / 293 tests pass with the change; tsc reports no errors in the modified file. Ruling per the acceptance plan P1-B: the modal entry stays (granted duty managers need the RDM tabs), while the host override settings group renders only for the project owner or a system admin; RDM tabs keep their own fail-closed gating. Impact: ProjectSettingsModal project tab renders an explanatory empty state for non-privileged viewers; members/duties/matrix tabs unchanged. Refs: S9 acceptance report P1-B
This commit is contained in:
@@ -19,6 +19,11 @@ export function ProjectSettingsModal() {
|
||||
const rdmDocReviewAvailable = useStore(s => s.rdmDocReviewAvailable)
|
||||
const rdmPermMatrixAvailable = useStore(s => s.rdmPermMatrixAvailable)
|
||||
const owner = useStore(s => s.me?.owner)
|
||||
const isAdmin = useStore(s => s.me?.isAdmin ?? false)
|
||||
// P1-B 裁定:宿主覆盖设置(含模型与密钥)仅项目负责人/系统管理员可查看与修改;
|
||||
// RDM 页签(成员/文档职责/项目权限)不在此列——数据面由 RDM 权限自行收敛,
|
||||
// 授权的职责管理者仍可进入。
|
||||
const projectPrivileged = !!project && (project.owner === owner || isAdmin)
|
||||
const [tab, setTab] = useState('project')
|
||||
const [schema, setSchema] = useState<SettingDesc[]>([])
|
||||
const [draft, setDraft] = useState<Record<string, any>>({})
|
||||
@@ -85,6 +90,8 @@ export function ProjectSettingsModal() {
|
||||
</>}
|
||||
{tab !== 'members' && tab !== 'duties' && tab !== 'matrix' && !loaded ? (
|
||||
<EmptyState icon="settings">{error || '加载中…'}</EmptyState>
|
||||
) : tab !== 'members' && tab !== 'duties' && tab !== 'matrix' && !projectPrivileged ? (
|
||||
<EmptyState icon="settings">项目覆盖设置(含模型与密钥)仅项目负责人或系统管理员可查看与修改。</EmptyState>
|
||||
) : tab !== 'members' && tab !== 'duties' && tab !== 'matrix' ? (
|
||||
<>
|
||||
<div className="empty-note" style={{ marginBottom: 10 }}>
|
||||
|
||||
Reference in New Issue
Block a user