]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/videos/video-privacy.ts
Refactor video rights checker
[github/Chocobozzz/PeerTube.git] / server / tests / api / videos / video-privacy.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
11474c3c 2
975e6e0e 3import 'mocha'
d4a8e7a6 4import * as chai from 'chai'
c55e3d72 5import { wait } from '@shared/core-utils'
4c7e60bc 6import { HttpStatusCode, VideoCreateResult, VideoPrivacy } from '@shared/models'
c55e3d72 7import { cleanupTests, createSingleServer, doubleFollow, PeerTubeServer, setAccessTokensToServers, waitJobs } from '@shared/server-commands'
975e6e0e
C
8
9const expect = chai.expect
11474c3c
C
10
11describe('Test video privacy', function () {
254d3579 12 const servers: PeerTubeServer[] = []
22a73cb8
C
13 let anotherUserToken: string
14
c49db162
C
15 let privateVideoId: number
16 let privateVideoUUID: string
22a73cb8
C
17
18 let internalVideoId: number
19 let internalVideoUUID: string
20
d4a8e7a6 21 let unlistedVideo: VideoCreateResult
3092e9bb 22 let nonFederatedUnlistedVideoUUID: string
22a73cb8 23
c49db162 24 let now: number
11474c3c 25
3092e9bb
LB
26 const dontFederateUnlistedConfig = {
27 federation: {
28 videos: {
29 federate_unlisted: false
30 }
31 }
32 }
33
11474c3c 34 before(async function () {
572f8d3d 35 this.timeout(50000)
11474c3c
C
36
37 // Run servers
254d3579
C
38 servers.push(await createSingleServer(1, dontFederateUnlistedConfig))
39 servers.push(await createSingleServer(2))
11474c3c
C
40
41 // Get the access tokens
42 await setAccessTokensToServers(servers)
43
975e6e0e
C
44 // Server 1 and server 2 follow each other
45 await doubleFollow(servers[0], servers[1])
11474c3c
C
46 })
47
d4a8e7a6 48 describe('Private and internal videos', function () {
11474c3c 49
d4a8e7a6
C
50 it('Should upload a private and internal videos on server 1', async function () {
51 this.timeout(10000)
11474c3c 52
d4a8e7a6
C
53 for (const privacy of [ VideoPrivacy.PRIVATE, VideoPrivacy.INTERNAL ]) {
54 const attributes = { privacy }
89d241a7 55 await servers[0].videos.upload({ attributes })
d4a8e7a6 56 }
11474c3c 57
d4a8e7a6
C
58 await waitJobs(servers)
59 })
11474c3c 60
d4a8e7a6 61 it('Should not have these private and internal videos on server 2', async function () {
89d241a7 62 const { total, data } = await servers[1].videos.list()
11474c3c 63
d23dd9fb
C
64 expect(total).to.equal(0)
65 expect(data).to.have.lengthOf(0)
d4a8e7a6 66 })
22a73cb8 67
d4a8e7a6 68 it('Should not list the private and internal videos for an unauthenticated user on server 1', async function () {
89d241a7 69 const { total, data } = await servers[0].videos.list()
d4a8e7a6 70
d23dd9fb
C
71 expect(total).to.equal(0)
72 expect(data).to.have.lengthOf(0)
d4a8e7a6 73 })
22a73cb8 74
d4a8e7a6 75 it('Should not list the private video and list the internal video for an authenticated user on server 1', async function () {
89d241a7 76 const { total, data } = await servers[0].videos.listWithToken()
11474c3c 77
d23dd9fb
C
78 expect(total).to.equal(1)
79 expect(data).to.have.lengthOf(1)
11474c3c 80
d23dd9fb 81 expect(data[0].privacy.id).to.equal(VideoPrivacy.INTERNAL)
d4a8e7a6 82 })
22a73cb8 83
d4a8e7a6 84 it('Should list my (private and internal) videos', async function () {
89d241a7 85 const { total, data } = await servers[0].videos.listMyVideos()
22a73cb8 86
d23dd9fb
C
87 expect(total).to.equal(2)
88 expect(data).to.have.lengthOf(2)
22a73cb8 89
d23dd9fb 90 const privateVideo = data.find(v => v.privacy.id === VideoPrivacy.PRIVATE)
d4a8e7a6
C
91 privateVideoId = privateVideo.id
92 privateVideoUUID = privateVideo.uuid
22a73cb8 93
d23dd9fb 94 const internalVideo = data.find(v => v.privacy.id === VideoPrivacy.INTERNAL)
d4a8e7a6
C
95 internalVideoId = internalVideo.id
96 internalVideoUUID = internalVideo.uuid
97 })
11474c3c 98
d4a8e7a6 99 it('Should not be able to watch the private/internal video with non authenticated user', async function () {
89d241a7
C
100 await servers[0].videos.get({ id: privateVideoUUID, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
101 await servers[0].videos.get({ id: internalVideoUUID, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
d4a8e7a6 102 })
11474c3c 103
d4a8e7a6
C
104 it('Should not be able to watch the private video with another user', async function () {
105 this.timeout(10000)
77a87fec 106
d4a8e7a6
C
107 const user = {
108 username: 'hello',
109 password: 'super password'
110 }
89d241a7 111 await servers[0].users.create({ username: user.username, password: user.password })
11474c3c 112
89d241a7 113 anotherUserToken = await servers[0].login.getAccessToken(user)
d23dd9fb 114
89d241a7 115 await servers[0].videos.getWithToken({
d23dd9fb
C
116 token: anotherUserToken,
117 id: privateVideoUUID,
118 expectedStatus: HttpStatusCode.FORBIDDEN_403
119 })
d4a8e7a6 120 })
11474c3c 121
d4a8e7a6 122 it('Should be able to watch the internal video with another user', async function () {
89d241a7 123 await servers[0].videos.getWithToken({ token: anotherUserToken, id: internalVideoUUID })
d4a8e7a6 124 })
22a73cb8 125
d4a8e7a6 126 it('Should be able to watch the private video with the correct user', async function () {
89d241a7 127 await servers[0].videos.getWithToken({ id: privateVideoUUID })
d4a8e7a6 128 })
11474c3c
C
129 })
130
d4a8e7a6 131 describe('Unlisted videos', function () {
11474c3c 132
d4a8e7a6
C
133 it('Should upload an unlisted video on server 2', async function () {
134 this.timeout(60000)
11474c3c 135
d4a8e7a6
C
136 const attributes = {
137 name: 'unlisted video',
138 privacy: VideoPrivacy.UNLISTED
139 }
89d241a7 140 await servers[1].videos.upload({ attributes })
11474c3c 141
d4a8e7a6
C
142 // Server 2 has transcoding enabled
143 await waitJobs(servers)
144 })
11474c3c 145
d4a8e7a6
C
146 it('Should not have this unlisted video listed on server 1 and 2', async function () {
147 for (const server of servers) {
89d241a7 148 const { total, data } = await server.videos.list()
11474c3c 149
d23dd9fb
C
150 expect(total).to.equal(0)
151 expect(data).to.have.lengthOf(0)
d4a8e7a6
C
152 }
153 })
11474c3c 154
d4a8e7a6 155 it('Should list my (unlisted) videos', async function () {
89d241a7 156 const { total, data } = await servers[1].videos.listMyVideos()
11474c3c 157
d23dd9fb
C
158 expect(total).to.equal(1)
159 expect(data).to.have.lengthOf(1)
11474c3c 160
d23dd9fb 161 unlistedVideo = data[0]
d4a8e7a6 162 })
11474c3c 163
d4a8e7a6 164 it('Should not be able to get this unlisted video using its id', async function () {
4c7e60bc 165 await servers[1].videos.get({ id: unlistedVideo.id, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
d4a8e7a6 166 })
11474c3c 167
d4a8e7a6
C
168 it('Should be able to get this unlisted video using its uuid/shortUUID', async function () {
169 for (const server of servers) {
170 for (const id of [ unlistedVideo.uuid, unlistedVideo.shortUUID ]) {
89d241a7 171 const video = await server.videos.get({ id })
3092e9bb 172
d23dd9fb 173 expect(video.name).to.equal('unlisted video')
d4a8e7a6
C
174 }
175 }
176 })
3092e9bb 177
d4a8e7a6
C
178 it('Should upload a non-federating unlisted video to server 1', async function () {
179 this.timeout(30000)
180
181 const attributes = {
182 name: 'unlisted video',
183 privacy: VideoPrivacy.UNLISTED
184 }
89d241a7 185 await servers[0].videos.upload({ attributes })
3092e9bb 186
d4a8e7a6
C
187 await waitJobs(servers)
188 })
3092e9bb 189
d4a8e7a6 190 it('Should list my new unlisted video', async function () {
89d241a7 191 const { total, data } = await servers[0].videos.listMyVideos()
3092e9bb 192
d23dd9fb
C
193 expect(total).to.equal(3)
194 expect(data).to.have.lengthOf(3)
3092e9bb 195
d23dd9fb 196 nonFederatedUnlistedVideoUUID = data[0].uuid
d4a8e7a6 197 })
3092e9bb 198
d4a8e7a6 199 it('Should be able to get non-federated unlisted video from origin', async function () {
89d241a7 200 const video = await servers[0].videos.get({ id: nonFederatedUnlistedVideoUUID })
3092e9bb 201
d23dd9fb 202 expect(video.name).to.equal('unlisted video')
d4a8e7a6
C
203 })
204
205 it('Should not be able to get non-federated unlisted video from federated server', async function () {
89d241a7 206 await servers[1].videos.get({ id: nonFederatedUnlistedVideoUUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
d4a8e7a6 207 })
3092e9bb
LB
208 })
209
d4a8e7a6 210 describe('Privacy update', function () {
11474c3c 211
d4a8e7a6 212 it('Should update the private and internal videos to public on server 1', async function () {
0fbc0dec 213 this.timeout(100000)
22a73cb8 214
d4a8e7a6 215 now = Date.now()
22a73cb8 216
d4a8e7a6 217 {
d23dd9fb 218 const attributes = {
d4a8e7a6
C
219 name: 'private video becomes public',
220 privacy: VideoPrivacy.PUBLIC
221 }
11474c3c 222
89d241a7 223 await servers[0].videos.update({ id: privateVideoId, attributes })
22a73cb8 224 }
11474c3c 225
d4a8e7a6 226 {
d23dd9fb 227 const attributes = {
d4a8e7a6
C
228 name: 'internal video becomes public',
229 privacy: VideoPrivacy.PUBLIC
230 }
89d241a7 231 await servers[0].videos.update({ id: internalVideoId, attributes })
d4a8e7a6 232 }
11474c3c 233
0fbc0dec 234 await wait(10000)
d4a8e7a6
C
235 await waitJobs(servers)
236 })
22a73cb8 237
d4a8e7a6
C
238 it('Should have this new public video listed on server 1 and 2', async function () {
239 for (const server of servers) {
89d241a7 240 const { total, data } = await server.videos.list()
d23dd9fb
C
241 expect(total).to.equal(2)
242 expect(data).to.have.lengthOf(2)
22a73cb8 243
d23dd9fb
C
244 const privateVideo = data.find(v => v.name === 'private video becomes public')
245 const internalVideo = data.find(v => v.name === 'internal video becomes public')
22a73cb8 246
d4a8e7a6
C
247 expect(privateVideo).to.not.be.undefined
248 expect(internalVideo).to.not.be.undefined
11474c3c 249
d4a8e7a6
C
250 expect(new Date(privateVideo.publishedAt).getTime()).to.be.at.least(now)
251 // We don't change the publish date of internal videos
252 expect(new Date(internalVideo.publishedAt).getTime()).to.be.below(now)
11474c3c 253
d4a8e7a6
C
254 expect(privateVideo.privacy.id).to.equal(VideoPrivacy.PUBLIC)
255 expect(internalVideo.privacy.id).to.equal(VideoPrivacy.PUBLIC)
256 }
257 })
46a6db24 258
d4a8e7a6
C
259 it('Should set these videos as private and internal', async function () {
260 this.timeout(10000)
46a6db24 261
89d241a7
C
262 await servers[0].videos.update({ id: internalVideoId, attributes: { privacy: VideoPrivacy.PRIVATE } })
263 await servers[0].videos.update({ id: privateVideoId, attributes: { privacy: VideoPrivacy.INTERNAL } })
46a6db24 264
d4a8e7a6 265 await waitJobs(servers)
46a6db24 266
d4a8e7a6 267 for (const server of servers) {
89d241a7 268 const { total, data } = await server.videos.list()
d4a8e7a6 269
d23dd9fb
C
270 expect(total).to.equal(0)
271 expect(data).to.have.lengthOf(0)
d4a8e7a6 272 }
46a6db24 273
d4a8e7a6 274 {
89d241a7 275 const { total, data } = await servers[0].videos.listMyVideos()
d23dd9fb
C
276 expect(total).to.equal(3)
277 expect(data).to.have.lengthOf(3)
22a73cb8 278
d23dd9fb
C
279 const privateVideo = data.find(v => v.name === 'private video becomes public')
280 const internalVideo = data.find(v => v.name === 'internal video becomes public')
22a73cb8 281
d4a8e7a6
C
282 expect(privateVideo).to.not.be.undefined
283 expect(internalVideo).to.not.be.undefined
46a6db24 284
d4a8e7a6
C
285 expect(privateVideo.privacy.id).to.equal(VideoPrivacy.INTERNAL)
286 expect(internalVideo.privacy.id).to.equal(VideoPrivacy.PRIVATE)
287 }
288 })
46a6db24
C
289 })
290
7c3b7976
C
291 after(async function () {
292 await cleanupTests(servers)
11474c3c
C
293 })
294})