Browse Source

support edit role privilege

Signed-off-by: ruiyi.jiang <ruiyi.jiang@zilliz.com>
ruiyi.jiang 1 year ago
parent
commit
220491372e

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

@@ -15,12 +15,13 @@ const userTrans = {
 
 
   // role
   // role
   deleteEditRoleTip: 'root role is not editable.',
   deleteEditRoleTip: 'root role is not editable.',
-  disabbleEditRolePriviledgeTip: 'admin and public role are not editable.',
+  disableEditRolePrivilegeTip: 'admin and public role are not editable.',
 
 
   role: 'Role',
   role: 'Role',
   editRole: 'Edit Role',
   editRole: 'Edit Role',
   roles: 'Roles',
   roles: 'Roles',
   createRoleTitle: 'Create Role',
   createRoleTitle: 'Create Role',
+  updateRolePrivilegeTitle: 'Update Role',
   updateRoleSuccess: 'User Role',
   updateRoleSuccess: 'User Role',
   type: 'Type',
   type: 'Type',
 
 

+ 1 - 0
client/src/pages/user/PrivilegeOptions.tsx

@@ -67,6 +67,7 @@ const PrivilegeOptions: FC<PrivilegeOptionsProps> = ({
             key={r}
             key={r}
             label={r}
             label={r}
             value={r}
             value={r}
+            checked={selection.filter((s: Privilege) => s.privilegeName === r).length > 0}
             className={classes.checkBox}
             className={classes.checkBox}
           />
           />
         ))}
         ))}

+ 25 - 7
client/src/pages/user/Roles.tsx

@@ -9,7 +9,7 @@ import DeleteTemplate from '@/components/customDialog/DeleteDialogTemplate';
 import { rootContext } from '@/context/Root';
 import { rootContext } from '@/context/Root';
 import { useNavigationHook } from '@/hooks/Navigation';
 import { useNavigationHook } from '@/hooks/Navigation';
 import { ALL_ROUTER_TYPES } from '@/router/Types';
 import { ALL_ROUTER_TYPES } from '@/router/Types';
