feat(c1): permission fields on frontend menu items and page routes + manifest migration for all plugins
Check Cross-Plugin Imports / check (push) Has been cancelled

This commit is contained in:
Agent Zero
2026-08-23 21:59:22 +02:00
parent 8a76bfdba4
commit 5e9be254e2
10 changed files with 36 additions and 17 deletions
+2 -2
View File
@@ -52,10 +52,10 @@ class AIAssistantPlugin(BasePlugin):
], ],
is_core=True, is_core=True,
menu_items=[ menu_items=[
FrontendMenuItem(label_key='nav.aiAssistant', label='KI Assistent', path='/ai-assistant', icon='Bot', order=90), FrontendMenuItem(label_key='nav.aiAssistant', label='KI Assistent', path='/ai-assistant', icon='Bot', order=90, permission='ai:read'),
], ],
page_routes=[ page_routes=[
FrontendPageRoute(path='/ai-assistant', component='@/pages/AIAssistant', protected=True), FrontendPageRoute(path='/ai-assistant', component='@/pages/AIAssistant', protected=True, permission='ai:read'),
], ],
settings_pages=[ settings_pages=[
FrontendSettingsPage(path='ai', label_key='settings.ai', label='AI Settings', component='@/pages/AISettings', icon='Bot', order=60), FrontendSettingsPage(path='ai', label_key='settings.ai', label='AI Settings', component='@/pages/AISettings', icon='Bot', order=60),
@@ -82,6 +82,7 @@ class AutomationPlugin(BasePlugin):
path="/workflows", path="/workflows",
icon="Workflow", icon="Workflow",
order=52, order=52,
permission="automation:read",
), ),
FrontendMenuItem( FrontendMenuItem(
label_key="nav.importExport", label_key="nav.importExport",
@@ -89,6 +90,7 @@ class AutomationPlugin(BasePlugin):
path="/import-export", path="/import-export",
icon="ArrowUpDown", icon="ArrowUpDown",
order=53, order=53,
permission="import_export:read",
), ),
FrontendMenuItem( FrontendMenuItem(
label_key="nav.dedupMerge", label_key="nav.dedupMerge",
@@ -96,6 +98,7 @@ class AutomationPlugin(BasePlugin):
path="/contacts/dedup", path="/contacts/dedup",
icon="Copy", icon="Copy",
order=54, order=54,
permission="contacts:read",
), ),
FrontendMenuItem( FrontendMenuItem(
label_key="nav.tags", label_key="nav.tags",
@@ -103,6 +106,7 @@ class AutomationPlugin(BasePlugin):
path="/tags", path="/tags",
icon="Tag", icon="Tag",
order=55, order=55,
permission="tags:read",
), ),
FrontendMenuItem( FrontendMenuItem(
label_key="nav.activity", label_key="nav.activity",
@@ -110,6 +114,7 @@ class AutomationPlugin(BasePlugin):
path="/activity", path="/activity",
icon="Activity", icon="Activity",
order=56, order=56,
permission="contacts:read",
), ),
], ],
page_routes=[ page_routes=[
@@ -117,21 +122,25 @@ class AutomationPlugin(BasePlugin):
path="/automation", path="/automation",
component="@/pages/AutomationDashboard", component="@/pages/AutomationDashboard",
order=50, order=50,
permission="automation:read",
), ),
FrontendPageRoute( FrontendPageRoute(
path="/agents", path="/agents",
component="@/pages/AgentDashboard", component="@/pages/AgentDashboard",
order=51, order=51,
permission="agents:read",
), ),
FrontendPageRoute( FrontendPageRoute(
path="/workflows", path="/workflows",
component="@/pages/Workflows", component="@/pages/Workflows",
order=52, order=52,
permission="automation:read",
), ),
FrontendPageRoute( FrontendPageRoute(
path="/import-export", path="/import-export",
component="@/pages/ImportExport", component="@/pages/ImportExport",
order=53, order=53,
permission="import_export:read",
), ),
], ],
settings_pages=[ settings_pages=[
+2 -2
View File
@@ -48,10 +48,10 @@ class CalendarPlugin(BasePlugin):
"calendar:admin", "calendar:admin",
], ],
menu_items=[ menu_items=[
FrontendMenuItem(label_key='nav.calendar', label='Kalender', path='/calendar', icon='Calendar', order=20), FrontendMenuItem(label_key='nav.calendar', label='Kalender', path='/calendar', icon='Calendar', order=20, permission='calendar:read'),
], ],
page_routes=[ page_routes=[
FrontendPageRoute(path='/calendar', component='@/pages/Calendar', protected=True), FrontendPageRoute(path='/calendar', component='@/pages/Calendar', protected=True, permission='calendar:read'),
], ],
detail_tabs=[ detail_tabs=[
FrontendDetailTab(entity_type='contact', label_key='tabs.calendar', label='Calendar', component='@/components/contact/ContactCalendarTab', icon='Calendar', order=30, permission='calendar:read'), FrontendDetailTab(entity_type='contact', label_key='tabs.calendar', label='Calendar', component='@/components/contact/ContactCalendarTab', icon='Calendar', order=30, permission='calendar:read'),
+4 -4
View File
@@ -38,12 +38,12 @@ class DmsPlugin(BasePlugin):
"dms:admin", "dms:admin",
], ],
menu_items=[ menu_items=[
FrontendMenuItem(label_key='nav.dms', label='Dateien', path='/dms', icon='FolderOpen', group='Dateien', order=40), FrontendMenuItem(label_key='nav.dms', label='Dateien', path='/dms', icon='FolderOpen', group='Dateien', order=40, permission='dms:read'),
FrontendMenuItem(label_key='nav.dms.trash', label='Papierkorb', path='/dms/trash', icon='Trash2', group='Dateien', order=41), FrontendMenuItem(label_key='nav.dms.trash', label='Papierkorb', path='/dms/trash', icon='Trash2', group='Dateien', order=41, permission='dms:read'),
], ],
page_routes=[ page_routes=[
FrontendPageRoute(path='/dms', component='@/pages/Dms', protected=True), FrontendPageRoute(path='/dms', component='@/pages/Dms', protected=True, permission='dms:read'),
FrontendPageRoute(path='/dms/trash', component='@/pages/DmsTrash', protected=True), FrontendPageRoute(path='/dms/trash', component='@/pages/DmsTrash', protected=True, permission='dms:read'),
], ],
detail_tabs=[ detail_tabs=[
FrontendDetailTab(entity_type='contact', label_key='tabs.files', label='Dateien', component='@/components/contact/ContactFilesTab', icon='FolderOpen', order=40, permission='dms:read'), FrontendDetailTab(entity_type='contact', label_key='tabs.files', label='Dateien', component='@/components/contact/ContactFilesTab', icon='FolderOpen', order=40, permission='dms:read'),
+2 -2
View File
@@ -50,10 +50,10 @@ class KommunikationPlugin(BasePlugin):
], ],
is_core=True, is_core=True,
menu_items=[ menu_items=[
FrontendMenuItem(label_key='nav.communication', label='Kommunikation', path='/communication', icon='MessageSquare', order=80), FrontendMenuItem(label_key='nav.communication', label='Kommunikation', path='/communication', icon='MessageSquare', order=80, permission='comm:read'),
], ],
page_routes=[ page_routes=[
FrontendPageRoute(path='/communication', component='@/pages/Communication', protected=True), FrontendPageRoute(path='/communication', component='@/pages/Communication', protected=True, permission='comm:read'),
], ],
author="LeoCRM Team", author="LeoCRM Team",
min_app_version="1.0.0", min_app_version="1.0.0",
+3 -3
View File
@@ -141,11 +141,11 @@ class MailPlugin(BasePlugin):
migrations=["0001_initial.sql", "0006_flag_type.sql", "0007_sync_queue.sql", "0008_sync_queue_deleted_at.sql", "0009_remove_mail_soft_delete.sql", "0010_add_deleted_at.sql"], migrations=["0001_initial.sql", "0006_flag_type.sql", "0007_sync_queue.sql", "0008_sync_queue_deleted_at.sql", "0009_remove_mail_soft_delete.sql", "0010_add_deleted_at.sql"],
permissions=["mail:read", "mail:send", "mail:config", "mail:share", "mail:write", "mail:delete"], permissions=["mail:read", "mail:send", "mail:config", "mail:share", "mail:write", "mail:delete"],
menu_items=[ menu_items=[
FrontendMenuItem(label_key='nav.mail', label='E-Mail', path='/mail', icon='Mail', order=30), FrontendMenuItem(label_key='nav.mail', label='E-Mail', path='/mail', icon='Mail', order=30, permission='mail:read'),
], ],
page_routes=[ page_routes=[
FrontendPageRoute(path='/mail', component='@/pages/Mail', protected=True), FrontendPageRoute(path='/mail', component='@/pages/Mail', protected=True, permission='mail:read'),
FrontendPageRoute(path='/mail/settings', component='@/pages/MailSettings', protected=True), FrontendPageRoute(path='/mail/settings', component='@/pages/MailSettings', protected=True, permission='mail:config'),
], ],
settings_pages=[ settings_pages=[
FrontendSettingsPage(path='mail', label_key='settings.mail', label='Mail', component='@/pages/MailSettings', icon='Mail', order=50), FrontendSettingsPage(path='mail', label_key='settings.mail', label='Mail', component='@/pages/MailSettings', icon='Mail', order=50),
@@ -27,10 +27,10 @@ class ReportGeneratorPlugin(BasePlugin):
migrations=["0001_initial.sql", "0002_reports_folder_id.sql"], migrations=["0001_initial.sql", "0002_reports_folder_id.sql"],
permissions=["reports:read", "reports:generate", "reports:manage_templates"], permissions=["reports:read", "reports:generate", "reports:manage_templates"],
menu_items=[ menu_items=[
FrontendMenuItem(label_key='nav.reports', label='Berichte', path='/reports', icon='BarChart3', order=70), FrontendMenuItem(label_key='nav.reports', label='Berichte', path='/reports', icon='BarChart3', order=70, permission='reports:read'),
], ],
page_routes=[ page_routes=[
FrontendPageRoute(path='/reports', component='@/pages/Reports', protected=True), FrontendPageRoute(path='/reports', component='@/pages/Reports', protected=True, permission='reports:read'),
], ],
author="LeoCRM Team", author="LeoCRM Team",
+2
View File
@@ -43,6 +43,7 @@ class TasksPlugin(BasePlugin):
path="/tasks", path="/tasks",
icon="CheckSquare", icon="CheckSquare",
order=30, order=30,
permission="tasks:read",
), ),
], ],
page_routes=[ page_routes=[
@@ -51,6 +52,7 @@ class TasksPlugin(BasePlugin):
component="@/pages/Tasks", component="@/pages/Tasks",
protected=True, protected=True,
order=30, order=30,
permission="tasks:read",
), ),
], ],
cron_jobs=[ cron_jobs=[
+2 -2
View File
@@ -18,8 +18,8 @@ class WikiPlugin(BasePlugin):
PluginRouteDef(path="/api/v1/wiki", module="app.plugins.builtins.wiki.routes", router_attr="router"), PluginRouteDef(path="/api/v1/wiki", module="app.plugins.builtins.wiki.routes", router_attr="router"),
], ],
permissions=["wiki:read", "wiki:write", "wiki:delete", "wiki:admin"], permissions=["wiki:read", "wiki:write", "wiki:delete", "wiki:admin"],
menu_items=[FrontendMenuItem(label_key="wiki.menu.wiki", label="Wiki", path="/wiki", icon="BookOpen")], menu_items=[FrontendMenuItem(label_key="wiki.menu.wiki", label="Wiki", path="/wiki", icon="BookOpen", permission="wiki:read")],
page_routes=[FrontendPageRoute(path="/wiki", component="@/pages/Wiki")], page_routes=[FrontendPageRoute(path="/wiki", component="@/pages/Wiki", permission="wiki:read")],
) )
async def on_activate(self, db, service_container, event_bus) -> None: async def on_activate(self, db, service_container, event_bus) -> None:
+8
View File
@@ -43,6 +43,10 @@ class FrontendMenuItem(BaseModel):
group: str = Field(default="", description="Optional group label_key for tree-style nesting") group: str = Field(default="", description="Optional group label_key for tree-style nesting")
order: int = Field(default=100, description="Sort order within the sidebar") order: int = Field(default=100, description="Sort order within the sidebar")
badge_key: str = Field(default="", description="Optional store key for badge count") badge_key: str = Field(default="", description="Optional store key for badge count")
permission: str = Field(
default="",
description="Permission required to see/use this item (empty = any authenticated user)",
)
class FrontendPageRoute(BaseModel): class FrontendPageRoute(BaseModel):
@@ -58,6 +62,10 @@ class FrontendPageRoute(BaseModel):
) )
protected: bool = Field(default=True, description="Whether the route requires authentication") protected: bool = Field(default=True, description="Whether the route requires authentication")
order: int = Field(default=100, description="Sort order") order: int = Field(default=100, description="Sort order")
permission: str = Field(
default="",
description="Permission required to access this route (empty = any authenticated user)",
)
class FrontendDetailTab(BaseModel): class FrontendDetailTab(BaseModel):