diff options
author | Rigel Kent <sendmemail@rigelk.eu> | 2020-04-19 14:11:40 +0200 |
---|---|---|
committer | Rigel Kent <par@rigelk.eu> | 2020-05-01 16:41:02 +0200 |
commit | e0a929179a9dc76e035ca7fda2b61d5ff46afbc5 (patch) | |
tree | 1e6615c612ad6995dcb1c3619342dbbc7db35034 /server | |
parent | aeb1bed9835b3b092832160245080d4023c14d91 (diff) | |
download | PeerTube-e0a929179a9dc76e035ca7fda2b61d5ff46afbc5.tar.gz PeerTube-e0a929179a9dc76e035ca7fda2b61d5ff46afbc5.tar.zst PeerTube-e0a929179a9dc76e035ca7fda2b61d5ff46afbc5.zip |
Add filter inputs for blacklisted videos and muted accounts/servers
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/api/server/server-blocklist.ts | 16 | ||||
-rw-r--r-- | server/controllers/api/users/my-blocklist.ts | 16 | ||||
-rw-r--r-- | server/controllers/api/videos/blacklist.ts | 8 | ||||
-rw-r--r-- | server/middlewares/validators/videos/video-blacklist.ts | 4 | ||||
-rw-r--r-- | server/models/account/account-blocklist.ts | 32 | ||||
-rw-r--r-- | server/models/server/server-blocklist.ts | 17 | ||||
-rw-r--r-- | server/models/utils.ts | 15 | ||||
-rw-r--r-- | server/models/video/video-abuse.ts | 18 | ||||
-rw-r--r-- | server/models/video/video-blacklist.ts | 13 |
9 files changed, 109 insertions, 30 deletions
diff --git a/server/controllers/api/server/server-blocklist.ts b/server/controllers/api/server/server-blocklist.ts index d165db191..ffb7814fa 100644 --- a/server/controllers/api/server/server-blocklist.ts +++ b/server/controllers/api/server/server-blocklist.ts | |||
@@ -82,7 +82,13 @@ export { | |||
82 | async function listBlockedAccounts (req: express.Request, res: express.Response) { | 82 | async function listBlockedAccounts (req: express.Request, res: express.Response) { |
83 | const serverActor = await getServerActor() | 83 | const serverActor = await getServerActor() |
84 | 84 | ||
85 | const resultList = await AccountBlocklistModel.listForApi(serverActor.Account.id, req.query.start, req.query.count, req.query.sort) | 85 | const resultList = await AccountBlocklistModel.listForApi({ |
86 | start: req.query.start, | ||
87 | count: req.query.count, | ||
88 | sort: req.query.sort, | ||
89 | search: req.query.search, | ||
90 | accountId: serverActor.Account.id | ||
91 | }) | ||
86 | 92 | ||
87 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | 93 | return res.json(getFormattedObjects(resultList.data, resultList.total)) |
88 | } | 94 | } |
@@ -107,7 +113,13 @@ async function unblockAccount (req: express.Request, res: express.Response) { | |||
107 | async function listBlockedServers (req: express.Request, res: express.Response) { | 113 | async function listBlockedServers (req: express.Request, res: express.Response) { |
108 | const serverActor = await getServerActor() | 114 | const serverActor = await getServerActor() |
109 | 115 | ||
110 | const resultList = await ServerBlocklistModel.listForApi(serverActor.Account.id, req.query.start, req.query.count, req.query.sort) | 116 | const resultList = await ServerBlocklistModel.listForApi({ |
117 | start: req.query.start, | ||
118 | count: req.query.count, | ||
119 | sort: req.query.sort, | ||
120 | search: req.query.search, | ||
121 | accountId: serverActor.Account.id | ||
122 | }) | ||
111 | 123 | ||
112 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | 124 | return res.json(getFormattedObjects(resultList.data, resultList.total)) |
113 | } | 125 | } |
diff --git a/server/controllers/api/users/my-blocklist.ts b/server/controllers/api/users/my-blocklist.ts index 713c16022..3a44376f2 100644 --- a/server/controllers/api/users/my-blocklist.ts +++ b/server/controllers/api/users/my-blocklist.ts | |||
@@ -74,7 +74,13 @@ export { | |||
74 | async function listBlockedAccounts (req: express.Request, res: express.Response) { | 74 | async function listBlockedAccounts (req: express.Request, res: express.Response) { |
75 | const user = res.locals.oauth.token.User | 75 | const user = res.locals.oauth.token.User |
76 | 76 | ||
77 | const resultList = await AccountBlocklistModel.listForApi(user.Account.id, req.query.start, req.query.count, req.query.sort) | 77 | const resultList = await AccountBlocklistModel.listForApi({ |
78 | start: req.query.start, | ||
79 | count: req.query.count, | ||
80 | sort: req.query.sort, | ||
81 | search: req.query.search, | ||
82 | accountId: user.Account.id | ||
83 | }) | ||
78 | 84 | ||
79 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | 85 | return res.json(getFormattedObjects(resultList.data, resultList.total)) |
80 | } | 86 | } |
@@ -99,7 +105,13 @@ async function unblockAccount (req: express.Request, res: express.Response) { | |||
99 | async function listBlockedServers (req: express.Request, res: express.Response) { | 105 | async function listBlockedServers (req: express.Request, res: express.Response) { |
100 | const user = res.locals.oauth.token.User | 106 | const user = res.locals.oauth.token.User |
101 | 107 | ||
102 | const resultList = await ServerBlocklistModel.listForApi(user.Account.id, req.query.start, req.query.count, req.query.sort) | 108 | const resultList = await ServerBlocklistModel.listForApi({ |
109 | start: req.query.start, | ||
110 | count: req.query.count, | ||
111 | sort: req.query.sort, | ||
112 | search: req.query.search, | ||
113 | accountId: user.Account.id | ||
114 | }) | ||
103 | 115 | ||
104 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | 116 | return res.json(getFormattedObjects(resultList.data, resultList.total)) |
105 | } | 117 | } |
diff --git a/server/controllers/api/videos/blacklist.ts b/server/controllers/api/videos/blacklist.ts index 2a667480d..c4aa79cd2 100644 --- a/server/controllers/api/videos/blacklist.ts +++ b/server/controllers/api/videos/blacklist.ts | |||
@@ -102,7 +102,13 @@ async function updateVideoBlacklistController (req: express.Request, res: expres | |||
102 | } | 102 | } |
103 | 103 | ||
104 | async function listBlacklist (req: express.Request, res: express.Response) { | 104 | async function listBlacklist (req: express.Request, res: express.Response) { |
105 | const resultList = await VideoBlacklistModel.listForApi(req.query.start, req.query.count, req.query.sort, req.query.type) | 105 | const resultList = await VideoBlacklistModel.listForApi({ |
106 | start: req.query.start, | ||
107 | count: req.query.count, | ||
108 | sort: req.query.sort, | ||
109 | search: req.query.search, | ||
110 | type: req.query.type | ||
111 | }) | ||
106 | 112 | ||
107 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | 113 | return res.json(getFormattedObjects(resultList.data, resultList.total)) |
108 | } | 114 | } |
diff --git a/server/middlewares/validators/videos/video-blacklist.ts b/server/middlewares/validators/videos/video-blacklist.ts index 5440e57e7..4bd6a8333 100644 --- a/server/middlewares/validators/videos/video-blacklist.ts +++ b/server/middlewares/validators/videos/video-blacklist.ts | |||
@@ -69,6 +69,10 @@ const videosBlacklistFiltersValidator = [ | |||
69 | query('type') | 69 | query('type') |
70 | .optional() | 70 | .optional() |
71 | .custom(isVideoBlacklistTypeValid).withMessage('Should have a valid video blacklist type attribute'), | 71 | .custom(isVideoBlacklistTypeValid).withMessage('Should have a valid video blacklist type attribute'), |
72 | query('search') | ||
73 | .optional() | ||
74 | .not() | ||
75 | .isEmpty().withMessage('Should have a valid search'), | ||
72 | 76 | ||
73 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 77 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
74 | logger.debug('Checking videos blacklist filters query', { parameters: req.query }) | 78 | logger.debug('Checking videos blacklist filters query', { parameters: req.query }) |
diff --git a/server/models/account/account-blocklist.ts b/server/models/account/account-blocklist.ts index e2f66d733..fe2d5d010 100644 --- a/server/models/account/account-blocklist.ts +++ b/server/models/account/account-blocklist.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' | 1 | import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' |
2 | import { AccountModel } from './account' | 2 | import { AccountModel } from './account' |
3 | import { getSort } from '../utils' | 3 | import { getSort, searchAttribute } from '../utils' |
4 | import { AccountBlock } from '../../../shared/models/blocklist' | 4 | import { AccountBlock } from '../../../shared/models/blocklist' |
5 | import { Op } from 'sequelize' | 5 | import { Op } from 'sequelize' |
6 | import * as Bluebird from 'bluebird' | 6 | import * as Bluebird from 'bluebird' |
@@ -111,16 +111,36 @@ export class AccountBlocklistModel extends Model<AccountBlocklistModel> { | |||
111 | return AccountBlocklistModel.findOne(query) | 111 | return AccountBlocklistModel.findOne(query) |
112 | } | 112 | } |
113 | 113 | ||
114 | static listForApi (accountId: number, start: number, count: number, sort: string) { | 114 | static listForApi (parameters: { |
115 | start: number | ||
116 | count: number | ||
117 | sort: string | ||
118 | search?: string | ||
119 | accountId: number | ||
120 | }) { | ||
121 | const { start, count, sort, search, accountId } = parameters | ||
122 | |||
115 | const query = { | 123 | const query = { |
116 | offset: start, | 124 | offset: start, |
117 | limit: count, | 125 | limit: count, |
118 | order: getSort(sort), | 126 | order: getSort(sort) |
119 | where: { | 127 | } |
120 | accountId | 128 | |
121 | } | 129 | const where = { |
130 | accountId | ||
122 | } | 131 | } |
123 | 132 | ||
133 | if (search) { | ||
134 | Object.assign(where, { | ||
135 | [Op.or]: [ | ||
136 | { ...searchAttribute(search, '$BlockedAccount.name$') }, | ||
137 | { ...searchAttribute(search, '$BlockedAccount.Actor.url$') } | ||
138 | ] | ||
139 | }) | ||
140 | } | ||
141 | |||
142 | Object.assign(query, { where }) | ||
143 | |||
124 | return AccountBlocklistModel | 144 | return AccountBlocklistModel |
125 | .scope([ ScopeNames.WITH_ACCOUNTS ]) | 145 | .scope([ ScopeNames.WITH_ACCOUNTS ]) |
126 | .findAndCountAll<MAccountBlocklistAccounts>(query) | 146 | .findAndCountAll<MAccountBlocklistAccounts>(query) |
diff --git a/server/models/server/server-blocklist.ts b/server/models/server/server-blocklist.ts index 883ae47ab..764203d2c 100644 --- a/server/models/server/server-blocklist.ts +++ b/server/models/server/server-blocklist.ts | |||
@@ -2,7 +2,7 @@ import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, Updated | |||
2 | import { AccountModel } from '../account/account' | 2 | import { AccountModel } from '../account/account' |
3 | import { ServerModel } from './server' | 3 | import { ServerModel } from './server' |
4 | import { ServerBlock } from '../../../shared/models/blocklist' | 4 | import { ServerBlock } from '../../../shared/models/blocklist' |
5 | import { getSort } from '../utils' | 5 | import { getSort, searchAttribute } from '../utils' |
6 | import * as Bluebird from 'bluebird' | 6 | import * as Bluebird from 'bluebird' |
7 | import { MServerBlocklist, MServerBlocklistAccountServer, MServerBlocklistFormattable } from '@server/typings/models' | 7 | import { MServerBlocklist, MServerBlocklistAccountServer, MServerBlocklistFormattable } from '@server/typings/models' |
8 | import { Op } from 'sequelize' | 8 | import { Op } from 'sequelize' |
@@ -120,16 +120,27 @@ export class ServerBlocklistModel extends Model<ServerBlocklistModel> { | |||
120 | return ServerBlocklistModel.findOne(query) | 120 | return ServerBlocklistModel.findOne(query) |
121 | } | 121 | } |
122 | 122 | ||
123 | static listForApi (accountId: number, start: number, count: number, sort: string) { | 123 | static listForApi (parameters: { |
124 | start: number | ||
125 | count: number | ||
126 | sort: string | ||
127 | search?: string | ||
128 | accountId: number | ||
129 | }) { | ||
130 | const { start, count, sort, search, accountId } = parameters | ||
131 | |||
124 | const query = { | 132 | const query = { |
125 | offset: start, | 133 | offset: start, |
126 | limit: count, | 134 | limit: count, |
127 | order: getSort(sort), | 135 | order: getSort(sort), |
128 | where: { | 136 | where: { |
129 | accountId | 137 | accountId, |
138 | ...searchAttribute(search, '$BlockedServer.host$') | ||
130 | } | 139 | } |
131 | } | 140 | } |
132 | 141 | ||
142 | console.log(search) | ||
143 | |||
133 | return ServerBlocklistModel | 144 | return ServerBlocklistModel |
134 | .scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_SERVER ]) | 145 | .scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_SERVER ]) |
135 | .findAndCountAll<MServerBlocklistAccountServer>(query) | 146 | .findAndCountAll<MServerBlocklistAccountServer>(query) |
diff --git a/server/models/utils.ts b/server/models/utils.ts index 06ff05864..7137419a2 100644 --- a/server/models/utils.ts +++ b/server/models/utils.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { Model, Sequelize } from 'sequelize-typescript' | 1 | import { Model, Sequelize } from 'sequelize-typescript' |
2 | import validator from 'validator' | 2 | import validator from 'validator' |
3 | import { Col } from 'sequelize/types/lib/utils' | 3 | import { Col } from 'sequelize/types/lib/utils' |
4 | import { literal, OrderItem } from 'sequelize' | 4 | import { literal, OrderItem, Op } from 'sequelize' |
5 | 5 | ||
6 | type Primitive = string | Function | number | boolean | Symbol | undefined | null | 6 | type Primitive = string | Function | number | boolean | Symbol | undefined | null |
7 | type DeepOmitHelper<T, K extends keyof T> = { | 7 | type DeepOmitHelper<T, K extends keyof T> = { |
@@ -207,6 +207,16 @@ function buildDirectionAndField (value: string) { | |||
207 | return { direction, field } | 207 | return { direction, field } |
208 | } | 208 | } |
209 | 209 | ||
210 | function searchAttribute (sourceField, targetField) { | ||
211 | return sourceField | ||
212 | ? { | ||
213 | [targetField]: { | ||
214 | [Op.iLike]: `%${sourceField}%` | ||
215 | } | ||
216 | } | ||
217 | : {} | ||
218 | } | ||
219 | |||
210 | // --------------------------------------------------------------------------- | 220 | // --------------------------------------------------------------------------- |
211 | 221 | ||
212 | export { | 222 | export { |
@@ -228,7 +238,8 @@ export { | |||
228 | parseAggregateResult, | 238 | parseAggregateResult, |
229 | getFollowsSort, | 239 | getFollowsSort, |
230 | buildDirectionAndField, | 240 | buildDirectionAndField, |
231 | createSafeIn | 241 | createSafeIn, |
242 | searchAttribute | ||
232 | } | 243 | } |
233 | 244 | ||
234 | // --------------------------------------------------------------------------- | 245 | // --------------------------------------------------------------------------- |
diff --git a/server/models/video/video-abuse.ts b/server/models/video/video-abuse.ts index d68608ca6..e8c3bd823 100644 --- a/server/models/video/video-abuse.ts +++ b/server/models/video/video-abuse.ts | |||
@@ -9,7 +9,7 @@ import { | |||
9 | isVideoAbuseStateValid | 9 | isVideoAbuseStateValid |
10 | } from '../../helpers/custom-validators/video-abuses' | 10 | } from '../../helpers/custom-validators/video-abuses' |
11 | import { AccountModel } from '../account/account' | 11 | import { AccountModel } from '../account/account' |
12 | import { buildBlockedAccountSQL, getSort, throwIfNotValid } from '../utils' | 12 | import { buildBlockedAccountSQL, getSort, throwIfNotValid, searchAttribute } from '../utils' |
13 | import { VideoModel } from './video' | 13 | import { VideoModel } from './video' |
14 | import { VideoAbuseState, VideoDetails } from '../../../shared' | 14 | import { VideoAbuseState, VideoDetails } from '../../../shared' |
15 | import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants' | 15 | import { CONSTRAINTS_FIELDS, VIDEO_ABUSE_STATES } from '../../initializers/constants' |
@@ -17,8 +17,8 @@ import { MUserAccountId, MVideoAbuse, MVideoAbuseFormattable, MVideoAbuseVideo } | |||
17 | import * as Bluebird from 'bluebird' | 17 | import * as Bluebird from 'bluebird' |
18 | import { literal, Op } from 'sequelize' | 18 | import { literal, Op } from 'sequelize' |
19 | import { ThumbnailModel } from './thumbnail' | 19 | import { ThumbnailModel } from './thumbnail' |
20 | import { VideoChannelModel } from './video-channel' | ||
21 | import { VideoBlacklistModel } from './video-blacklist' | 20 | import { VideoBlacklistModel } from './video-blacklist' |
21 | import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel' | ||
22 | 22 | ||
23 | export enum ScopeNames { | 23 | export enum ScopeNames { |
24 | FOR_API = 'FOR_API' | 24 | FOR_API = 'FOR_API' |
@@ -33,12 +33,6 @@ export enum ScopeNames { | |||
33 | serverAccountId: number | 33 | serverAccountId: number |
34 | userAccountId: any | 34 | userAccountId: any |
35 | }) => { | 35 | }) => { |
36 | const search = (sourceField, targetField) => sourceField ? ({ | ||
37 | [targetField]: { | ||
38 | [Op.iLike]: `%${sourceField}%` | ||
39 | } | ||
40 | }) : {} | ||
41 | |||
42 | let where = { | 36 | let where = { |
43 | reporterAccountId: { | 37 | reporterAccountId: { |
44 | [Op.notIn]: literal('(' + buildBlockedAccountSQL(options.serverAccountId, options.userAccountId) + ')') | 38 | [Op.notIn]: literal('(' + buildBlockedAccountSQL(options.serverAccountId, options.userAccountId) + ')') |
@@ -148,19 +142,19 @@ export enum ScopeNames { | |||
148 | { | 142 | { |
149 | model: AccountModel, | 143 | model: AccountModel, |
150 | required: true, | 144 | required: true, |
151 | where: { ...search(options.searchReporter, 'name') } | 145 | where: { ...searchAttribute(options.searchReporter, 'name') } |
152 | }, | 146 | }, |
153 | { | 147 | { |
154 | model: VideoModel, | 148 | model: VideoModel, |
155 | required: false, | 149 | required: false, |
156 | where: { ...search(options.searchVideo, 'name') }, | 150 | where: { ...searchAttribute(options.searchVideo, 'name') }, |
157 | include: [ | 151 | include: [ |
158 | { | 152 | { |
159 | model: ThumbnailModel | 153 | model: ThumbnailModel |
160 | }, | 154 | }, |
161 | { | 155 | { |
162 | model: VideoChannelModel.scope([ 'WITH_ACTOR', 'WITH_ACCOUNT' ]), | 156 | model: VideoChannelModel.scope({ method: [ VideoChannelScopeNames.SUMMARY, { withAccount: true } as SummaryOptions ] }), |
163 | where: { ...search(options.searchVideoChannel, 'name') } | 157 | where: { ...searchAttribute(options.searchVideoChannel, 'name') } |
164 | }, | 158 | }, |
165 | { | 159 | { |
166 | attributes: [ 'id', 'reason', 'unfederated' ], | 160 | attributes: [ 'id', 'reason', 'unfederated' ], |
diff --git a/server/models/video/video-blacklist.ts b/server/models/video/video-blacklist.ts index 694983cb3..680eba471 100644 --- a/server/models/video/video-blacklist.ts +++ b/server/models/video/video-blacklist.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' | 1 | import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' |
2 | import { getBlacklistSort, SortType, throwIfNotValid } from '../utils' | 2 | import { getBlacklistSort, SortType, throwIfNotValid, searchAttribute } from '../utils' |
3 | import { VideoModel } from './video' | 3 | import { VideoModel } from './video' |
4 | import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel' | 4 | import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel' |
5 | import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist' | 5 | import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist' |
@@ -54,7 +54,15 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> { | |||
54 | }) | 54 | }) |
55 | Video: VideoModel | 55 | Video: VideoModel |
56 | 56 | ||
57 | static listForApi (start: number, count: number, sort: SortType, type?: VideoBlacklistType) { | 57 | static listForApi (parameters: { |
58 | start: number | ||
59 | count: number | ||
60 | sort: SortType | ||
61 | search?: string | ||
62 | type?: VideoBlacklistType | ||
63 | }) { | ||
64 | const { start, count, sort, search, type } = parameters | ||
65 | |||
58 | function buildBaseQuery (): FindOptions { | 66 | function buildBaseQuery (): FindOptions { |
59 | return { | 67 | return { |
60 | offset: start, | 68 | offset: start, |
@@ -70,6 +78,7 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> { | |||
70 | { | 78 | { |
71 | model: VideoModel, | 79 | model: VideoModel, |
72 | required: true, | 80 | required: true, |
81 | where: { ...searchAttribute(search, 'name') }, | ||
73 | include: [ | 82 | include: [ |
74 | { | 83 | { |
75 | model: VideoChannelModel.scope({ method: [ VideoChannelScopeNames.SUMMARY, { withAccount: true } as SummaryOptions ] }), | 84 | model: VideoChannelModel.scope({ method: [ VideoChannelScopeNames.SUMMARY, { withAccount: true } as SummaryOptions ] }), |