feat(rbac): Viewer-Rolle durchsetzen — alle Mutations nur für Admins
- middleware.go: RequireAdminForMutations() blockiert POST/PUT/DELETE für Nicht-Admins (GET/HEAD passieren immer durch) - main.go: Middleware in den authed-Gruppe eingehängt — wirkt für alle ~30 Resource-Handler gleichzeitig - api/client.ts: 403 → AntD-Notification "Nur Lesezugriff" statt stiller Fehler - Header: "Nur lesen"-Badge + Tooltip wenn role=viewer - i18n de+en: viewerBadge + viewerHint Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Button, Dropdown, Select, Space } from 'antd'
|
||||
import { GlobalOutlined, LogoutOutlined, MenuOutlined, UserOutlined } from '@ant-design/icons'
|
||||
import { Button, Dropdown, Select, Space, Tag, Tooltip } from 'antd'
|
||||
import { EyeOutlined, GlobalOutlined, LogoutOutlined, MenuOutlined, UserOutlined } from '@ant-design/icons'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
@@ -55,23 +55,32 @@ export default function Header({ pageTitle, onMenuToggle }: HeaderProps) {
|
||||
popupMatchSelectWidth={false}
|
||||
/>
|
||||
{user && (
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: [
|
||||
{
|
||||
key: 'logout',
|
||||
icon: <LogoutOutlined />,
|
||||
label: t('auth.logout'),
|
||||
onClick: onLogout,
|
||||
},
|
||||
],
|
||||
}}
|
||||
placement="bottomRight"
|
||||
>
|
||||
<Button type="text" className="header-user">
|
||||
<Space><UserOutlined />{user.actor}</Space>
|
||||
</Button>
|
||||
</Dropdown>
|
||||
<>
|
||||
{user.role === 'viewer' && (
|
||||
<Tooltip title={t('auth.viewerHint')}>
|
||||
<Tag icon={<EyeOutlined />} color="default" style={{ marginRight: 4 }}>
|
||||
{t('auth.viewerBadge')}
|
||||
</Tag>
|
||||
</Tooltip>
|
||||
)}
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: [
|
||||
{
|
||||
key: 'logout',
|
||||
icon: <LogoutOutlined />,
|
||||
label: t('auth.logout'),
|
||||
onClick: onLogout,
|
||||
},
|
||||
],
|
||||
}}
|
||||
placement="bottomRight"
|
||||
>
|
||||
<Button type="text" className="header-user">
|
||||
<Space><UserOutlined />{user.actor}</Space>
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
Reference in New Issue
Block a user