Skip to content

Commit

Permalink
Add createPrivilegeGroup/dropPrivilegeGroup/listPrivilegeGroups/addPr…
Browse files Browse the repository at this point in the history
…ivilegesToGroup/removePrivilegesFromGroup (#394)

* add apis

Signed-off-by: ryjiang <[email protected]>

* finish

Signed-off-by: ryjiang <[email protected]>

* add more tests

Signed-off-by: ryjiang <[email protected]>

---------

Signed-off-by: ryjiang <[email protected]>
  • Loading branch information
shanghaikid committed Dec 24, 2024
1 parent 889fe0c commit e8e68a9
Show file tree
Hide file tree
Showing 5 changed files with 292 additions and 4 deletions.
5 changes: 5 additions & 0 deletions milvus/const/milvus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,3 +434,8 @@ export enum RANKER_TYPE {
RRF = 'rrf',
WEIGHTED = 'weighted',
}

export enum OperatePrivilegeGroupType {
AddPrivilegesToGroup = 0,
RemovePrivilegesFromGroup = 1,
}
198 changes: 198 additions & 0 deletions milvus/grpc/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,20 @@ import {
ListGrantsReq,
HasRoleReq,
listRoleReq,
CreatePrivilegeGroupReq,
DropPrivilegeGroupReq,
OperatePrivilegeGroupReq,
AddPrivilegesToGroupReq,
RemovePrivilegesFromGroupReq,
OperatePrivilegeGroupType,
GrpcTimeOut,
ListCredUsersResponse,
ResStatus,
SelectRoleResponse,
SelectUserResponse,
SelectGrantResponse,
HasRoleResponse,
ListPrivilegeGroupsResponse,
promisify,
stringToBase64,
} from '../';
Expand Down Expand Up @@ -680,4 +687,195 @@ export class User extends Resource {
hasRole: result.results.map(r => r.role.name).includes(data.roleName),
};
}

/**
* Create a new privilege group in Milvus.
* @param {CreatePrivilegeGroupReq} data - The privilege group data.
* @param {string} data.group_name - The name of the new privilege group.
* @param {number} [data.timeout] - An optional duration of time in milliseconds to allow for the RPC. If it is set to undefined, the client keeps waiting until the server responds or error occurs. Default is undefined.
*
* @returns {Promise<ResStatus>} The response status.
*
* @example
* ```javascript
* milvusClient.createPrivilegeGroup({
* group_name: 'exampleGroup',
* });
* ```
*/
async createPrivilegeGroup(
data: CreatePrivilegeGroupReq
): Promise<ResStatus> {
const promise = await promisify(
this.channelPool,
'CreatePrivilegeGroup',
data,
data.timeout || this.timeout
);

return promise;
}

/**
* Drop a privilege group in Milvus.
* @param {DropPrivilegeGroupReq} data - The privilege group data.
* @param {string} data.group_name - The name of the privilege group to be dropped.
* @param {number} [data.timeout] - An optional duration of time in milliseconds to allow for the RPC. If it is set to undefined, the client keeps waiting until the server responds or error occurs. Default is undefined.
*
* @returns {Promise<ResStatus>} The response status.
*
* @example
* ```javascript
* await milvusClient.dropPrivilegeGroup({
* group_name: 'exampleGroup',
* });
* ```
*/
async dropPrivilegeGroup(data: DropPrivilegeGroupReq): Promise<ResStatus> {
const promise = await promisify(
this.channelPool,
'DropPrivilegeGroup',
data,
data.timeout || this.timeout
);

return promise;
}

/**
* List all privilege groups in Milvus.
* @param {GrpcTimeOut} data - The data object.
* @param {number} [data.timeout] - An optional duration of time in milliseconds to allow for the RPC. If it is set to undefined, the client keeps waiting until the server responds or error occurs. Default is undefined.
*
* @returns {Promise<ListPrivilegeGroupsResponse>} The response object.
* @returns {ResStatus} response.status - The response status.
* @returns {number} response.status.error_code - The error code number.
* @returns {string} response.status.reason - The cause of the error, if any.
* @returns {PrivelegeGroup[]} response.privilege_groups - An array of privilege groups.
* @returns {string} response.privilege_groups.group_name - The name of the privilege group.
* @returns {PrivilegeEntity[]} response.privilege_groups.privileges - An array of privileges.
* @returns {string} response.privilege_groups.privileges.name - The name of the privilege.
*
* @example
* ```javascript
* await milvusClient.listPrivilegeGroups();
* ```
*/
async listPrivilegeGroups(
data?: GrpcTimeOut
): Promise<ListPrivilegeGroupsResponse> {
const promise = await promisify(
this.channelPool,
'ListPrivilegeGroups',
{},
data?.timeout || this.timeout
);

return promise;
}

