Skip to content

Commit 624f351

Browse files
committed
feat(server): make permission a standalone module (#7880)
1 parent ba8958f commit 624f351

File tree

30 files changed

+123
-116
lines changed

30 files changed

+123
-116
lines changed

packages/backend/server/src/app.module.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { AuthModule } from './core/auth';
1212
import { ADD_ENABLED_FEATURES, ServerConfigModule } from './core/config';
1313
import { DocModule } from './core/doc';
1414
import { FeatureModule } from './core/features';
15+
import { PermissionModule } from './core/permission';
1516
import { QuotaModule } from './core/quota';
1617
import { SelfhostModule } from './core/selfhost';
1718
import { StorageModule } from './core/storage';
@@ -41,7 +42,6 @@ import { ENABLED_PLUGINS } from './plugins/registry';
4142

4243
export const FunctionalityModules = [
4344
ConfigModule.forRoot(),
44-
ScheduleModule.forRoot(),
4545
EventModule,
4646
CacheModule,
4747
MutexModule,
@@ -147,12 +147,12 @@ export function buildAppModule() {
147147
const factor = new AppModuleBuilder(AFFiNE);
148148

149149
factor
150-
// common fundamental modules
150+
// basic
151151
.use(...FunctionalityModules)
152152
.useIf(config => config.flavor.sync, WebSocketModule)
153153

154154
// auth
155-
.use(UserModule, AuthModule)
155+
.use(UserModule, AuthModule, PermissionModule)
156156

157157
// business modules
158158
.use(DocModule)
@@ -163,9 +163,10 @@ export function buildAppModule() {
163163
// graphql server only
164164
.useIf(
165165
config => config.flavor.graphql,
166-
ServerConfigModule,
166+
ScheduleModule.forRoot(),
167167
GqlModule,
168168
StorageModule,
169+
ServerConfigModule,
169170
WorkspaceModule,
170171
FeatureModule,
171172
QuotaModule

packages/backend/server/src/core/doc/history.ts

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ import {
1111
DocNotFound,
1212
metrics,
1313
OnEvent,
14-
WorkspaceNotFound,
1514
} from '../../fundamentals';
15+
import { PermissionService } from '../permission';
1616
import { QuotaService } from '../quota';
17-
import { Permission } from '../workspaces/types';
1817
import { isEmptyBuffer } from './manager';
1918

2019
@Injectable()
@@ -23,7 +22,8 @@ export class DocHistoryManager {
2322
constructor(
2423
private readonly config: Config,
2524
private readonly db: PrismaClient,
26-
private readonly quota: QuotaService
25+
private readonly quota: QuotaService,
26+
private readonly permission: PermissionService
2727
) {}
2828

2929
@OnEvent('workspace.deleted')
@@ -235,21 +235,8 @@ export class DocHistoryManager {
235235
}
236236

237237
async getExpiredDateFromNow(workspaceId: string) {
238-
const permission = await this.db.workspaceUserPermission.findFirst({
239-
select: {
240-
userId: true,
241-
},
242-
where: {
243-
workspaceId,
244-
type: Permission.Owner,
245-
},
246-
});
247-
248-
if (!permission) {
249-
throw new WorkspaceNotFound({ workspaceId });
250-
}
251-
252-
const quota = await this.quota.getUserQuota(permission.userId);
238+
const owner = await this.permission.getWorkspaceOwner(workspaceId);
239+
const quota = await this.quota.getUserQuota(owner.id);
253240
return quota.feature.historyPeriodFromNow;
254241
}
255242

packages/backend/server/src/core/doc/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import './config';
22

33
import { Module } from '@nestjs/common';
44

5+
import { PermissionModule } from '../permission';
56
import { QuotaModule } from '../quota';
67
import { DocHistoryManager } from './history';
78
import { DocManager } from './manager';
89

910
@Module({
10-
imports: [QuotaModule],
11+
imports: [QuotaModule, PermissionModule],
1112
providers: [DocManager, DocHistoryManager],
1213
exports: [DocManager, DocHistoryManager],
1314
})
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Module } from '@nestjs/common';
2+
3+
import { PermissionService } from './service';
4+
5+
@Module({
6+
providers: [PermissionService],
7+
exports: [PermissionService],
8+
})
9+
export class PermissionModule {}
10+
11+
export { PermissionService } from './service';
12+
export { Permission, PublicPageMode } from './types';

packages/backend/server/src/core/workspaces/permission.ts renamed to packages/backend/server/src/core/permission/service.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ import { Injectable } from '@nestjs/common';
22
import type { Prisma } from '@prisma/client';
33
import { PrismaClient } from '@prisma/client';
44

5-
import { DocAccessDenied, WorkspaceAccessDenied } from '../../fundamentals';
6-
import { Permission } from './types';
7-
8-
export enum PublicPageMode {
9-
Page,
10-
Edgeless,
11-
}
5+
import {
6+
DocAccessDenied,
7+
WorkspaceAccessDenied,
8+
WorkspaceOwnerNotFound,
9+
} from '../../fundamentals';
10+
import { Permission, PublicPageMode } from './types';
1211

1312
@Injectable()
1413
export class PermissionService {
@@ -59,7 +58,7 @@ export class PermissionService {
5958
}
6059

6160
async getWorkspaceOwner(workspaceId: string) {
62-
return this.prisma.workspaceUserPermission.findFirstOrThrow({
61+
const owner = await this.prisma.workspaceUserPermission.findFirst({
6362
where: {
6463
workspaceId,
6564
type: Permission.Owner,
@@ -68,6 +67,12 @@ export class PermissionService {
6867
user: true,
6968
},
7069
});
70+
71+
if (!owner) {
72+
throw new WorkspaceOwnerNotFound({ workspaceId });
73+
}
74+
75+
return owner.user;
7176
}
7277

7378
async tryGetWorkspaceOwner(workspaceId: string) {
@@ -195,6 +200,17 @@ export class PermissionService {
195200
return false;
196201
}
197202

203+
async allowUrlPreview(ws: string) {
204+
const count = await this.prisma.workspace.count({
205+
where: {
206+
id: ws,
207+
public: true,
208+
},
209+
});
210+
211+
return count > 0;
212+
}
213+
198214
async grant(
199215
ws: string,
200216
user: string,
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export enum Permission {
2+
Read = 0,
3+
Write = 1,
4+
Admin = 10,
5+
Owner = 99,
6+
}
7+
8+
export enum PublicPageMode {
9+
Page,
10+
Edgeless,
11+
}

packages/backend/server/src/core/quota/index.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Module } from '@nestjs/common';
22

33
import { FeatureModule } from '../features';
4+
import { PermissionModule } from '../permission';
45
import { StorageModule } from '../storage';
5-
import { PermissionService } from '../workspaces/permission';
66
import { QuotaManagementResolver } from './resolver';
77
import { QuotaService } from './service';
88
import { QuotaManagementService } from './storage';
@@ -14,13 +14,8 @@ import { QuotaManagementService } from './storage';
1414
* - quota statistics
1515
*/
1616
@Module({
17-
imports: [FeatureModule, StorageModule],
18-
providers: [
19-
PermissionService,
20-
QuotaService,
21-
QuotaManagementResolver,
22-
QuotaManagementService,
23-
],
17+
imports: [FeatureModule, StorageModule, PermissionModule],
18+
providers: [QuotaService, QuotaManagementResolver, QuotaManagementService],
2419
exports: [QuotaService, QuotaManagementService],
2520
})
2621
export class QuotaModule {}

packages/backend/server/src/core/quota/storage.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { Injectable, Logger } from '@nestjs/common';
22

3-
import { WorkspaceOwnerNotFound } from '../../fundamentals';
43
import { FeatureService, FeatureType } from '../features';
4+
import { PermissionService } from '../permission';
55
import { WorkspaceBlobStorage } from '../storage';
6-
import { PermissionService } from '../workspaces/permission';
76
import { OneGB } from './constant';
87
import { QuotaService } from './service';
98
import { formatSize, QuotaQueryType } from './types';
@@ -113,9 +112,7 @@ export class QuotaManagementService {
113112
// get workspace's owner quota and total size of used
114113
// quota was apply to owner's account
115114
async getWorkspaceUsage(workspaceId: string): Promise<QuotaBusinessType> {
116-
const { user: owner } =
117-
await this.permissions.getWorkspaceOwner(workspaceId);
118-
if (!owner) throw new WorkspaceOwnerNotFound({ workspaceId });
115+
const owner = await this.permissions.getWorkspaceOwner(workspaceId);
119116
const {
120117
feature: {
121118
name,

packages/backend/server/src/core/sync/events/events.gateway.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ import {
2323
} from '../../../fundamentals';
2424
import { Auth, CurrentUser } from '../../auth';
2525
import { DocManager } from '../../doc';
26+
import { Permission, PermissionService } from '../../permission';
2627
import { DocID } from '../../utils/doc';
27-
import { PermissionService } from '../../workspaces/permission';
28-
import { Permission } from '../../workspaces/types';
2928

3029
const SubscribeMessage = (event: string) =>
3130
applyDecorators(
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { Module } from '@nestjs/common';
22

33
import { DocModule } from '../../doc';
4-
import { PermissionService } from '../../workspaces/permission';
4+
import { PermissionModule } from '../../permission';
55
import { EventsGateway } from './events.gateway';
66

77
@Module({
8-
imports: [DocModule],
9-
providers: [EventsGateway, PermissionService],
8+
imports: [DocModule, PermissionModule],
9+
providers: [EventsGateway],
1010
})
1111
export class EventsModule {}

0 commit comments

Comments
 (0)