From 0d0e8dd0904b380b70e19ebcb4763d65601c4632 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 10 Nov 2017 14:34:45 +0100 Subject: Continue activitypub --- .../custom-validators/activitypub/activity.ts | 34 ++++ .../helpers/custom-validators/activitypub/index.ts | 1 + .../helpers/custom-validators/activitypub/misc.ts | 12 +- .../custom-validators/activitypub/videos.ts | 223 +++++++-------------- 4 files changed, 124 insertions(+), 146 deletions(-) create mode 100644 server/helpers/custom-validators/activitypub/activity.ts (limited to 'server/helpers/custom-validators/activitypub') diff --git a/server/helpers/custom-validators/activitypub/activity.ts b/server/helpers/custom-validators/activitypub/activity.ts new file mode 100644 index 000000000..dd671c4cf --- /dev/null +++ b/server/helpers/custom-validators/activitypub/activity.ts @@ -0,0 +1,34 @@ +import * as validator from 'validator' +import { + isVideoChannelCreateActivityValid, + isVideoTorrentAddActivityValid, + isVideoTorrentUpdateActivityValid, + isVideoChannelUpdateActivityValid +} from './videos' + +function isRootActivityValid (activity: any) { + return Array.isArray(activity['@context']) && + ( + (activity.type === 'Collection' || activity.type === 'OrderedCollection') && + validator.isInt(activity.totalItems, { min: 0 }) && + Array.isArray(activity.items) + ) || + ( + validator.isURL(activity.id) && + validator.isURL(activity.actor) + ) +} + +function isActivityValid (activity: any) { + return isVideoTorrentAddActivityValid(activity) || + isVideoChannelCreateActivityValid(activity) || + isVideoTorrentUpdateActivityValid(activity) || + isVideoChannelUpdateActivityValid(activity) +} + +// --------------------------------------------------------------------------- + +export { + isRootActivityValid, + isActivityValid +} diff --git a/server/helpers/custom-validators/activitypub/index.ts b/server/helpers/custom-validators/activitypub/index.ts index 800f0ddf3..0eba06a7b 100644 --- a/server/helpers/custom-validators/activitypub/index.ts +++ b/server/helpers/custom-validators/activitypub/index.ts @@ -1,4 +1,5 @@ export * from './account' +export * from './activity' export * from './signature' export * from './misc' export * from './videos' diff --git a/server/helpers/custom-validators/activitypub/misc.ts b/server/helpers/custom-validators/activitypub/misc.ts index 806d33483..f049f5a8c 100644 --- a/server/helpers/custom-validators/activitypub/misc.ts +++ b/server/helpers/custom-validators/activitypub/misc.ts @@ -12,6 +12,16 @@ function isActivityPubUrlValid (url: string) { return exists(url) && validator.isURL(url, isURLOptions) } +function isBaseActivityValid (activity: any, type: string) { + return Array.isArray(activity['@context']) && + activity.type === type && + validator.isURL(activity.id) && + validator.isURL(activity.actor) && + Array.isArray(activity.to) && + activity.to.every(t => validator.isURL(t)) +} + export { - isActivityPubUrlValid + isActivityPubUrlValid, + isBaseActivityValid } diff --git a/server/helpers/custom-validators/activitypub/videos.ts b/server/helpers/custom-validators/activitypub/videos.ts index e0ffba679..9233a1359 100644 --- a/server/helpers/custom-validators/activitypub/videos.ts +++ b/server/helpers/custom-validators/activitypub/videos.ts @@ -1,184 +1,117 @@ -import 'express-validator' -import { has, values } from 'lodash' +import * as validator from 'validator' import { - REQUEST_ENDPOINTS, - REQUEST_ENDPOINT_ACTIONS, - REQUEST_VIDEO_EVENT_TYPES + ACTIVITY_PUB } from '../../../initializers' -import { isArray, isDateValid, isUUIDValid } from '../misc' +import { isDateValid, isUUIDValid } from '../misc' import { - isVideoThumbnailDataValid, - isVideoAbuseReasonValid, - isVideoAbuseReporterUsernameValid, isVideoViewsValid, - isVideoLikesValid, - isVideoDislikesValid, - isVideoEventCountValid, - isRemoteVideoCategoryValid, - isRemoteVideoLicenceValid, - isRemoteVideoLanguageValid, isVideoNSFWValid, isVideoTruncatedDescriptionValid, isVideoDurationValid, - isVideoFileInfoHashValid, isVideoNameValid, - isVideoTagsValid, - isVideoFileExtnameValid, - isVideoFileResolutionValid + isVideoTagValid } from '../videos' import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../video-channels' -import { isVideoAuthorNameValid } from '../video-authors' - -const ENDPOINT_ACTIONS = REQUEST_ENDPOINT_ACTIONS[REQUEST_ENDPOINTS.VIDEOS] - -const checkers: { [ id: string ]: (obj: any) => boolean } = {} -checkers[ENDPOINT_ACTIONS.ADD_VIDEO] = checkAddVideo -checkers[ENDPOINT_ACTIONS.UPDATE_VIDEO] = checkUpdateVideo -checkers[ENDPOINT_ACTIONS.REMOVE_VIDEO] = checkRemoveVideo -checkers[ENDPOINT_ACTIONS.REPORT_ABUSE] = checkReportVideo -checkers[ENDPOINT_ACTIONS.ADD_CHANNEL] = checkAddVideoChannel -checkers[ENDPOINT_ACTIONS.UPDATE_CHANNEL] = checkUpdateVideoChannel -checkers[ENDPOINT_ACTIONS.REMOVE_CHANNEL] = checkRemoveVideoChannel -checkers[ENDPOINT_ACTIONS.ADD_AUTHOR] = checkAddAuthor -checkers[ENDPOINT_ACTIONS.REMOVE_AUTHOR] = checkRemoveAuthor - -function removeBadRequestVideos (requests: any[]) { - for (let i = requests.length - 1; i >= 0 ; i--) { - const request = requests[i] - const video = request.data - - if ( - !video || - checkers[request.type] === undefined || - checkers[request.type](video) === false - ) { - requests.splice(i, 1) - } - } +import { isBaseActivityValid } from './misc' + +function isVideoTorrentAddActivityValid (activity: any) { + return isBaseActivityValid(activity, 'Add') && + isVideoTorrentObjectValid(activity.object) +} + +function isVideoTorrentUpdateActivityValid (activity: any) { + return isBaseActivityValid(activity, 'Update') && + isVideoTorrentObjectValid(activity.object) } -function removeBadRequestVideosQadu (requests: any[]) { - for (let i = requests.length - 1; i >= 0 ; i--) { - const request = requests[i] - const video = request.data - - if ( - !video || - ( - isUUIDValid(video.uuid) && - (has(video, 'views') === false || isVideoViewsValid(video.views)) && - (has(video, 'likes') === false || isVideoLikesValid(video.likes)) && - (has(video, 'dislikes') === false || isVideoDislikesValid(video.dislikes)) - ) === false - ) { - requests.splice(i, 1) - } - } +function isVideoTorrentObjectValid (video: any) { + return video.type === 'Video' && + isVideoNameValid(video.name) && + isVideoDurationValid(video.duration) && + isUUIDValid(video.uuid) && + setValidRemoteTags(video) && + isRemoteIdentifierValid(video.category) && + isRemoteIdentifierValid(video.licence) && + isRemoteIdentifierValid(video.language) && + isVideoViewsValid(video.video) && + isVideoNSFWValid(video.nsfw) && + isDateValid(video.published) && + isDateValid(video.updated) && + isRemoteVideoContentValid(video.mediaType, video.content) && + isRemoteVideoIconValid(video.icon) && + setValidRemoteVideoUrls(video.url) } -function removeBadRequestVideosEvents (requests: any[]) { - for (let i = requests.length - 1; i >= 0 ; i--) { - const request = requests[i] - const eventData = request.data - - if ( - !eventData || - ( - isUUIDValid(eventData.uuid) && - values(REQUEST_VIDEO_EVENT_TYPES).indexOf(eventData.eventType) !== -1 && - isVideoEventCountValid(eventData.count) - ) === false - ) { - requests.splice(i, 1) - } - } +function isVideoChannelCreateActivityValid (activity: any) { + return isBaseActivityValid(activity, 'Create') && + isVideoChannelObjectValid(activity.object) +} + +function isVideoChannelUpdateActivityValid (activity: any) { + return isBaseActivityValid(activity, 'Update') && + isVideoChannelObjectValid(activity.object) +} + +function isVideoChannelObjectValid (videoChannel: any) { + return videoChannel.type === 'VideoChannel' && + isVideoChannelNameValid(videoChannel.name) && + isVideoChannelDescriptionValid(videoChannel.description) && + isUUIDValid(videoChannel.uuid) } // --------------------------------------------------------------------------- export { - removeBadRequestVideos, - removeBadRequestVideosQadu, - removeBadRequestVideosEvents + isVideoTorrentAddActivityValid, + isVideoChannelCreateActivityValid, + isVideoTorrentUpdateActivityValid, + isVideoChannelUpdateActivityValid } // --------------------------------------------------------------------------- -function isCommonVideoAttributesValid (video: any) { - return isDateValid(video.createdAt) && - isDateValid(video.updatedAt) && - isRemoteVideoCategoryValid(video.category) && - isRemoteVideoLicenceValid(video.licence) && - isRemoteVideoLanguageValid(video.language) && - isVideoNSFWValid(video.nsfw) && - isVideoTruncatedDescriptionValid(video.truncatedDescription) && - isVideoDurationValid(video.duration) && - isVideoNameValid(video.name) && - isVideoTagsValid(video.tags) && - isUUIDValid(video.uuid) && - isVideoViewsValid(video.views) && - isVideoLikesValid(video.likes) && - isVideoDislikesValid(video.dislikes) && - isArray(video.files) && - video.files.every(videoFile => { - if (!videoFile) return false - - return ( - isVideoFileInfoHashValid(videoFile.infoHash) && - isVideoFileExtnameValid(videoFile.extname) && - isVideoFileResolutionValid(videoFile.resolution) - ) - }) -} +function setValidRemoteTags (video: any) { + if (Array.isArray(video.tag) === false) return false -function checkAddVideo (video: any) { - return isCommonVideoAttributesValid(video) && - isUUIDValid(video.channelUUID) && - isVideoThumbnailDataValid(video.thumbnailData) -} + const newTag = video.tag.filter(t => { + return t.type === 'Hashtag' && + isVideoTagValid(t.name) + }) -function checkUpdateVideo (video: any) { - return isCommonVideoAttributesValid(video) + video.tag = newTag + return true } -function checkRemoveVideo (video: any) { - return isUUIDValid(video.uuid) +function isRemoteIdentifierValid (data: any) { + return validator.isInt(data.identifier, { min: 0 }) } -function checkReportVideo (abuse: any) { - return isUUIDValid(abuse.videoUUID) && - isVideoAbuseReasonValid(abuse.reportReason) && - isVideoAbuseReporterUsernameValid(abuse.reporterUsername) +function isRemoteVideoContentValid (mediaType: string, content: string) { + return mediaType === 'text/markdown' && isVideoTruncatedDescriptionValid(content) } -function checkAddVideoChannel (videoChannel: any) { - return isUUIDValid(videoChannel.uuid) && - isVideoChannelNameValid(videoChannel.name) && - isVideoChannelDescriptionValid(videoChannel.description) && - isDateValid(videoChannel.createdAt) && - isDateValid(videoChannel.updatedAt) && - isUUIDValid(videoChannel.ownerUUID) +function isRemoteVideoIconValid (icon: any) { + return icon.type === 'Image' && + validator.isURL(icon.url) && + icon.mediaType === 'image/jpeg' && + validator.isInt(icon.width, { min: 0 }) && + validator.isInt(icon.height, { min: 0 }) } -function checkUpdateVideoChannel (videoChannel: any) { - return isUUIDValid(videoChannel.uuid) && - isVideoChannelNameValid(videoChannel.name) && - isVideoChannelDescriptionValid(videoChannel.description) && - isDateValid(videoChannel.createdAt) && - isDateValid(videoChannel.updatedAt) && - isUUIDValid(videoChannel.ownerUUID) -} +function setValidRemoteVideoUrls (video: any) { + if (Array.isArray(video.url) === false) return false -function checkRemoveVideoChannel (videoChannel: any) { - return isUUIDValid(videoChannel.uuid) -} + const newUrl = video.url.filter(u => isRemoteVideoUrlValid(u)) + video.url = newUrl -function checkAddAuthor (author: any) { - return isUUIDValid(author.uuid) && - isVideoAuthorNameValid(author.name) + return true } -function checkRemoveAuthor (author: any) { - return isUUIDValid(author.uuid) +function isRemoteVideoUrlValid (url: any) { + return url.type === 'Link' && + ACTIVITY_PUB.VIDEO_URL_MIME_TYPES.indexOf(url.mimeType) !== -1 && + validator.isURL(url.url) && + validator.isInt(url.width, { min: 0 }) && + validator.isInt(url.size, { min: 0 }) } -- cgit v1.2.3