-import CreateRole from './CreateRoleDialog';
+import UpdateRoleDialog from './UpdateRoleDialog';
 
 
 const useStyles = makeStyles((theme: Theme) => ({
 const useStyles = makeStyles((theme: Theme) => ({
   wrapper: {
   wrapper: {
@@ -32,11 +32,22 @@ const Roles = () => {
 
 
   const fetchRoles = async () => {
   const fetchRoles = async () => {
     const roles = await UserHttp.getRoles();
     const roles = await UserHttp.getRoles();
-
-    setRoles(roles.results.map((v: any) => ({ name: v.role.name })));
+    setSelectedRole([]);
+
+    setRoles(
+      roles.results.map((v: any) => ({
+        name: v.role.name,
+        privileges: v.entities.map((e: any) => ({
+          roleName: v.role.name,
+          object: e.object.name,
+          objectName: e.object_name,
+          privilegeName: e.grantor.privilege.name,
+        })),
+      }))
+    );
   };
   };
 
 
-  const onCreate = async () => {
+  const onUpdate = async () => {
     fetchRoles();
     fetchRoles();
     openSnackBar(successTrans('create', { name: userTrans('role') }));
     openSnackBar(successTrans('create', { name: userTrans('role') }));
     handleCloseDialog();
     handleCloseDialog();
@@ -64,7 +75,10 @@ const Roles = () => {
           type: 'custom',
           type: 'custom',
           params: {
           params: {
             component: (
             component: (
-              <CreateRole onCreate={onCreate} handleClose={handleCloseDialog} />
+              <UpdateRoleDialog
+                onUpdate={onUpdate}
+                handleClose={handleCloseDialog}
+              />
             ),
             ),
           },
           },
         });
         });
@@ -81,7 +95,11 @@ const Roles = () => {
           type: 'custom',
           type: 'custom',
           params: {
           params: {
             component: (
             component: (
-              <CreateRole onCreate={onCreate} handleClose={handleCloseDialog} />
+              <UpdateRoleDialog
+                role={selectedRole[0]}
+                onUpdate={onUpdate}
+                handleClose={handleCloseDialog}
+              />
             ),
             ),
           },
           },
         });
         });
@@ -92,7 +110,7 @@ const Roles = () => {
         selectedRole.length > 1 ||
         selectedRole.length > 1 ||
         selectedRole.findIndex(v => v.name === 'admin') > -1 ||
         selectedRole.findIndex(v => v.name === 'admin') > -1 ||
         selectedRole.findIndex(v => v.name === 'public') > -1,
         selectedRole.findIndex(v => v.name === 'public') > -1,
-      disabledTooltip: userTrans('disabbleEditRolePriviledgeTip'),
+      disabledTooltip: userTrans('disableEditRolePrivilegeTip'),
     },
     },
 
 
     {
     {

+ 8 - 4
client/src/pages/user/Types.ts

@@ -58,9 +58,15 @@ export interface CreateRoleParams {
   privileges: Privilege[];
   privileges: Privilege[];
 }
 }
 
 
+export interface RoleData {
+  name: string;
+  privileges: Privilege[];
+}
+
 export interface CreateRoleProps {
 export interface CreateRoleProps {
-  onCreate: (data: CreateRoleParams) => void;
+  onUpdate: (data: CreateRoleParams) => void;
   handleClose: () => void;
   handleClose: () => void;
+  role?: RoleData;
 }
 }
 
 
 export interface DeleteRoleParams {
 export interface DeleteRoleParams {
@@ -74,9 +80,7 @@ export interface AssignRoleParams {
 
 
 export interface UnassignRoleParams extends AssignRoleParams {}
 export interface UnassignRoleParams extends AssignRoleParams {}
 
 
-export interface RoleData {
-  name: string;
-}
+
 
 
 export enum TAB_EMUM {
 export enum TAB_EMUM {
   'schema',
   'schema',

+ 23 - 11
client/src/pages/user/CreateRoleDialog.tsx → client/src/pages/user/UpdateRoleDialog.tsx

@@ -32,7 +32,11 @@ const useStyles = makeStyles((theme: Theme) => ({
   },
   },
 }));
 }));
 
 
-const CreateRoleDialog: FC<CreateRoleProps> = ({ onCreate, handleClose }) => {
+const UpdateRoleDialog: FC<CreateRoleProps> = ({
+  onUpdate,
+  handleClose,
+  role = { name: '', privileges: [] },
+}) => {
   const { t: userTrans } = useTranslation('user');
   const { t: userTrans } = useTranslation('user');
   const { t: btnTrans } = useTranslation('btn');
   const { t: btnTrans } = useTranslation('btn');
   const { t: warningTrans } = useTranslation('warning');
   const { t: warningTrans } = useTranslation('warning');
@@ -46,21 +50,21 @@ const CreateRoleDialog: FC<CreateRoleProps> = ({ onCreate, handleClose }) => {
 
 
   const fetchRBAC = async () => {
   const fetchRBAC = async () => {
     const rbacOptions = await UserHttp.getRBAC();
     const rbacOptions = await UserHttp.getRBAC();
-    const roles = await UserHttp.getRoles();
-
-    console.log(rbacOptions, roles);
 
 
     setRbacOptions(rbacOptions);
     setRbacOptions(rbacOptions);
   };
   };
 
 
+  const isEditing = role.name !== '';
+
   useEffect(() => {
   useEffect(() => {
     fetchRBAC();
     fetchRBAC();
   }, []);
   }, []);
 
 
   const [form, setForm] = useState<CreateRoleParams>({
   const [form, setForm] = useState<CreateRoleParams>({
-    roleName: '',
-    privileges: [],
+    roleName: role.name,
+    privileges: JSON.parse(JSON.stringify(role.privileges)),
   });
   });
+
   const checkedForm = useMemo(() => {
   const checkedForm = useMemo(() => {
     return formatForm(form);
     return formatForm(form);
   }, [form]);
   }, [form]);
@@ -97,14 +101,19 @@ const CreateRoleDialog: FC<CreateRoleProps> = ({ onCreate, handleClose }) => {
         },
         },
       ],
       ],
       defaultValue: form.roleName,
       defaultValue: form.roleName,
+      disabled: isEditing,
     },
     },
   ];
   ];
 
 
   const handleCreateRole = async () => {
   const handleCreateRole = async () => {
-    await UserHttp.createRole(form);
+    if (!isEditing) {
+      await UserHttp.createRole(form);
+    }
+
+    console.log('form', form);
     await UserHttp.updateRolePrivileges(form);
     await UserHttp.updateRolePrivileges(form);
 
 
-    onCreate(form);
+    onUpdate(form);
   };
   };
 
 
   const onChange = (newSelection: any) => {
   const onChange = (newSelection: any) => {
@@ -142,9 +151,11 @@ const CreateRoleDialog: FC<CreateRoleProps> = ({ onCreate, handleClose }) => {
 
 
   return (
   return (
     <DialogTemplate
     <DialogTemplate
-      title={userTrans('createRoleTitle')}
+      title={userTrans(
+        isEditing ? 'updateRolePrivilegeTitle' : 'createRoleTitle'
+      )}
       handleClose={handleClose}
       handleClose={handleClose}
-      confirmLabel={btnTrans('create')}
+      confirmLabel={btnTrans(isEditing ? 'update' : 'create')}
       handleConfirm={handleCreateRole}
       handleConfirm={handleCreateRole}
       confirmDisabled={disabled}
       confirmDisabled={disabled}
       dialogClass={classes.dialogWrapper}
       dialogClass={classes.dialogWrapper}
@@ -165,6 +176,7 @@ const CreateRoleDialog: FC<CreateRoleProps> = ({ onCreate, handleClose }) => {
 
 
         {optionGroups.map(o => (
         {optionGroups.map(o => (
           <PrivilegeOptions
           <PrivilegeOptions
+            key={o.object}
             title={o.title}
             title={o.title}
             object={o.object}
             object={o.object}
             options={o.options}
             options={o.options}
@@ -178,4 +190,4 @@ const CreateRoleDialog: FC<CreateRoleProps> = ({ onCreate, handleClose }) => {
   );
   );
 };
 };
 
 
-export default CreateRoleDialog;
+export default UpdateRoleDialog;

+ 11 - 12
server/src/users/users.controller.ts

@@ -230,18 +230,17 @@ export class UserController {
         roleName,
         roleName,
       });
       });
 
 
-      console.log('existing privileges', existingPrivileges);
-
-      // const existingPrivileges = privileges.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,
-      //     });
-      //   }
-      // }
+      // revoke all
+      for (let i = 0; i < existingPrivileges.entities.length; i++) {
+        const res = existingPrivileges.entities[i];
+        const result = await this.userService.revokeRolePrivilege({
+          object: res.object.name,
+          objectName: res.object_name,
+          privilegeName: res.grantor.privilege.name,
+          roleName: res.role.name,
+        });
+        results.push(result);
+      }
 
 
       // assign new user roles
       // assign new user roles
       for (let i = 0; i < privileges.length; i++) {
       for (let i = 0; i < privileges.length; i++) {

+ 6 - 0
server/src/users/users.service.ts

@@ -116,4 +116,10 @@ export class UserService {
     throwErrorFromSDK(res);
     throwErrorFromSDK(res);
     return res;
     return res;
   }
   }
+
+  async revokeRolePrivilege(data: OperateRolePrivilegeReq) {
+    const res = await this.milvusService.client.revokeRolePrivilege(data);
+    throwErrorFromSDK(res);
+    return res;
+  }
 }
 }