From 504ae524401ddd2574ffa942d5665422f252bc52 Mon Sep 17 00:00:00 2001 From: williambza Date: Wed, 17 Jun 2026 11:21:40 +0200 Subject: [PATCH 01/13] Show user permissions if available --- .../configuration/UserPermissions.vue | 124 ++++++++++++++++++ src/Frontend/src/resources/RootUrls.ts | 2 + src/Frontend/src/router/config.ts | 5 + src/Frontend/src/router/routeLinks.ts | 1 + .../src/stores/EnvironmentAndVersionsStore.ts | 2 + .../src/stores/UserPermissionsStore.ts | 50 +++++++ src/Frontend/src/views/ConfigurationView.vue | 15 +++ 7 files changed, 199 insertions(+) create mode 100644 src/Frontend/src/components/configuration/UserPermissions.vue create mode 100644 src/Frontend/src/stores/UserPermissionsStore.ts diff --git a/src/Frontend/src/components/configuration/UserPermissions.vue b/src/Frontend/src/components/configuration/UserPermissions.vue new file mode 100644 index 0000000000..11b542a712 --- /dev/null +++ b/src/Frontend/src/components/configuration/UserPermissions.vue @@ -0,0 +1,124 @@ + + + + + diff --git a/src/Frontend/src/resources/RootUrls.ts b/src/Frontend/src/resources/RootUrls.ts index 5c18ca5c65..7826ba27a2 100644 --- a/src/Frontend/src/resources/RootUrls.ts +++ b/src/Frontend/src/resources/RootUrls.ts @@ -17,4 +17,6 @@ export default interface RootUrls { event_log_items: string; archived_groups_url: string; get_archive_group: string; + mypermissions_all?: string; + mypermissions_summary?: string; } diff --git a/src/Frontend/src/router/config.ts b/src/Frontend/src/router/config.ts index 9e4f579db0..10ed24d8e2 100644 --- a/src/Frontend/src/router/config.ts +++ b/src/Frontend/src/router/config.ts @@ -206,6 +206,11 @@ const config: RouteItem[] = [ path: routeLinks.configuration.endpointConnection.template, component: () => import("@/components/configuration/EndpointConnection.vue"), }, + { + title: "User Permissions", + path: routeLinks.configuration.userPermissions.template, + component: () => import("@/components/configuration/UserPermissions.vue"), + }, { title: "Usage Setup", path: routeLinks.throughput.setup.root, diff --git a/src/Frontend/src/router/routeLinks.ts b/src/Frontend/src/router/routeLinks.ts index 64ee77620c..f2e957c9b4 100644 --- a/src/Frontend/src/router/routeLinks.ts +++ b/src/Frontend/src/router/routeLinks.ts @@ -51,6 +51,7 @@ const configurationLinks = (root: string) => { retryRedirects: createLink("retry-redirects"), connections: createLink("connections"), endpointConnection: createLink("endpoint-connection"), + userPermissions: createLink("user-permissions"), }; }; diff --git a/src/Frontend/src/stores/EnvironmentAndVersionsStore.ts b/src/Frontend/src/stores/EnvironmentAndVersionsStore.ts index 0f15264f93..3e797116cf 100644 --- a/src/Frontend/src/stores/EnvironmentAndVersionsStore.ts +++ b/src/Frontend/src/stores/EnvironmentAndVersionsStore.ts @@ -17,6 +17,7 @@ export const useEnvironmentAndVersionsStore = defineStore("EnvironmentAndVersion is_compatible_with_sc: true, sp_version: window.defaultConfig && window.defaultConfig.version ? window.defaultConfig.version : "1.2.0", supportsArchiveGroups: false, + supportsUserPermissions: false, endpoints_error_url: "", known_endpoints_url: "", endpoints_message_search_url: "", @@ -56,6 +57,7 @@ export const useEnvironmentAndVersionsStore = defineStore("EnvironmentAndVersion const [products, scVer] = await Promise.all([productsResult, scResult, mResult]); if (scVer) { environment.supportsArchiveGroups = !!scVer.archived_groups_url; + environment.supportsUserPermissions = !!scVer.mypermissions_all && !!scVer.mypermissions_summary; environment.is_compatible_with_sc = isSupported(environment.sc_version, environment.minimum_supported_sc_version); environment.endpoints_error_url = scVer && scVer.endpoints_error_url; environment.known_endpoints_url = scVer && scVer.known_endpoints_url; diff --git a/src/Frontend/src/stores/UserPermissionsStore.ts b/src/Frontend/src/stores/UserPermissionsStore.ts new file mode 100644 index 0000000000..fd3c1f41e4 --- /dev/null +++ b/src/Frontend/src/stores/UserPermissionsStore.ts @@ -0,0 +1,50 @@ +import { acceptHMRUpdate, defineStore } from "pinia"; +import { ref } from "vue"; +import serviceControlClient from "@/components/serviceControlClient"; + +interface PermissionsSummary { + failed_messages_read: boolean; + failed_messages_write: boolean; + auditing_read: boolean; + monitoring_read: boolean; + monitoring_write: boolean; + admin_read: boolean; + admin_write: boolean; +} + +interface PermissionsDescriptor { + user: string; + permissions: string[]; +} + +export const useUserPermissionsStore = defineStore("UserPermissionsStore", () => { + const summary = ref(null); + const descriptor = ref(null); + const loading = ref(false); + const error = ref(null); + + async function refresh() { + loading.value = true; + error.value = null; + try { + const [summaryResult, descriptorResult] = await Promise.all([ + serviceControlClient.fetchTypedFromServiceControl("my/permissions"), + serviceControlClient.fetchTypedFromServiceControl("my/permissions/all"), + ]); + summary.value = summaryResult[1]; + descriptor.value = descriptorResult[1]; + } catch { + error.value = "Failed to load user permissions"; + } finally { + loading.value = false; + } + } + + return { summary, descriptor, loading, error, refresh }; +}); + +export type { PermissionsSummary, PermissionsDescriptor }; + +if (import.meta.hot) { + import.meta.hot.accept(acceptHMRUpdate(useUserPermissionsStore, import.meta.hot)); +} diff --git a/src/Frontend/src/views/ConfigurationView.vue b/src/Frontend/src/views/ConfigurationView.vue index ecb4b8e438..8fe60293f2 100644 --- a/src/Frontend/src/views/ConfigurationView.vue +++ b/src/Frontend/src/views/ConfigurationView.vue @@ -11,6 +11,8 @@ import useThroughputStoreAutoRefresh from "@/composables/useThroughputStoreAutoR import useConnectionsAndStatsAutoRefresh from "@/composables/useConnectionsAndStatsAutoRefresh"; import { useRedirectsStore } from "@/stores/RedirectsStore"; import { useLicenseStore } from "@/stores/LicenseStore"; +import { useAuthStore } from "@/stores/AuthStore"; +import { useEnvironmentAndVersionsStore } from "@/stores/EnvironmentAndVersionsStore"; const { store: throughputStore } = useThroughputStoreAutoRefresh(); const { hasErrors } = storeToRefs(throughputStore); @@ -19,6 +21,9 @@ const connectionState = connectionStore.connectionState; const redirectsStore = useRedirectsStore(); const licenseStore = useLicenseStore(); const { licenseStatus } = licenseStore; +const authStore = useAuthStore(); +const environmentStore = useEnvironmentAndVersionsStore(); +const { environment } = storeToRefs(environmentStore); onMounted(async () => { if (notConnected.value) { @@ -96,6 +101,16 @@ function preventIfDisabled(e: Event) { + From 9d1aa0681961ed432ca104e0ad7214ed135dd7f9 Mon Sep 17 00:00:00 2001 From: williambza Date: Fri, 19 Jun 2026 10:20:04 +0200 Subject: [PATCH 02/13] Only show permissions tab if auth is enabled --- src/Frontend/src/App.vue | 14 ++++++++++- src/Frontend/src/components/PageHeader.vue | 25 ++++++++++++++------ src/Frontend/src/views/ConfigurationView.vue | 20 +++++++++------- 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/Frontend/src/App.vue b/src/Frontend/src/App.vue index de55293cb5..20ce9d5768 100644 --- a/src/Frontend/src/App.vue +++ b/src/Frontend/src/App.vue @@ -1,5 +1,5 @@