diff options
author | Chocobozzz <me@florianbigard.com> | 2019-02-11 11:52:34 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2019-02-11 11:52:34 +0100 |
commit | 88108880bbdba473cfe36ecbebc1c3c4f972e102 (patch) | |
tree | b242efb3b4f0d7e49d88f2d1f2063b5b3b0489c0 /server/controllers/activitypub | |
parent | 53a94c7cfa8368da4cd248d65df8346905938f0c (diff) | |
parent | 9b712a2017e4ab3cf12cd6bd58278905520159d0 (diff) | |
download | PeerTube-88108880bbdba473cfe36ecbebc1c3c4f972e102.tar.gz PeerTube-88108880bbdba473cfe36ecbebc1c3c4f972e102.tar.zst PeerTube-88108880bbdba473cfe36ecbebc1c3c4f972e102.zip |
Merge branch 'develop' into pr/1217
Diffstat (limited to 'server/controllers/activitypub')
-rw-r--r-- | server/controllers/activitypub/client.ts | 86 | ||||
-rw-r--r-- | server/controllers/activitypub/inbox.ts | 6 |
2 files changed, 67 insertions, 25 deletions
diff --git a/server/controllers/activitypub/client.ts b/server/controllers/activitypub/client.ts index 433186179..31c0a5fbd 100644 --- a/server/controllers/activitypub/client.ts +++ b/server/controllers/activitypub/client.ts | |||
@@ -3,7 +3,7 @@ import * as express from 'express' | |||
3 | import { VideoPrivacy, VideoRateType } from '../../../shared/models/videos' | 3 | import { VideoPrivacy, VideoRateType } from '../../../shared/models/videos' |
4 | import { activityPubCollectionPagination, activityPubContextify } from '../../helpers/activitypub' | 4 | import { activityPubCollectionPagination, activityPubContextify } from '../../helpers/activitypub' |
5 | import { CONFIG, ROUTE_CACHE_LIFETIME } from '../../initializers' | 5 | import { CONFIG, ROUTE_CACHE_LIFETIME } from '../../initializers' |
6 | import { buildAnnounceWithVideoAudience } from '../../lib/activitypub/send' | 6 | import { buildAnnounceWithVideoAudience, buildLikeActivity } from '../../lib/activitypub/send' |
7 | import { audiencify, getAudience } from '../../lib/activitypub/audience' | 7 | import { audiencify, getAudience } from '../../lib/activitypub/audience' |
8 | import { buildCreateActivity } from '../../lib/activitypub/send/send-create' | 8 | import { buildCreateActivity } from '../../lib/activitypub/send/send-create' |
9 | import { | 9 | import { |
@@ -11,9 +11,10 @@ import { | |||
11 | executeIfActivityPub, | 11 | executeIfActivityPub, |
12 | localAccountValidator, | 12 | localAccountValidator, |
13 | localVideoChannelValidator, | 13 | localVideoChannelValidator, |
14 | videosCustomGetValidator | 14 | videosCustomGetValidator, |
15 | videosShareValidator | ||
15 | } from '../../middlewares' | 16 | } from '../../middlewares' |
16 | import { videoCommentGetValidator, videosGetValidator, videosShareValidator } from '../../middlewares/validators' | 17 | import { getAccountVideoRateValidator, videoCommentGetValidator, videosGetValidator } from '../../middlewares/validators' |
17 | import { AccountModel } from '../../models/account/account' | 18 | import { AccountModel } from '../../models/account/account' |
18 | import { ActorModel } from '../../models/activitypub/actor' | 19 | import { ActorModel } from '../../models/activitypub/actor' |
19 | import { ActorFollowModel } from '../../models/activitypub/actor-follow' | 20 | import { ActorFollowModel } from '../../models/activitypub/actor-follow' |
@@ -25,14 +26,17 @@ import { cacheRoute } from '../../middlewares/cache' | |||
25 | import { activityPubResponse } from './utils' | 26 | import { activityPubResponse } from './utils' |
26 | import { AccountVideoRateModel } from '../../models/account/account-video-rate' | 27 | import { AccountVideoRateModel } from '../../models/account/account-video-rate' |
27 | import { | 28 | import { |
29 | getRateUrl, | ||
28 | getVideoCommentsActivityPubUrl, | 30 | getVideoCommentsActivityPubUrl, |
29 | getVideoDislikesActivityPubUrl, | 31 | getVideoDislikesActivityPubUrl, |
30 | getVideoLikesActivityPubUrl, | 32 | getVideoLikesActivityPubUrl, |
31 | getVideoSharesActivityPubUrl | 33 | getVideoSharesActivityPubUrl |
32 | } from '../../lib/activitypub' | 34 | } from '../../lib/activitypub' |
33 | import { VideoCaptionModel } from '../../models/video/video-caption' | 35 | import { VideoCaptionModel } from '../../models/video/video-caption' |
34 | import { videoRedundancyGetValidator } from '../../middlewares/validators/redundancy' | 36 | import { videoFileRedundancyGetValidator, videoPlaylistRedundancyGetValidator } from '../../middlewares/validators/redundancy' |
35 | import { getServerActor } from '../../helpers/utils' | 37 | import { getServerActor } from '../../helpers/utils' |
38 | import { VideoRedundancyModel } from '../../models/redundancy/video-redundancy' | ||
39 | import { buildDislikeActivity } from '../../lib/activitypub/send/send-dislike' | ||
36 | 40 | ||
37 | const activityPubClientRouter = express.Router() | 41 | const activityPubClientRouter = express.Router() |
38 | 42 | ||
@@ -48,21 +52,29 @@ activityPubClientRouter.get('/accounts?/:name/following', | |||
48 | executeIfActivityPub(asyncMiddleware(localAccountValidator)), | 52 | executeIfActivityPub(asyncMiddleware(localAccountValidator)), |
49 | executeIfActivityPub(asyncMiddleware(accountFollowingController)) | 53 | executeIfActivityPub(asyncMiddleware(accountFollowingController)) |
50 | ) | 54 | ) |
55 | activityPubClientRouter.get('/accounts?/:name/likes/:videoId', | ||
56 | executeIfActivityPub(asyncMiddleware(getAccountVideoRateValidator('like'))), | ||
57 | executeIfActivityPub(getAccountVideoRate('like')) | ||
58 | ) | ||
59 | activityPubClientRouter.get('/accounts?/:name/dislikes/:videoId', | ||
60 | executeIfActivityPub(asyncMiddleware(getAccountVideoRateValidator('dislike'))), | ||
61 | executeIfActivityPub(getAccountVideoRate('dislike')) | ||
62 | ) | ||
51 | 63 | ||
52 | activityPubClientRouter.get('/videos/watch/:id', | 64 | activityPubClientRouter.get('/videos/watch/:id', |
53 | executeIfActivityPub(asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.ACTIVITY_PUB.VIDEOS))), | 65 | executeIfActivityPub(asyncMiddleware(cacheRoute(ROUTE_CACHE_LIFETIME.ACTIVITY_PUB.VIDEOS))), |
54 | executeIfActivityPub(asyncMiddleware(videosGetValidator)), | 66 | executeIfActivityPub(asyncMiddleware(videosCustomGetValidator('only-video-with-rights'))), |
55 | executeIfActivityPub(asyncMiddleware(videoController)) | 67 | executeIfActivityPub(asyncMiddleware(videoController)) |
56 | ) | 68 | ) |
57 | activityPubClientRouter.get('/videos/watch/:id/activity', | 69 | activityPubClientRouter.get('/videos/watch/:id/activity', |
58 | executeIfActivityPub(asyncMiddleware(videosGetValidator)), | 70 | executeIfActivityPub(asyncMiddleware(videosCustomGetValidator('only-video-with-rights'))), |
59 | executeIfActivityPub(asyncMiddleware(videoController)) | 71 | executeIfActivityPub(asyncMiddleware(videoController)) |
60 | ) | 72 | ) |
61 | activityPubClientRouter.get('/videos/watch/:id/announces', | 73 | activityPubClientRouter.get('/videos/watch/:id/announces', |
62 | executeIfActivityPub(asyncMiddleware(videosCustomGetValidator('only-video'))), | 74 | executeIfActivityPub(asyncMiddleware(videosCustomGetValidator('only-video'))), |
63 | executeIfActivityPub(asyncMiddleware(videoAnnouncesController)) | 75 | executeIfActivityPub(asyncMiddleware(videoAnnouncesController)) |
64 | ) | 76 | ) |
65 | activityPubClientRouter.get('/videos/watch/:id/announces/:accountId', | 77 | activityPubClientRouter.get('/videos/watch/:id/announces/:actorId', |
66 | executeIfActivityPub(asyncMiddleware(videosShareValidator)), | 78 | executeIfActivityPub(asyncMiddleware(videosShareValidator)), |
67 | executeIfActivityPub(asyncMiddleware(videoAnnounceController)) | 79 | executeIfActivityPub(asyncMiddleware(videoAnnounceController)) |
68 | ) | 80 | ) |
@@ -101,7 +113,11 @@ activityPubClientRouter.get('/video-channels/:name/following', | |||
101 | ) | 113 | ) |
102 | 114 | ||
103 | activityPubClientRouter.get('/redundancy/videos/:videoId/:resolution([0-9]+)(-:fps([0-9]+))?', | 115 | activityPubClientRouter.get('/redundancy/videos/:videoId/:resolution([0-9]+)(-:fps([0-9]+))?', |
104 | executeIfActivityPub(asyncMiddleware(videoRedundancyGetValidator)), | 116 | executeIfActivityPub(asyncMiddleware(videoFileRedundancyGetValidator)), |
117 | executeIfActivityPub(asyncMiddleware(videoRedundancyController)) | ||
118 | ) | ||
119 | activityPubClientRouter.get('/redundancy/video-playlists/:streamingPlaylistType/:videoId', | ||
120 | executeIfActivityPub(asyncMiddleware(videoPlaylistRedundancyGetValidator)), | ||
105 | executeIfActivityPub(asyncMiddleware(videoRedundancyController)) | 121 | executeIfActivityPub(asyncMiddleware(videoRedundancyController)) |
106 | ) | 122 | ) |
107 | 123 | ||
@@ -133,8 +149,25 @@ async function accountFollowingController (req: express.Request, res: express.Re | |||
133 | return activityPubResponse(activityPubContextify(activityPubResult), res) | 149 | return activityPubResponse(activityPubContextify(activityPubResult), res) |
134 | } | 150 | } |
135 | 151 | ||
136 | async function videoController (req: express.Request, res: express.Response, next: express.NextFunction) { | 152 | function getAccountVideoRate (rateType: VideoRateType) { |
137 | const video: VideoModel = res.locals.video | 153 | return (req: express.Request, res: express.Response) => { |
154 | const accountVideoRate: AccountVideoRateModel = res.locals.accountVideoRate | ||
155 | |||
156 | const byActor = accountVideoRate.Account.Actor | ||
157 | const url = getRateUrl(rateType, byActor, accountVideoRate.Video) | ||
158 | const APObject = rateType === 'like' | ||
159 | ? buildLikeActivity(url, byActor, accountVideoRate.Video) | ||
160 | : buildDislikeActivity(url, byActor, accountVideoRate.Video) | ||
161 | |||
162 | return activityPubResponse(activityPubContextify(APObject), res) | ||
163 | } | ||
164 | } | ||
165 | |||
166 | async function videoController (req: express.Request, res: express.Response) { | ||
167 | // We need more attributes | ||
168 | const video: VideoModel = await VideoModel.loadForGetAPI(res.locals.video.id) | ||
169 | |||
170 | if (video.url.startsWith(CONFIG.WEBSERVER.URL) === false) return res.redirect(video.url) | ||
138 | 171 | ||
139 | // We need captions to render AP object | 172 | // We need captions to render AP object |
140 | video.VideoCaptions = await VideoCaptionModel.listVideoCaptions(video.id) | 173 | video.VideoCaptions = await VideoCaptionModel.listVideoCaptions(video.id) |
@@ -150,14 +183,17 @@ async function videoController (req: express.Request, res: express.Response, nex | |||
150 | return activityPubResponse(activityPubContextify(videoObject), res) | 183 | return activityPubResponse(activityPubContextify(videoObject), res) |
151 | } | 184 | } |
152 | 185 | ||
153 | async function videoAnnounceController (req: express.Request, res: express.Response, next: express.NextFunction) { | 186 | async function videoAnnounceController (req: express.Request, res: express.Response) { |
154 | const share = res.locals.videoShare as VideoShareModel | 187 | const share = res.locals.videoShare as VideoShareModel |
188 | |||
189 | if (share.url.startsWith(CONFIG.WEBSERVER.URL) === false) return res.redirect(share.url) | ||
190 | |||
155 | const { activity } = await buildAnnounceWithVideoAudience(share.Actor, share, res.locals.video, undefined) | 191 | const { activity } = await buildAnnounceWithVideoAudience(share.Actor, share, res.locals.video, undefined) |
156 | 192 | ||
157 | return activityPubResponse(activityPubContextify(activity), res) | 193 | return activityPubResponse(activityPubContextify(activity), res) |
158 | } | 194 | } |
159 | 195 | ||
160 | async function videoAnnouncesController (req: express.Request, res: express.Response, next: express.NextFunction) { | 196 | async function videoAnnouncesController (req: express.Request, res: express.Response) { |
161 | const video: VideoModel = res.locals.video | 197 | const video: VideoModel = res.locals.video |
162 | 198 | ||
163 | const handler = async (start: number, count: number) => { | 199 | const handler = async (start: number, count: number) => { |
@@ -172,21 +208,21 @@ async function videoAnnouncesController (req: express.Request, res: express.Resp | |||
172 | return activityPubResponse(activityPubContextify(json), res) | 208 | return activityPubResponse(activityPubContextify(json), res) |
173 | } | 209 | } |
174 | 210 | ||
175 | async function videoLikesController (req: express.Request, res: express.Response, next: express.NextFunction) { | 211 | async function videoLikesController (req: express.Request, res: express.Response) { |
176 | const video: VideoModel = res.locals.video | 212 | const video: VideoModel = res.locals.video |
177 | const json = await videoRates(req, 'like', video, getVideoLikesActivityPubUrl(video)) | 213 | const json = await videoRates(req, 'like', video, getVideoLikesActivityPubUrl(video)) |
178 | 214 | ||
179 | return activityPubResponse(activityPubContextify(json), res) | 215 | return activityPubResponse(activityPubContextify(json), res) |
180 | } | 216 | } |
181 | 217 | ||
182 | async function videoDislikesController (req: express.Request, res: express.Response, next: express.NextFunction) { | 218 | async function videoDislikesController (req: express.Request, res: express.Response) { |
183 | const video: VideoModel = res.locals.video | 219 | const video: VideoModel = res.locals.video |
184 | const json = await videoRates(req, 'dislike', video, getVideoDislikesActivityPubUrl(video)) | 220 | const json = await videoRates(req, 'dislike', video, getVideoDislikesActivityPubUrl(video)) |
185 | 221 | ||
186 | return activityPubResponse(activityPubContextify(json), res) | 222 | return activityPubResponse(activityPubContextify(json), res) |
187 | } | 223 | } |
188 | 224 | ||
189 | async function videoCommentsController (req: express.Request, res: express.Response, next: express.NextFunction) { | 225 | async function videoCommentsController (req: express.Request, res: express.Response) { |
190 | const video: VideoModel = res.locals.video | 226 | const video: VideoModel = res.locals.video |
191 | 227 | ||
192 | const handler = async (start: number, count: number) => { | 228 | const handler = async (start: number, count: number) => { |
@@ -201,29 +237,31 @@ async function videoCommentsController (req: express.Request, res: express.Respo | |||
201 | return activityPubResponse(activityPubContextify(json), res) | 237 | return activityPubResponse(activityPubContextify(json), res) |
202 | } | 238 | } |
203 | 239 | ||
204 | async function videoChannelController (req: express.Request, res: express.Response, next: express.NextFunction) { | 240 | async function videoChannelController (req: express.Request, res: express.Response) { |
205 | const videoChannel: VideoChannelModel = res.locals.videoChannel | 241 | const videoChannel: VideoChannelModel = res.locals.videoChannel |
206 | 242 | ||
207 | return activityPubResponse(activityPubContextify(videoChannel.toActivityPubObject()), res) | 243 | return activityPubResponse(activityPubContextify(videoChannel.toActivityPubObject()), res) |
208 | } | 244 | } |
209 | 245 | ||
210 | async function videoChannelFollowersController (req: express.Request, res: express.Response, next: express.NextFunction) { | 246 | async function videoChannelFollowersController (req: express.Request, res: express.Response) { |
211 | const videoChannel: VideoChannelModel = res.locals.videoChannel | 247 | const videoChannel: VideoChannelModel = res.locals.videoChannel |
212 | const activityPubResult = await actorFollowers(req, videoChannel.Actor) | 248 | const activityPubResult = await actorFollowers(req, videoChannel.Actor) |
213 | 249 | ||
214 | return activityPubResponse(activityPubContextify(activityPubResult), res) | 250 | return activityPubResponse(activityPubContextify(activityPubResult), res) |
215 | } | 251 | } |
216 | 252 | ||
217 | async function videoChannelFollowingController (req: express.Request, res: express.Response, next: express.NextFunction) { | 253 | async function videoChannelFollowingController (req: express.Request, res: express.Response) { |
218 | const videoChannel: VideoChannelModel = res.locals.videoChannel | 254 | const videoChannel: VideoChannelModel = res.locals.videoChannel |
219 | const activityPubResult = await actorFollowing(req, videoChannel.Actor) | 255 | const activityPubResult = await actorFollowing(req, videoChannel.Actor) |
220 | 256 | ||
221 | return activityPubResponse(activityPubContextify(activityPubResult), res) | 257 | return activityPubResponse(activityPubContextify(activityPubResult), res) |
222 | } | 258 | } |
223 | 259 | ||
224 | async function videoCommentController (req: express.Request, res: express.Response, next: express.NextFunction) { | 260 | async function videoCommentController (req: express.Request, res: express.Response) { |
225 | const videoComment: VideoCommentModel = res.locals.videoComment | 261 | const videoComment: VideoCommentModel = res.locals.videoComment |
226 | 262 | ||
263 | if (videoComment.url.startsWith(CONFIG.WEBSERVER.URL) === false) return res.redirect(videoComment.url) | ||
264 | |||
227 | const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, undefined) | 265 | const threadParentComments = await VideoCommentModel.listThreadParentComments(videoComment, undefined) |
228 | const isPublic = true // Comments are always public | 266 | const isPublic = true // Comments are always public |
229 | const audience = getAudience(videoComment.Account.Actor, isPublic) | 267 | const audience = getAudience(videoComment.Account.Actor, isPublic) |
@@ -239,7 +277,9 @@ async function videoCommentController (req: express.Request, res: express.Respon | |||
239 | } | 277 | } |
240 | 278 | ||
241 | async function videoRedundancyController (req: express.Request, res: express.Response) { | 279 | async function videoRedundancyController (req: express.Request, res: express.Response) { |
242 | const videoRedundancy = res.locals.videoRedundancy | 280 | const videoRedundancy: VideoRedundancyModel = res.locals.videoRedundancy |
281 | if (videoRedundancy.url.startsWith(CONFIG.WEBSERVER.URL) === false) return res.redirect(videoRedundancy.url) | ||
282 | |||
243 | const serverActor = await getServerActor() | 283 | const serverActor = await getServerActor() |
244 | 284 | ||
245 | const audience = getAudience(serverActor) | 285 | const audience = getAudience(serverActor) |
@@ -260,7 +300,7 @@ async function actorFollowing (req: express.Request, actor: ActorModel) { | |||
260 | return ActorFollowModel.listAcceptedFollowingUrlsForApi([ actor.id ], undefined, start, count) | 300 | return ActorFollowModel.listAcceptedFollowingUrlsForApi([ actor.id ], undefined, start, count) |
261 | } | 301 | } |
262 | 302 | ||
263 | return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, handler, req.query.page) | 303 | return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.path, handler, req.query.page) |
264 | } | 304 | } |
265 | 305 | ||
266 | async function actorFollowers (req: express.Request, actor: ActorModel) { | 306 | async function actorFollowers (req: express.Request, actor: ActorModel) { |
@@ -268,7 +308,7 @@ async function actorFollowers (req: express.Request, actor: ActorModel) { | |||
268 | return ActorFollowModel.listAcceptedFollowerUrlsForApi([ actor.id ], undefined, start, count) | 308 | return ActorFollowModel.listAcceptedFollowerUrlsForApi([ actor.id ], undefined, start, count) |
269 | } | 309 | } |
270 | 310 | ||
271 | return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, handler, req.query.page) | 311 | return activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.path, handler, req.query.page) |
272 | } | 312 | } |
273 | 313 | ||
274 | function videoRates (req: express.Request, rateType: VideoRateType, video: VideoModel, url: string) { | 314 | function videoRates (req: express.Request, rateType: VideoRateType, video: VideoModel, url: string) { |
@@ -276,7 +316,7 @@ function videoRates (req: express.Request, rateType: VideoRateType, video: Video | |||
276 | const result = await AccountVideoRateModel.listAndCountAccountUrlsByVideoId(rateType, video.id, start, count) | 316 | const result = await AccountVideoRateModel.listAndCountAccountUrlsByVideoId(rateType, video.id, start, count) |
277 | return { | 317 | return { |
278 | total: result.count, | 318 | total: result.count, |
279 | data: result.rows.map(r => r.Account.Actor.url) | 319 | data: result.rows.map(r => r.url) |
280 | } | 320 | } |
281 | } | 321 | } |
282 | return activityPubCollectionPagination(url, handler, req.query.page) | 322 | return activityPubCollectionPagination(url, handler, req.query.page) |
diff --git a/server/controllers/activitypub/inbox.ts b/server/controllers/activitypub/inbox.ts index 738d155eb..f0e65015b 100644 --- a/server/controllers/activitypub/inbox.ts +++ b/server/controllers/activitypub/inbox.ts | |||
@@ -43,11 +43,13 @@ export { | |||
43 | // --------------------------------------------------------------------------- | 43 | // --------------------------------------------------------------------------- |
44 | 44 | ||
45 | const inboxQueue = queue<{ activities: Activity[], signatureActor?: ActorModel, inboxActor?: ActorModel }, Error>((task, cb) => { | 45 | const inboxQueue = queue<{ activities: Activity[], signatureActor?: ActorModel, inboxActor?: ActorModel }, Error>((task, cb) => { |
46 | processActivities(task.activities, task.signatureActor, task.inboxActor) | 46 | const options = { signatureActor: task.signatureActor, inboxActor: task.inboxActor } |
47 | |||
48 | processActivities(task.activities, options) | ||
47 | .then(() => cb()) | 49 | .then(() => cb()) |
48 | }) | 50 | }) |
49 | 51 | ||
50 | function inboxController (req: express.Request, res: express.Response, next: express.NextFunction) { | 52 | function inboxController (req: express.Request, res: express.Response) { |
51 | const rootActivity: RootActivity = req.body | 53 | const rootActivity: RootActivity = req.body |
52 | let activities: Activity[] = [] | 54 | let activities: Activity[] = [] |
53 | 55 | ||