Browse Source

add display assign role name

Mitsuaki Ito 1 year ago
parent
commit
e3dc23e6f3

+ 3 - 2
kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/AccessController.java

@@ -36,7 +36,7 @@ public class AccessController implements AuthorizationApi {
         .map(user -> accessControlService.getRoles()
         .map(user -> accessControlService.getRoles()
             .stream()
             .stream()
             .filter(role -> user.groups().contains(role.getName()))
             .filter(role -> user.groups().contains(role.getName()))
-            .map(role -> mapPermissions(role.getPermissions(), role.getClusters()))
+            .map(role -> mapPermissions(role.getName(), role.getPermissions(), role.getClusters()))
             .flatMap(Collection::stream)
             .flatMap(Collection::stream)
             .collect(Collectors.toList())
             .collect(Collectors.toList())
         )
         )
@@ -57,11 +57,12 @@ public class AccessController implements AuthorizationApi {
         .map(ResponseEntity::ok);
         .map(ResponseEntity::ok);
   }
   }
 
 
-  private List<UserPermissionDTO> mapPermissions(List<Permission> permissions, List<String> clusters) {
+  private List<UserPermissionDTO> mapPermissions(String name, List<Permission> permissions, List<String> clusters) {
     return permissions
     return permissions
         .stream()
         .stream()
         .map(permission -> {
         .map(permission -> {
           UserPermissionDTO dto = new UserPermissionDTO();
           UserPermissionDTO dto = new UserPermissionDTO();
+          dto.setRoleName(name);
           dto.setClusters(clusters);
           dto.setClusters(clusters);
           dto.setResource(ResourceTypeDTO.fromValue(permission.getResource().toString().toUpperCase()));
           dto.setResource(ResourceTypeDTO.fromValue(permission.getResource().toString().toUpperCase()));
           dto.setValue(permission.getValue());
           dto.setValue(permission.getValue());

+ 7 - 0
kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/rbac/Permission.java

@@ -37,11 +37,18 @@ public class Permission {
   Resource resource;
   Resource resource;
   List<String> actions;
   List<String> actions;
 
 
+  String roleName;
+
   @Nullable
   @Nullable
   String value;
   String value;
   @Nullable
   @Nullable
   transient Pattern compiledValuePattern;
   transient Pattern compiledValuePattern;
 
 
+  @SuppressWarnings("unused")
+  public void setRoleName(String roleName) {
+    this.roleName = roleName;
+  }
+
   @SuppressWarnings("unused")
   @SuppressWarnings("unused")
   public void setResource(String resource) {
   public void setResource(String resource) {
     this.resource = Resource.fromString(resource.toUpperCase());
     this.resource = Resource.fromString(resource.toUpperCase());

+ 2 - 0
kafka-ui-contract/src/main/resources/swagger/kafka-ui-api.yaml

@@ -3554,6 +3554,8 @@ components:
     UserPermission:
     UserPermission:
       type: object
       type: object
       properties:
       properties:
+        roleName:
+          type: string
         clusters:
         clusters:
           type: array
           type: array
           items:
           items:

+ 11 - 1
kafka-ui-react-app/src/components/NavBar/UserInfo/UserInfo.styled.ts

@@ -9,8 +9,18 @@ export const Wrapper = styled.div`
     position: relative;
     position: relative;
   }
   }
 `;
 `;
-
 export const Text = styled.div(
 export const Text = styled.div(
+  ({ theme }) => css`
+    color: ${theme.menu.color.normal};
+  `
+);
+export const HeaderText = styled.div(
+  ({ theme }) => css`
+    color: ${theme.menu.titleColor};
+  `
+);
+
+export const LinkText = styled.div(
   ({ theme }) => css`
   ({ theme }) => css`
     color: ${theme.button.primary.invertedColors.normal};
     color: ${theme.button.primary.invertedColors.normal};
   `
   `

+ 33 - 2
kafka-ui-react-app/src/components/NavBar/UserInfo/UserInfo.tsx

@@ -7,18 +7,49 @@ import { useUserInfo } from 'lib/hooks/useUserInfo';
 import * as S from './UserInfo.styled';
 import * as S from './UserInfo.styled';
 
 
 const UserInfo = () => {
 const UserInfo = () => {
-  const { username } = useUserInfo();
+  const { username, roles } = useUserInfo();
+
+  const roleNames = roles
+    ? Array.from(roles.values())
+        .map((value) => {
+          const types = Array.from(value.values()).map((r) => r);
+          const names = new Set(
+            types.map((u) => u.map((a) => a.roleName)).flat()
+          );
+
+          return Array.from(names);
+        })
+        .flat()
+    : [];
 
 
   return username ? (
   return username ? (
     <Dropdown
     <Dropdown
       label={
       label={
         <S.Wrapper>
         <S.Wrapper>
           <UserIcon />
           <UserIcon />
-          <S.Text>{username}</S.Text>
+          <S.LinkText>{username}</S.LinkText>
           <DropdownArrowIcon isOpen={false} />
           <DropdownArrowIcon isOpen={false} />
         </S.Wrapper>
         </S.Wrapper>
       }
       }
     >
     >
+      {roleNames.length > 0 && (
+        <>
+          <DropdownItem>
+            <S.HeaderText>Assigned roles</S.HeaderText>
+          </DropdownItem>
+
+          {roleNames.map((name) => (
+            <DropdownItem key={name}>
+              <S.Text>{name}</S.Text>
+            </DropdownItem>
+          ))}
+
+          <DropdownItem>
+            <hr />
+          </DropdownItem>
+        </>
+      )}
+
       <DropdownItem href={`${window.basePath}/logout`}>
       <DropdownItem href={`${window.basePath}/logout`}>
         <S.LogoutLink>Log out</S.LogoutLink>
         <S.LogoutLink>Log out</S.LogoutLink>
       </DropdownItem>
       </DropdownItem>

+ 23 - 0
kafka-ui-react-app/src/components/NavBar/UserInfo/__tests__/UserInfo.spec.tsx

@@ -59,4 +59,27 @@ describe('UserInfo', () => {
     renderComponent();
     renderComponent();
     expect(screen.queryByRole('listbox')).not.toBeInTheDocument();
     expect(screen.queryByRole('listbox')).not.toBeInTheDocument();
   });
   });
+
+  it('should render the role names with correct data', () => {
+    const map = new Map();
+    map.set(
+      'someCluster',
+      new Map([
+        ['CONFIG', [{ roleName: 'someRole1' }, { roleName: 'someRole2' }]],
+      ])
+    );
+
+    (useUserInfo as jest.Mock).mockImplementation(() => ({
+      username: 'someName',
+      roles: map,
+    }));
+
+    renderComponent();
+
+    expect(screen.getByText('someName')).toBeInTheDocument();
+    expect(screen.getByText('Assigned roles')).toBeInTheDocument();
+    expect(screen.getByText('someRole1')).toBeInTheDocument();
+    expect(screen.getByText('someRole2')).toBeInTheDocument();
+    expect(screen.getByText('Log out')).toBeInTheDocument();
+  });
 });
 });