Skip to content

Commit

Permalink
1ファイルの容量制限 (#104)
Browse files Browse the repository at this point in the history
  • Loading branch information
kozakura913 authored Jun 21, 2024
1 parent 6929f9e commit f116907
Show file tree
Hide file tree
Showing 11 changed files with 54 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG_yojo.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

### General
- メディアプロキシurlと拡大画像urlを分割
- 1ファイルの容量をロールでも制限できるように

### Client
- enhance: ノートとユーザーの検索時に照会を行うかが選択できるようになりました
Expand Down
4 changes: 4 additions & 0 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7324,6 +7324,10 @@ export interface Locale extends ILocale {
* ドライブ容量
*/
"driveCapacity": string;
/**
* ファイルサイズ上限
*/
"fileSizeLimit": string;
/**
* ファイルにNSFWを常に付与
*/
Expand Down
1 change: 1 addition & 0 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1898,6 +1898,7 @@ _role:
canManageCustomEmojis: "カスタム絵文字の管理"
canManageAvatarDecorations: "アバターデコレーションの管理"
driveCapacity: "ドライブ容量"
fileSizeLimit: "ファイルサイズ上限"
alwaysMarkNsfw: "ファイルにNSFWを常に付与"
pinMax: "ノートのピン留めの最大数"
antennaMax: "アンテナの作成可能数"
Expand Down
6 changes: 6 additions & 0 deletions packages/backend/src/core/DriveService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,12 @@ export class DriveService {
sensitiveThresholdForPorn: 0.75,
enableSensitiveMediaDetectionForVideos: instance.enableSensitiveMediaDetectionForVideos,
});
//ファイル単位の容量制限チェック
if (user == null) {
//system user skip
} else if (info.size > (await this.roleService.getUserPolicies(user.id)).fileSizeLimit * 1024 * 1024) {
throw new IdentifiableError('e5989b6d-ae66-49ed-88af-516ded10ca0c', 'File size limit over');
}
this.registerLogger.info(`${JSON.stringify(info)}`);

// 現状 false positive が多すぎて実用に耐えない
Expand Down
3 changes: 3 additions & 0 deletions packages/backend/src/core/RoleService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export type RolePolicies = {
userEachUserListsLimit: number;
rateLimitFactor: number;
avatarDecorationLimit: number;
fileSizeLimit: number;
};

export const DEFAULT_POLICIES: RolePolicies = {
Expand Down Expand Up @@ -87,6 +88,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
userEachUserListsLimit: 50,
rateLimitFactor: 1,
avatarDecorationLimit: 1,
fileSizeLimit: 50,
};

@Injectable()
Expand Down Expand Up @@ -352,6 +354,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
userEachUserListsLimit: calc('userEachUserListsLimit', vs => Math.max(...vs)),
rateLimitFactor: calc('rateLimitFactor', vs => Math.max(...vs)),
avatarDecorationLimit: calc('avatarDecorationLimit', vs => Math.max(...vs)),
fileSizeLimit: calc('fileSizeLimit', vs => Math.max(...vs)),
};
}

Expand Down
4 changes: 4 additions & 0 deletions packages/backend/src/models/json-schema/role.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,10 @@ export const packedRolePoliciesSchema = {
type: 'integer',
optional: false, nullable: false,
},
fileSizeLimit: {
type: 'integer',
optional: false, nullable: false,
},
canEditNote: {
type: 'boolean',
optional: false, nullable: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ export const meta = {
code: 'NO_FREE_SPACE',
id: 'd08dbc37-a6a9-463a-8c47-96c32ab5f064',
},
invalidFileSize: {
message: 'File size exceeds limit.',
code: 'INVALID_FILE_SIZE',
id: '9068668f-0465-4c0e-8341-1c52fd6f5ab3',
},
},
} as const;

Expand Down Expand Up @@ -114,6 +119,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (err instanceof IdentifiableError) {
if (err.id === '282f77bf-5816-4f72-9264-aa14d8261a21') throw new ApiError(meta.errors.inappropriate);
if (err.id === 'c6244ed2-a39a-4e1c-bf93-f0fbd7764fa6') throw new ApiError(meta.errors.noFreeSpace);
if (err.id === 'e5989b6d-ae66-49ed-88af-516ded10ca0c') throw new ApiError(meta.errors.invalidFileSize);
}
throw new ApiError();
} finally {
Expand Down
1 change: 1 addition & 0 deletions packages/cherrypick-js/src/autogen/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5006,6 +5006,7 @@ export type components = {
userEachUserListsLimit: number;
rateLimitFactor: number;
avatarDecorationLimit: number;
fileSizeLimit: number;
canEditNote: boolean;
};
ReversiGameLite: {
Expand Down
1 change: 1 addition & 0 deletions packages/frontend/src/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ export const ROLE_POLICIES = [
'userEachUserListsLimit',
'rateLimitFactor',
'avatarDecorationLimit',
'fileSizeLimit',
] as const;

// なんか動かない
Expand Down
20 changes: 20 additions & 0 deletions packages/frontend/src/pages/admin/roles.editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,26 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkRange>
</div>
</MkFolder>
<MkFolder v-if="matchQuery([i18n.ts._role._options.fileSizeLimit, 'fileSizeLimit'])">
<template #label>{{ i18n.ts._role._options.fileSizeLimit }}</template>
<template #suffix>
<span v-if="role.policies.fileSizeLimit.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
<span v-else>{{ role.policies.fileSizeLimit.value + 'MB' }}</span>
<span :class="$style.priorityIndicator"><i :class="getPriorityIcon(role.policies.fileSizeLimit)"></i></span>
</template>
<div class="_gaps">
<MkSwitch v-model="role.policies.fileSizeLimit.useDefault" :readonly="readonly">
<template #label>{{ i18n.ts._role.useBaseValue }}</template>
</MkSwitch>
<MkInput v-model="role.policies.fileSizeLimit.value" type="number" :min="0">
<template #label>{{ i18n.ts._role._options.fileSizeLimit }}</template>
<template #suffix>MB</template>
</MkInput>
<MkRange v-model="role.policies.fileSizeLimit.priority" :min="0" :max="2" :step="1" easing :textConverter="(v) => v === 0 ? i18n.ts._role._priority.low : v === 1 ? i18n.ts._role._priority.middle : v === 2 ? i18n.ts._role._priority.high : ''">
<template #label>{{ i18n.ts._role.priority }}</template>
</MkRange>
</div>
</MkFolder>
</div>
</FormSlot>
</div>
Expand Down
7 changes: 7 additions & 0 deletions packages/frontend/src/pages/admin/roles.vue
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,13 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkInput v-model="policies.avatarDecorationLimit" type="number" :min="0">
</MkInput>
</MkFolder>
<MkFolder v-if="matchQuery([i18n.ts._role._options.fileSizeLimit, 'fileSizeLimit'])">
<template #label>{{ i18n.ts._role._options.fileSizeLimit }}</template>
<template #suffix>{{ policies.fileSizeLimit }}MB</template>
<MkInput v-model="policies.fileSizeLimit" type="number" :min="0">
<template #suffix>MB</template>
</MkInput>
</MkFolder>

<MkButton primary rounded @click="updateBaseRole">{{ i18n.ts.save }}</MkButton>
</div>
Expand Down

0 comments on commit f116907

Please sign in to comment.