/**
* Operate a privilege group in Milvus.
* @param {OperatePrivilegeGroupReq} data - The privilege group data.
* @param {string} data.group_name - The name of the privilege group to be operated.
* @param {PrivilegeEntity[]} data.privileges - The privileges to be operated.
* @param {OperatePrivilegeGroupType} data.type - The operation type.
* @param {number} [data.timeout] - An optional duration of time in milliseconds to allow for the RPC. If it is set to undefined, the client keeps waiting until the server responds or error occurs. Default is undefined.
* @returns {Promise<any>} The response object.
*
* @example
* ```javascript
* await milvusClient.operatePrivilegeGroup({
* group_name: 'exampleGroup',
* privileges: [{name: 'CreateCollection'}],
* type: OperatePrivilegeGroupType.AddPrivilegesToGroup,
* });
* ```
*/
async operatePrivilegeGroup(
data: OperatePrivilegeGroupReq
): Promise<ResStatus> {
const promise = await promisify(
this.channelPool,
'OperatePrivilegeGroup',
data,
data.timeout || this.timeout
);

return promise;
}

/**
* add privileges to a privilege group in Milvus.
* @param {AddPrivilegesToGroupReq} data - The privilege group data.
* @param {string} data.group_name - The name of the privilege group to be operated.
* @param {string[]} data.privileges - The privileges to be added to the group.
*
* @returns {Promise<ResStatus>} The response object.
* @returns {ResStatus} response.status - The response status.
* @returns {number} response.status.error_code - The error code number.
* @returns {string} response.status.reason - The cause of the error, if any.
*
* @example
* ```javascript
* await milvusClient.addPrivilegesToGroup({
* group_name: 'exampleGroup',
* privileges: ['CreateCollection', 'DropCollection'],
* });
*
* ```
*/
async addPrivilegesToGroup(
data: AddPrivilegesToGroupReq
): Promise<ResStatus> {
const promise = await promisify(
this.channelPool,
'OperatePrivilegeGroup',
{
group_name: data.group_name,
privileges: data.privileges.map(p => ({ name: p })),
type: OperatePrivilegeGroupType.AddPrivilegesToGroup,
},
data.timeout || this.timeout
);

return promise;
}

