Browse Source

assign user multiple roles when creating user

Signed-off-by: shanghaikid <jiangruiyi@gmail.com>
shanghaikid 1 year ago
parent
commit
7a7a15490f

+ 2 - 2
client/src/http/User.ts

@@ -47,9 +47,9 @@ export class UserHttp extends BaseModel {
     return super.delete({ path: `${this.USER_URL}/roles/${data.roleName}` });
   }
 
-  static assignUserRole(data: AssignRoleParams) {
+  static updateUserRole(data: AssignRoleParams) {
     return super.update({
-      path: `${this.USER_URL}/${data.username}/role/assign`,
+      path: `${this.USER_URL}/${data.username}/role/update`,
       data,
     });
   }

+ 2 - 1
client/src/i18n/en/user.ts

@@ -10,9 +10,10 @@ const userTrans = {
   update: 'Update password',
   isNotSame: 'Not same as new password',
   deleteTip:
-    'Please select at least one item to drop and root can not be dropped.',
+    'Please select at least one item to drop and the root user can not be dropped.',
 
   role: 'Role',
+  editRole:'Edit Role',
   roles: 'Roles',
   createRoleTitle: 'Create Role',
 };

+ 6 - 1
client/src/pages/user/CreateUser.tsx

@@ -4,6 +4,7 @@ import {
   Checkbox,
   FormGroup,
   FormControlLabel,
+  Typography,
 } from '@material-ui/core';
 import { FC, useMemo, useState } from 'react';
 import { useTranslation } from 'react-i18next';
@@ -16,7 +17,7 @@ import { CreateUserProps, CreateUserParams } from './Types';
 
 const useStyles = makeStyles((theme: Theme) => ({
   input: {
-    margin: theme.spacing(3, 0, 0.5),
+    margin: theme.spacing(2, 0, 0.5),
   },
   dialogWrapper: {
     maxWidth: theme.spacing(70),
@@ -120,6 +121,10 @@ const CreateUser: FC<CreateUserProps> = ({
           />
         ))}
 
+        <Typography variant="h5" component="span">
+          {userTrans('roles')}
+        </Typography>
+
         <FormGroup row>
           {roles.map((r: any, index: number) => (
             <FormControlLabel

+ 1 - 1
client/src/pages/user/Types.ts

@@ -48,7 +48,7 @@ export interface DeleteRoleParams {
 
 export interface AssignRoleParams {
   username: string;
-  roleName: string;
+  roles: string[];
 }
 
 export interface UnassignRoleParams extends AssignRoleParams {}

+ 29 - 9
client/src/pages/user/User.tsx

@@ -50,7 +50,7 @@ const Users = () => {
           role:
             v === 'root'
               ? 'root'
-              : rolesByName.map((r: any) => r.role.name).join(','),
+              : rolesByName.map((r: any) => r.role.name).join(' , '),
         };
       })
     );
@@ -60,13 +60,10 @@ const Users = () => {
     await UserHttp.createUser(data);
     console.log(data, data.roles);
     // assign user role if
-    if (data.roles.length > 0) {
-      console.log('assign roles');
-      // await UserHttp.assignUserRole({
-      //   username: data.username,
-      //   roleName: data.roleName,
-      // });
-    }
+    await UserHttp.updateUserRole({
+      username: data.username,
+      roles: data.roles,
+    });
 
     fetchUsers();
     openSnackBar(successTrans('create', { name: userTrans('user') }));
@@ -117,6 +114,30 @@ const Users = () => {
       icon: 'add',
     },
 
+    {
+      type: 'iconBtn',
+      label: userTrans('editRole'),
+      onClick: async () => {
+        const roles = await UserHttp.getRoles();
+        setDialog({
+          open: true,
+          type: 'custom',
+          params: {
+            component: (
+              <CreateUser
+                handleCreate={handleCreate}
+                handleClose={handleCloseDialog}
+                roles={roles.results.map((r: any) => {
+                  return { label: r.role.name, value: r.role.name };
+                })}
+              />
+            ),
+          },
+        });
+      },
+      icon: 'edit',
+    },
+
     {
       type: 'iconBtn',
       onClick: () => {
@@ -140,7 +161,6 @@ const Users = () => {
         selectedUser.length === 0 ||
         selectedUser.findIndex(v => v.name === 'root') > -1,
       disabledTooltip: userTrans('deleteTip'),
-
       icon: 'delete',
     },
   ];

+ 2 - 2
server/src/users/dto.ts

@@ -28,8 +28,8 @@ export class AssignUserRoleDto {
   @IsString()
   readonly username: string;
 
-  @IsString()
-  readonly roleName: string;
+  @IsString({ each: true })
+  readonly roles: string;
 }
 
 export class UnassignUserRoleDto {

+ 32 - 8
server/src/users/users.controller.ts

@@ -47,9 +47,9 @@ export class UserController {
     this.router.delete('/roles/:roleName', this.deleteRole.bind(this));
 
     this.router.put(
-      '/:username/role/assign',
+      '/:username/role/update',
       dtoValidationMiddleware(AssignUserRoleDto),
-      this.assignUserRole.bind(this)
+      this.updateUserRole.bind(this)
     );
 
     this.router.put(
@@ -134,16 +134,40 @@ export class UserController {
     }
   }
 
-  async assignUserRole(req: Request, res: Response, next: NextFunction) {
-    const { roleName } = req.body;
+  async updateUserRole(req: Request, res: Response, next: NextFunction) {
+    const { roles } = req.body;
     const { username } = req.params;
 
+    const results = [];
+
     try {
-      const result = await this.userService.assignUserRole({
+      // get user existing roles
+      const selectUser = await this.userService.selectUser({
         username,
-        roleName,
+        includeRoleInfo: false,
       });
-      res.send(result);
+
+      const existingRoles = selectUser.results[0].roles;
+      // remove user existing roles
+      for (let i = 0; i < existingRoles.length; i++) {
+        if (existingRoles[i].name.length > 0) {
+          await this.userService.unassignUserRole({
+            username,
+            roleName: existingRoles[i].name,
+          });
+        }
+      }
+
+      // assign new user roles
+      for (let i = 0; i < roles.length; i++) {
+        const result = await this.userService.assignUserRole({
+          username,
+          roleName: roles[i],
+        });
+        results.push(result);
+      }
+
+      res.send(results);
     } catch (error) {
       next(error);
     }
@@ -154,7 +178,7 @@ export class UserController {
     const { username } = req.params;
 
     try {
-      const result = await this.userService.assignUserRole({
+      const result = await this.userService.unassignUserRole({
         username,
         roleName,
       });

+ 12 - 5
server/src/users/users.service.ts

@@ -7,7 +7,9 @@ import {
   DropRoleReq,
   AddUserToRoleReq,
   RemoveUserFromRoleReq,
-  HasRoleReq
+  HasRoleReq,
+  listRoleReq,
+  SelectUserReq,
 } from '@zilliz/milvus2-sdk-node';
 import { throwErrorFromSDK } from '../utils/Error';
 
@@ -41,10 +43,15 @@ export class UserService {
     return res;
   }
 
-  async getRoles() {
-    const res = await this.milvusService.client.listRoles({
-      includeUserInfo: true,
-    });
+  async getRoles(data?: listRoleReq) {
+    const res = await this.milvusService.client.listRoles(data);
+    throwErrorFromSDK(res.status);
+
+    return res;
+  }
+
+  async selectUser(data?: SelectUserReq) {
+    const res = await this.milvusService.client.selectUser(data);
     throwErrorFromSDK(res.status);
 
     return res;