Skip to content

Commit

Permalink
feat(rbac): display administration nav to authorized users
Browse files Browse the repository at this point in the history
  • Loading branch information
debsmita1 committed Nov 7, 2023
1 parent a68b38d commit a319fba
Show file tree
Hide file tree
Showing 12 changed files with 2,278 additions and 2,190 deletions.
3 changes: 3 additions & 0 deletions packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
"@backstage/plugin-techdocs-module-addons-contrib": "^1.1.1",
"@backstage/plugin-techdocs-react": "^1.1.12",
"@backstage/plugin-user-settings": "^0.7.11",
"@janus-idp/backstage-plugin-rbac": "1.1.1",
"@janus-idp/backstage-plugin-rbac-common": "1.0.1",
"@mui/icons-material": "5.14.11",
"@backstage/theme": "^0.4.3",
"@material-ui/core": "^4.12.4",
"@material-ui/icons": "^4.11.3",
Expand Down
14 changes: 14 additions & 0 deletions packages/app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import { TechDocsAddons } from '@backstage/plugin-techdocs-react';

import { ScalprumProvider } from '@scalprum/react-core';

import { RbacPage } from '@janus-idp/backstage-plugin-rbac';
import { policyEntityReadPermission } from '@janus-idp/backstage-plugin-rbac-common';

import { apis } from './apis';
import { entityPage } from './components/catalog/EntityPage';
import { Root } from './components/Root';
Expand Down Expand Up @@ -66,6 +69,17 @@ export const AppBase = () => {
{searchPage}
</Route>
<Route path="/catalog-graph" element={<CatalogGraphPage />} />
<Route
path="/rbac"
element={
<RequirePermission
permission={policyEntityReadPermission}
resourceRef="policy-entity"
>
<RbacPage />
</RequirePermission>
}
/>
{dynamicRoutes.map(({ Component, path, ...props }) => (
<Route
key={path}
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/components/Root/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import MapIcon from '@material-ui/icons/MyLocation';
import SearchIcon from '@material-ui/icons/Search';
import { ScalprumComponent } from '@scalprum/react-core';

import { Administration } from '@janus-idp/backstage-plugin-rbac';

import LogoFull from './LogoFull';
import LogoIcon from './LogoIcon';

Expand Down Expand Up @@ -77,6 +79,7 @@ export const Root = ({ children }: PropsWithChildren<{}>) => (
</SidebarGroup>
<SidebarSpace />
<SidebarDivider />
<Administration />
<SidebarGroup
label="Settings"
icon={
Expand Down
54 changes: 54 additions & 0 deletions plugins/rbac/src/api/RBACBackendClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import {
ConfigApi,
createApiRef,
IdentityApi,
} from '@backstage/core-plugin-api';

// @public
export type RBACAPI = {
getUserAuthorization: () => Promise<{ status: string }>;
getRoles: () => Promise<any>;
};

export type Options = {
configApi: ConfigApi;
identityApi: IdentityApi;
};

// @public
export const rbacApiRef = createApiRef<RBACAPI>({
id: 'plugin.rbac.service',
});

export class RBACBackendClient implements RBACAPI {
// @ts-ignore
private readonly configApi: ConfigApi;
private readonly identityApi: IdentityApi;

constructor(options: Options) {
this.configApi = options.configApi;
this.identityApi = options.identityApi;
}

async getUserAuthorization() {
const { token: idToken } = await this.identityApi.getCredentials();
const backendUrl = this.configApi.getString('backend.baseUrl');
const jsonResponse = await fetch(`${backendUrl}/api/permission/`, {
headers: {
...(idToken && { Authorization: `Bearer ${idToken}` }),
},
});
return jsonResponse.json();
}

async getRoles() {
const { token: idToken } = await this.identityApi.getCredentials();
const backendUrl = this.configApi.getString('backend.baseUrl');
const jsonResponse = await fetch(`${backendUrl}/api/permission/roles`, {
headers: {
...(idToken && { Authorization: `Bearer ${idToken}` }),
},
});
return jsonResponse.json();
}
}
28 changes: 28 additions & 0 deletions plugins/rbac/src/components/Administration.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import { useAsync } from 'react-use';

import { SidebarItem } from '@backstage/core-components';
import { IconComponent, useApi } from '@backstage/core-plugin-api';

import AdminPanelSettingsOutlinedIcon from '@mui/icons-material/AdminPanelSettingsOutlined';

import { rbacApiRef } from '../api/RBACBackendClient';

export const Administration = () => {
const rbacApi = useApi(rbacApiRef);
const { loading: isUserLoading, value: result } = useAsync(
async () => await rbacApi.getUserAuthorization(),
[],
);

if (!isUserLoading) {
return result?.status === 'Authorized' ? (
<SidebarItem
text="Administration"
to="rbac"
icon={AdminPanelSettingsOutlinedIcon as IconComponent}
/>
) : null;
}
return null;
};
File renamed without changes.
1 change: 0 additions & 1 deletion plugins/rbac/src/components/RbacPage/index.ts

This file was deleted.

2 changes: 2 additions & 0 deletions plugins/rbac/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { RbacPage } from './RbacPage';
export { Administration } from './Administration';
2 changes: 1 addition & 1 deletion plugins/rbac/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { rbacPlugin, RbacPage } from './plugin';
export { rbacPlugin, RbacPage, Administration } from './plugin';
33 changes: 32 additions & 1 deletion plugins/rbac/src/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,52 @@
import {
configApiRef,
createApiFactory,
createComponentExtension,
createPlugin,
createRoutableExtension,
identityApiRef,
} from '@backstage/core-plugin-api';

import { rbacApiRef, RBACBackendClient } from './api/RBACBackendClient';
import { rootRouteRef } from './routes';

export const rbacPlugin = createPlugin({
id: 'rbac',
routes: {
root: rootRouteRef,
},
apis: [
createApiFactory({
api: rbacApiRef,
deps: {
configApi: configApiRef,
identityApi: identityApiRef,
},
factory: ({ configApi, identityApi }) =>
new RBACBackendClient({ configApi, identityApi }),
}),
],
});

/**
* @public
*/
export const RbacPage = rbacPlugin.provide(
createRoutableExtension({
name: 'RbacPage',
component: () => import('./components/RbacPage').then(m => m.RbacPage),
component: () => import('./components').then(m => m.RbacPage),
mountPoint: rootRouteRef,
}),
);

/**
* @public
*/
export const Administration = rbacPlugin.provide(
createComponentExtension({
name: 'Administration',
component: {
lazy: () => import('./components').then(m => m.Administration),
},
}),
);
Loading

0 comments on commit a319fba

Please sign in to comment.