/**
* remove privileges from a privilege group in Milvus.
* @param {RemovePrivilegesFromGroupReq} data - The privilege group data.
* @param {string} data.group_name - The name of the privilege group to be operated.
* @param {string[]} data.privileges - The privileges to be removed from the group.
*
* @returns {Promise<ResStatus>} The response object.
* @returns {ResStatus} response.status - The response status.
* @returns {number} response.status.error_code - The error code number.
* @returns {string} response.status.reason - The cause of the error, if any.
*
* @example
* ```javascript
* await milvusClient.removePrivilegesFromGroup({
* group_name: 'exampleGroup',
* privileges: ['CreateCollection', 'DropCollection'],
* });
*
* ```
*/
async removePrivilegesFromGroup(
data: RemovePrivilegesFromGroupReq
): Promise<ResStatus> {
const promise = await promisify(
this.channelPool,
'OperatePrivilegeGroup',
{
group_name: data.group_name,
privileges: data.privileges.map(p => ({ name: p })),
type: OperatePrivilegeGroupType.RemovePrivilegesFromGroup,
},
data.timeout || this.timeout
);

return promise;
}
}
3 changes: 2 additions & 1 deletion milvus/types/Common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ export interface GrpcTimeOut {
export type PrivilegesTypes =
| CollectionPrivileges
| UserPrivileges
| GlobalPrivileges;
| GlobalPrivileges
| string;

export interface ResStatus {
error_code: string | number;
Expand Down
35 changes: 34 additions & 1 deletion milvus/types/User.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GrpcTimeOut, PrivilegesTypes, resStatusResponse } from './Common';
import { RbacObjects } from '../';
import { RbacObjects, OperatePrivilegeGroupType } from '../';

// base
export interface usernameReq extends GrpcTimeOut {
Expand Down Expand Up @@ -84,3 +84,36 @@ export interface SelectGrantResponse extends resStatusResponse {
export interface HasRoleResponse extends resStatusResponse {
hasRole: boolean;
}

export interface CreatePrivilegeGroupReq extends GrpcTimeOut {
group_name: string; // required, name
}

export interface DropPrivilegeGroupReq extends GrpcTimeOut {
group_name: string; // required, name
}

export type PrivelegeGroup = {
group_name: string; // name
privileges: PrivilegeEntity[]; // privileges
};

export interface ListPrivilegeGroupsResponse extends resStatusResponse {
privilege_groups: PrivelegeGroup[]; // privilege groups
}

export interface OperatePrivilegeGroupReq extends GrpcTimeOut {
group_name: string; // required, group name
privileges: PrivilegeEntity[]; // required, privileges
type: OperatePrivilegeGroupType; // required, operation type
}

export interface AddPrivilegesToGroupReq extends GrpcTimeOut {
group_name: string; // required, group name
privileges: PrivilegesTypes[]; // required, privileges
}

export interface RemovePrivilegesFromGroupReq extends GrpcTimeOut {
group_name: string; // required, group name
privileges: PrivilegesTypes[]; // required, privileges
}
55 changes: 53 additions & 2 deletions test/grpc/User.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import exp from 'constants';
import {
MilvusClient,
ERROR_REASONS,
Expand All @@ -6,17 +7,19 @@ import {
Roles,
Privileges,
RbacObjects,
OperatePrivilegeGroupType,
} from '../../milvus';
import { timeoutTest } from '../tools';
import { IP, genCollectionParams, GENERATE_NAME } from '../tools';

const milvusClient = new MilvusClient({ address: IP });
const milvusClient = new MilvusClient({ address: IP, logLevel: 'info' });
let authClient: MilvusClient;
const USERNAME = 'username';
const PASSWORD = '123456';
const NEW_PASSWORD = '1234567';
const ROLE_NAME = GENERATE_NAME('role');
const COLLECTION_NAME = GENERATE_NAME();
const PRIVILEGE_GRP_NAME = GENERATE_NAME('privilege');

describe(`User Api`, () => {
beforeAll(async () => {
Expand Down Expand Up @@ -274,9 +277,57 @@ describe(`User Api`, () => {
}
});

// last test
// last test for user
it(`Auth client delete user expect success`, async () => {
const res = await authClient.deleteUser({ username: USERNAME });
expect(res.error_code).toEqual(ErrorCode.SUCCESS);
});

it(`create a privilege group`, async () => {
const res = await authClient.createPrivilegeGroup({
group_name: PRIVILEGE_GRP_NAME,
});
expect(res.error_code).toEqual(ErrorCode.SUCCESS);
});

it(`add privileges to a privilege group`, async () => {
const res = await authClient.addPrivilegesToGroup({
group_name: PRIVILEGE_GRP_NAME,
privileges: [Privileges.Query],
});

expect(res.error_code).toEqual(ErrorCode.SUCCESS);

const res2 = await authClient.operatePrivilegeGroup({
group_name: PRIVILEGE_GRP_NAME,
privileges: [{ name: Privileges.Search }],
type: OperatePrivilegeGroupType.AddPrivilegesToGroup,
});
expect(res2.error_code).toEqual(ErrorCode.SUCCESS);
});

it(`remove privileges from a privilege group`, async () => {
const res = await authClient.removePrivilegesFromGroup({
group_name: PRIVILEGE_GRP_NAME,
privileges: [Privileges.Query],
});
expect(res.error_code).toEqual(ErrorCode.SUCCESS);
});

it(`list privilege groups`, async () => {
const res = await authClient.listPrivilegeGroups();
expect(res.privilege_groups.length).toBeGreaterThan(0);
const grp = res.privilege_groups.find(
g => g.group_name === PRIVILEGE_GRP_NAME
)!;
expect(grp.group_name).toEqual(PRIVILEGE_GRP_NAME);
expect(grp.privileges.map(p => p.name)).toContain(Privileges.Search);
});

it(`drop a privilege group`, async () => {
const res = await authClient.dropPrivilegeGroup({
group_name: PRIVILEGE_GRP_NAME,
});
expect(res.error_code).toEqual(ErrorCode.SUCCESS);
});
});

0 comments on commit e8e68a9

Please sign in to comment.