mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-21 12:06:35 +08:00
refactor(server): permission (#10449)
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
import assert from 'node:assert';
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Transactional } from '@nestjs-cls/transactional';
|
||||
import { WorkspaceDocUserRole } from '@prisma/client';
|
||||
|
||||
import { CanNotBatchGrantDocOwnerPermissions, PaginationInput } from '../base';
|
||||
import { BaseModel } from './base';
|
||||
import { DocRole } from './common';
|
||||
|
||||
@Injectable()
|
||||
export class DocUserModel extends BaseModel {
|
||||
/**
|
||||
* Set or update the [Owner] of a doc.
|
||||
* The old [Owner] will be changed to [Manager] if there is already an [Owner].
|
||||
*/
|
||||
@Transactional()
|
||||
async setOwner(workspaceId: string, docId: string, userId: string) {
|
||||
const oldOwner = await this.db.workspaceDocUserRole.findFirst({
|
||||
where: {
|
||||
workspaceId,
|
||||
docId,
|
||||
type: DocRole.Owner,
|
||||
},
|
||||
});
|
||||
|
||||
if (oldOwner) {
|
||||
await this.db.workspaceDocUserRole.update({
|
||||
where: {
|
||||
workspaceId_docId_userId: {
|
||||
workspaceId,
|
||||
docId,
|
||||
userId: oldOwner.userId,
|
||||
},
|
||||
},
|
||||
data: {
|
||||
type: DocRole.Manager,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
await this.db.workspaceDocUserRole.upsert({
|
||||
where: {
|
||||
workspaceId_docId_userId: {
|
||||
workspaceId,
|
||||
docId,
|
||||
userId,
|
||||
},
|
||||
},
|
||||
update: {
|
||||
type: DocRole.Owner,
|
||||
},
|
||||
create: {
|
||||
workspaceId,
|
||||
docId,
|
||||
userId,
|
||||
type: DocRole.Owner,
|
||||
},
|
||||
});
|
||||
|
||||
if (oldOwner) {
|
||||
this.logger.log(
|
||||
`Transfer doc owner of [${workspaceId}/${docId}] from [${oldOwner.userId}] to [${userId}]`
|
||||
);
|
||||
} else {
|
||||
this.logger.log(
|
||||
`Set doc owner of [${workspaceId}/${docId}] to [${userId}]`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or update the Role of a user in a doc.
|
||||
*
|
||||
* NOTE: do not use this method to set the [Owner] of a doc. Use {@link setOwner} instead.
|
||||
*/
|
||||
@Transactional()
|
||||
async set(workspaceId: string, docId: string, userId: string, role: DocRole) {
|
||||
// internal misuse, throw directly
|
||||
assert(role !== DocRole.Owner, 'Cannot set Owner role of a doc to a user.');
|
||||
|
||||
const oldRole = await this.get(workspaceId, docId, userId);
|
||||
|
||||
if (oldRole && oldRole.type === role) {
|
||||
return oldRole;
|
||||
}
|
||||
|
||||
const newRole = await this.db.workspaceDocUserRole.upsert({
|
||||
where: {
|
||||
workspaceId_docId_userId: {
|
||||
workspaceId,
|
||||
docId,
|
||||
userId,
|
||||
},
|
||||
},
|
||||
update: {
|
||||
type: role,
|
||||
},
|
||||
create: {
|
||||
workspaceId,
|
||||
docId,
|
||||
userId,
|
||||
type: role,
|
||||
},
|
||||
});
|
||||
|
||||
return newRole;
|
||||
}
|
||||
|
||||
async batchSetUserRoles(
|
||||
workspaceId: string,
|
||||
docId: string,
|
||||
userIds: string[],
|
||||
role: DocRole
|
||||
) {
|
||||
if (userIds.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (role === DocRole.Owner) {
|
||||
throw new CanNotBatchGrantDocOwnerPermissions();
|
||||
}
|
||||
|
||||
const result = await this.db.workspaceDocUserRole.createMany({
|
||||
skipDuplicates: true,
|
||||
data: userIds.map(userId => ({
|
||||
workspaceId,
|
||||
docId,
|
||||
userId,
|
||||
type: role,
|
||||
})),
|
||||
});
|
||||
|
||||
return result.count;
|
||||
}
|
||||
|
||||
async delete(workspaceId: string, docId: string, userId: string) {
|
||||
await this.db.workspaceDocUserRole.deleteMany({
|
||||
where: {
|
||||
workspaceId,
|
||||
docId,
|
||||
userId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async getOwner(workspaceId: string, docId: string) {
|
||||
return await this.db.workspaceDocUserRole.findFirst({
|
||||
where: {
|
||||
workspaceId,
|
||||
docId,
|
||||
type: DocRole.Owner,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async get(workspaceId: string, docId: string, userId: string) {
|
||||
return await this.db.workspaceDocUserRole.findUnique({
|
||||
where: {
|
||||
workspaceId_docId_userId: {
|
||||
workspaceId,
|
||||
docId,
|
||||
userId,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
count(workspaceId: string, docId: string) {
|
||||
return this.db.workspaceDocUserRole.count({
|
||||
where: {
|
||||
workspaceId,
|
||||
docId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async paginate(
|
||||
workspaceId: string,
|
||||
docId: string,
|
||||
pagination: PaginationInput
|
||||
): Promise<[WorkspaceDocUserRole[], number]> {
|
||||
return await Promise.all([
|
||||
this.db.workspaceDocUserRole.findMany({
|
||||
where: {
|
||||
workspaceId,
|
||||
docId,
|
||||
createdAt: pagination.after
|
||||
? {
|
||||
gte: pagination.after,
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: 'asc',
|
||||
},
|
||||
take: pagination.first,
|
||||
skip: pagination.offset + (pagination.after ? 1 : 0),
|
||||
}),
|
||||
this.count(workspaceId, docId),
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user