Skip to content

Commit 199f454

Browse files
c121914yuFinleyGe
andauthored
feat: team permission refine (#4494) (#4498)
* feat: team permission refine (#4402) * chore: team permission extend * feat: manage team permission * chore: api auth * fix: i18n * feat: add initv493 * fix: test, org auth manager * test: app test for refined permission * update init sh * fix: add/remove manage permission (#4427) * fix: add/remove manage permission * fix: github action fastgpt-test * fix: mock create model * fix: team write permission * fix: ts * account permission --------- Co-authored-by: Finley Ge <[email protected]>
1 parent 80f41dd commit 199f454

File tree

51 files changed

+1113
-457
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1113
-457
lines changed

.github/workflows/fastgpt-test.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ jobs:
1515

1616
steps:
1717
- uses: actions/checkout@v4
18+
with:
19+
ref: ${{ github.event.pull_request.head.ref }}
20+
repository: ${{ github.event.pull_request.head.repo.full_name }}
1821
- uses: pnpm/action-setup@v4
1922
with:
2023
version: 10

package.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,20 @@
1212
"previewIcon": "node ./scripts/icon/index.js",
1313
"api:gen": "tsc ./scripts/openapi/index.ts && node ./scripts/openapi/index.js && npx @redocly/cli build-docs ./scripts/openapi/openapi.json -o ./projects/app/public/openapi/index.html",
1414
"create:i18n": "node ./scripts/i18n/index.js",
15-
"test": "vitest run --exclude 'test/cases/spec'",
16-
"test:all": "vitest run",
15+
"test": "vitest run",
1716
"test:workflow": "vitest run workflow"
1817
},
1918
"devDependencies": {
2019
"@chakra-ui/cli": "^2.4.1",
21-
"@vitest/coverage-v8": "^3.0.2",
20+
"@vitest/coverage-v8": "^3.0.9",
2221
"husky": "^8.0.3",
2322
"i18next": "23.16.8",
2423
"lint-staged": "^13.3.0",
2524
"next-i18next": "15.4.2",
2625
"prettier": "3.2.4",
2726
"react-i18next": "14.1.2",
28-
"vitest": "^3.0.2",
29-
"vitest-mongodb": "^1.0.1",
27+
"vitest": "^3.0.9",
28+
"mongodb-memory-server": "^10.1.4",
3029
"zhlint": "^0.7.4"
3130
},
3231
"lint-staged": {

packages/global/support/permission/collaborator.d.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@ export type CollaboratorItemType = {
1313
orgId: string;
1414
}>;
1515

16-
export type UpdateClbPermissionProps = {
16+
export type UpdateClbPermissionProps<addOnly = false> = {
1717
members?: string[];
1818
groups?: string[];
1919
orgs?: string[];
20-
permission: PermissionValueType;
21-
};
20+
} & (addOnly extends true
21+
? {}
22+
: {
23+
permission: PermissionValueType;
24+
});
2225

2326
export type DeletePermissionQuery = RequireOnlyOne<{
2427
tmbId?: string;

packages/global/support/permission/controller.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@ export type PerConstructPros = {
55
per?: PermissionValueType;
66
isOwner?: boolean;
77
permissionList?: PermissionListType;
8+
childUpdatePermissionCallback?: () => void;
89
};
910

1011
// the Permission helper class
1112
export class Permission {
1213
value: PermissionValueType;
13-
isOwner: boolean;
14-
hasManagePer: boolean;
15-
hasWritePer: boolean;
16-
hasReadPer: boolean;
14+
isOwner: boolean = false;
15+
hasManagePer: boolean = false;
16+
hasWritePer: boolean = false;
17+
hasReadPer: boolean = false;
1718
_permissionList: PermissionListType;
1819

1920
constructor(props?: PerConstructPros) {
@@ -24,11 +25,8 @@ export class Permission {
2425
this.value = per;
2526
}
2627

27-
this.isOwner = isOwner;
2828
this._permissionList = permissionList;
29-
this.hasManagePer = this.checkPer(this._permissionList['manage'].value);
30-
this.hasWritePer = this.checkPer(this._permissionList['write'].value);
31-
this.hasReadPer = this.checkPer(this._permissionList['read'].value);
29+
this.updatePermissions();
3230
}
3331

3432
// add permission(s)
@@ -68,10 +66,21 @@ export class Permission {
6866
return (this.value & perm) === perm;
6967
}
7068

69+
private updatePermissionCallback?: () => void;
70+
setUpdatePermissionCallback(callback: () => void) {
71+
callback();
72+
this.updatePermissionCallback = callback;
73+
}
74+
7175
private updatePermissions() {
7276
this.isOwner = this.value === OwnerPermissionVal;
7377
this.hasManagePer = this.checkPer(this._permissionList['manage'].value);
7478
this.hasWritePer = this.checkPer(this._permissionList['write'].value);
7579
this.hasReadPer = this.checkPer(this._permissionList['read'].value);
80+
this.updatePermissionCallback?.();
81+
}
82+
83+
toBinary() {
84+
return this.value.toString(2);
7685
}
7786
}

packages/global/support/permission/memberGroup/type.d.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,23 @@ type GroupMemberSchemaType = {
1717
role: `${GroupMemberRole}`;
1818
};
1919

20-
type MemberGroupListItemType<T extends boolean | undefined> = MemberGroupSchemaType & {
21-
members: T extends true
20+
type MemberGroupListItemType<WithMembers extends boolean | undefined> = MemberGroupSchemaType & {
21+
members: WithMembers extends true
2222
? {
2323
tmbId: string;
2424
name: string;
2525
avatar: string;
2626
}[]
2727
: undefined;
28-
count: T extends true ? number : undefined;
29-
owner?: T extends true
28+
count: WithMembers extends true ? number : undefined;
29+
owner?: WithMembers extends true
3030
? {
3131
tmbId: string;
3232
name: string;
3333
avatar: string;
3434
}
3535
: undefined;
36-
permission: T extends true ? Permission : undefined;
36+
permission: WithMembers extends true ? Permission : undefined;
3737
};
3838

3939
type GroupMemberItemType = {
Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,50 @@
11
import { PermissionKeyEnum } from '../constant';
22
import { PermissionListType } from '../type';
33
import { PermissionList } from '../constant';
4-
export const TeamPermissionList: PermissionListType = {
4+
import { i18nT } from '../../../../web/i18n/utils';
5+
export enum TeamPermissionKeyEnum {
6+
appCreate = 'appCreate',
7+
datasetCreate = 'datasetCreate',
8+
apikeyCreate = 'apikeyCreate'
9+
}
10+
11+
export const TeamPermissionList: PermissionListType<TeamPermissionKeyEnum> = {
512
[PermissionKeyEnum.read]: {
613
...PermissionList[PermissionKeyEnum.read],
7-
value: 0b100
14+
value: 0b000100
815
},
916
[PermissionKeyEnum.write]: {
1017
...PermissionList[PermissionKeyEnum.write],
11-
value: 0b010
18+
value: 0b000010
1219
},
1320
[PermissionKeyEnum.manage]: {
1421
...PermissionList[PermissionKeyEnum.manage],
15-
value: 0b001
22+
value: 0b000001
23+
},
24+
[TeamPermissionKeyEnum.appCreate]: {
25+
checkBoxType: 'multiple',
26+
description: '',
27+
name: i18nT('account_team:permission_appCreate'),
28+
value: 0b001000
29+
},
30+
[TeamPermissionKeyEnum.datasetCreate]: {
31+
checkBoxType: 'multiple',
32+
description: '',
33+
name: i18nT('account_team:permission_datasetCreate'),
34+
value: 0b010000
35+
},
36+
[TeamPermissionKeyEnum.apikeyCreate]: {
37+
checkBoxType: 'multiple',
38+
description: '',
39+
name: i18nT('account_team:permission_apikeyCreate'),
40+
value: 0b100000
1641
}
1742
};
1843

1944
export const TeamReadPermissionVal = TeamPermissionList['read'].value;
2045
export const TeamWritePermissionVal = TeamPermissionList['write'].value;
2146
export const TeamManagePermissionVal = TeamPermissionList['manage'].value;
47+
export const TeamAppCreatePermissionVal = TeamPermissionList['appCreate'].value;
48+
export const TeamDatasetCreatePermissionVal = TeamPermissionList['datasetCreate'].value;
49+
export const TeamApikeyCreatePermissionVal = TeamPermissionList['apikeyCreate'].value;
2250
export const TeamDefaultPermissionVal = TeamReadPermissionVal;

packages/global/support/permission/user/controller.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
import { PerConstructPros, Permission } from '../controller';
2-
import { TeamDefaultPermissionVal, TeamPermissionList } from './constant';
2+
import {
3+
TeamAppCreatePermissionVal,
4+
TeamDefaultPermissionVal,
5+
TeamPermissionList
6+
} from './constant';
37

48
export class TeamPermission extends Permission {
9+
hasAppCreatePer: boolean = false;
10+
hasDatasetCreatePer: boolean = false;
11+
hasApikeyCreatePer: boolean = false;
12+
513
constructor(props?: PerConstructPros) {
614
if (!props) {
715
props = {
@@ -12,5 +20,11 @@ export class TeamPermission extends Permission {
1220
}
1321
props.permissionList = TeamPermissionList;
1422
super(props);
23+
24+
this.setUpdatePermissionCallback(() => {
25+
this.hasAppCreatePer = this.checkPer(TeamAppCreatePermissionVal);
26+
this.hasDatasetCreatePer = this.checkPer(TeamAppCreatePermissionVal);
27+
this.hasApikeyCreatePer = this.checkPer(TeamAppCreatePermissionVal);
28+
});
1529
}
1630
}

packages/service/common/mongo/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ const addCommonMiddleware = (schema: mongoose.Schema) => {
6969

7070
export const getMongoModel = <T>(name: string, schema: mongoose.Schema) => {
7171
if (connectionMongo.models[name]) return connectionMongo.models[name] as Model<T>;
72-
console.log('Load model======', name);
72+
if (process.env.NODE_ENV !== 'test') console.log('Load model======', name);
7373
addCommonMiddleware(schema);
7474

7575
const model = connectionMongo.model<T>(name, schema);

packages/service/support/permission/auth/org.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { TeamPermission } from '@fastgpt/global/support/permission/user/controll
22
import { AuthModeType, AuthResponseType } from '../type';
33
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
44
import { authUserPer } from '../user/auth';
5-
import { ManagePermissionVal } from '@fastgpt/global/support/permission/constant';
5+
import { TeamManagePermissionVal } from '@fastgpt/global/support/permission/user/constant';
66

77
/*
88
Team manager can control org
@@ -15,7 +15,7 @@ export const authOrgMember = async ({
1515
} & AuthModeType): Promise<AuthResponseType> => {
1616
const result = await authUserPer({
1717
...props,
18-
per: ManagePermissionVal
18+
per: TeamManagePermissionVal
1919
});
2020
const { teamId, tmbId, isRoot, tmb } = result;
2121

packages/web/i18n/en/account_team.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,13 @@
6161
"user_team_invite_member": "Invite members",
6262
"user_team_leave_team": "Leave the team",
6363
"user_team_leave_team_failed": "Failure to leave the team",
64-
"waiting": "To be accepted"
64+
"waiting": "To be accepted",
65+
"permission_appCreate": "Create Application",
66+
"permission_datasetCreate": "Create Knowledge Base",
67+
"permission_apikeyCreate": "Create API Key",
68+
"permission_appCreate_tip": "Can create applications in the root directory (creation permissions in folders are controlled by the folder)",
69+
"permission_datasetCreate_Tip": "Can create knowledge bases in the root directory (creation permissions in folders are controlled by the folder)",
70+
"permission_apikeyCreate_Tip": "Can create global APIKeys",
71+
"permission_manage": "Admin",
72+
"permission_manage_tip": "Can manage members, create groups, manage all groups, and assign permissions to groups and members"
6573
}

0 commit comments

Comments
 (0)