aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/plugins/external-auth.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/tests/plugins/external-auth.ts')
-rw-r--r--server/tests/plugins/external-auth.ts184
1 files changed, 72 insertions, 112 deletions
diff --git a/server/tests/plugins/external-auth.ts b/server/tests/plugins/external-auth.ts
index 5addb45c7..f3e018d43 100644
--- a/server/tests/plugins/external-auth.ts
+++ b/server/tests/plugins/external-auth.ts
@@ -2,44 +2,32 @@
2 2
3import 'mocha' 3import 'mocha'
4import { expect } from 'chai' 4import { expect } from 'chai'
5import { ServerConfig, User, UserRole } from '@shared/models'
6import { 5import {
6 cleanupTests,
7 createSingleServer,
7 decodeQueryString, 8 decodeQueryString,
8 getConfig, 9 PeerTubeServer,
9 getExternalAuth, 10 PluginsCommand,
10 getMyUserInformation,
11 getPluginTestPath,
12 installPlugin,
13 loginUsingExternalToken,
14 logout,
15 refreshToken,
16 setAccessTokensToServers, 11 setAccessTokensToServers,
17 uninstallPlugin, 12 wait
18 updateMyUser, 13} from '@shared/extra-utils'
19 wait, 14import { HttpStatusCode, UserRole } from '@shared/models'
20 userLogin,
21 updatePluginSettings,
22 createUser
23} from '../../../shared/extra-utils'
24import { cleanupTests, flushAndRunServer, ServerInfo, waitUntilLog } from '../../../shared/extra-utils/server/servers'
25import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
26 15
27async function loginExternal (options: { 16async function loginExternal (options: {
28 server: ServerInfo 17 server: PeerTubeServer
29 npmName: string 18 npmName: string
30 authName: string 19 authName: string
31 username: string 20 username: string
32 query?: any 21 query?: any
33 statusCodeExpected?: HttpStatusCode 22 expectedStatus?: HttpStatusCode
34 statusCodeExpectedStep2?: HttpStatusCode 23 expectedStatusStep2?: HttpStatusCode
35}) { 24}) {
36 const res = await getExternalAuth({ 25 const res = await options.server.plugins.getExternalAuth({
37 url: options.server.url,
38 npmName: options.npmName, 26 npmName: options.npmName,
39 npmVersion: '0.0.1', 27 npmVersion: '0.0.1',
40 authName: options.authName, 28 authName: options.authName,
41 query: options.query, 29 query: options.query,
42 statusCodeExpected: options.statusCodeExpected || HttpStatusCode.FOUND_302 30 expectedStatus: options.expectedStatus || HttpStatusCode.FOUND_302
43 }) 31 })
44 32
45 if (res.status !== HttpStatusCode.FOUND_302) return 33 if (res.status !== HttpStatusCode.FOUND_302) return
@@ -47,18 +35,17 @@ async function loginExternal (options: {
47 const location = res.header.location 35 const location = res.header.location
48 const { externalAuthToken } = decodeQueryString(location) 36 const { externalAuthToken } = decodeQueryString(location)
49 37
50 const resLogin = await loginUsingExternalToken( 38 const resLogin = await options.server.login.loginUsingExternalToken({
51 options.server, 39 username: options.username,
52 options.username, 40 externalAuthToken: externalAuthToken as string,
53 externalAuthToken as string, 41 expectedStatus: options.expectedStatusStep2
54 options.statusCodeExpectedStep2 42 })
55 )
56 43
57 return resLogin.body 44 return resLogin.body
58} 45}
59 46
60describe('Test external auth plugins', function () { 47describe('Test external auth plugins', function () {
61 let server: ServerInfo 48 let server: PeerTubeServer
62 49
63 let cyanAccessToken: string 50 let cyanAccessToken: string
64 let cyanRefreshToken: string 51 let cyanRefreshToken: string
@@ -71,22 +58,16 @@ describe('Test external auth plugins', function () {
71 before(async function () { 58 before(async function () {
72 this.timeout(30000) 59 this.timeout(30000)
73 60
74 server = await flushAndRunServer(1) 61 server = await createSingleServer(1)
75 await setAccessTokensToServers([ server ]) 62 await setAccessTokensToServers([ server ])
76 63
77 for (const suffix of [ 'one', 'two', 'three' ]) { 64 for (const suffix of [ 'one', 'two', 'three' ]) {
78 await installPlugin({ 65 await server.plugins.install({ path: PluginsCommand.getPluginTestPath('-external-auth-' + suffix) })
79 url: server.url,
80 accessToken: server.accessToken,
81 path: getPluginTestPath('-external-auth-' + suffix)
82 })
83 } 66 }
84 }) 67 })
85 68
86 it('Should display the correct configuration', async function () { 69 it('Should display the correct configuration', async function () {
87 const res = await getConfig(server.url) 70 const config = await server.config.getConfig()
88
89 const config: ServerConfig = res.body
90 71
91 const auths = config.plugin.registeredExternalAuths 72 const auths = config.plugin.registeredExternalAuths
92 expect(auths).to.have.lengthOf(8) 73 expect(auths).to.have.lengthOf(8)
@@ -98,15 +79,14 @@ describe('Test external auth plugins', function () {
98 }) 79 })
99 80
100 it('Should redirect for a Cyan login', async function () { 81 it('Should redirect for a Cyan login', async function () {
101 const res = await getExternalAuth({ 82 const res = await server.plugins.getExternalAuth({
102 url: server.url,
103 npmName: 'test-external-auth-one', 83 npmName: 'test-external-auth-one',
104 npmVersion: '0.0.1', 84 npmVersion: '0.0.1',
105 authName: 'external-auth-1', 85 authName: 'external-auth-1',
106 query: { 86 query: {
107 username: 'cyan' 87 username: 'cyan'
108 }, 88 },
109 statusCodeExpected: HttpStatusCode.FOUND_302 89 expectedStatus: HttpStatusCode.FOUND_302
110 }) 90 })
111 91
112 const location = res.header.location 92 const location = res.header.location
@@ -121,13 +101,17 @@ describe('Test external auth plugins', function () {
121 }) 101 })
122 102
123 it('Should reject auto external login with a missing or invalid token', async function () { 103 it('Should reject auto external login with a missing or invalid token', async function () {
124 await loginUsingExternalToken(server, 'cyan', '', HttpStatusCode.BAD_REQUEST_400) 104 const command = server.login
125 await loginUsingExternalToken(server, 'cyan', 'blabla', HttpStatusCode.BAD_REQUEST_400) 105
106 await command.loginUsingExternalToken({ username: 'cyan', externalAuthToken: '', expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
107 await command.loginUsingExternalToken({ username: 'cyan', externalAuthToken: 'blabla', expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
126 }) 108 })
127 109
128 it('Should reject auto external login with a missing or invalid username', async function () { 110 it('Should reject auto external login with a missing or invalid username', async function () {
129 await loginUsingExternalToken(server, '', externalAuthToken, HttpStatusCode.BAD_REQUEST_400) 111 const command = server.login
130 await loginUsingExternalToken(server, '', externalAuthToken, HttpStatusCode.BAD_REQUEST_400) 112
113 await command.loginUsingExternalToken({ username: '', externalAuthToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
114 await command.loginUsingExternalToken({ username: '', externalAuthToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
131 }) 115 })
132 116
133 it('Should reject auto external login with an expired token', async function () { 117 it('Should reject auto external login with an expired token', async function () {
@@ -135,9 +119,13 @@ describe('Test external auth plugins', function () {
135 119
136 await wait(5000) 120 await wait(5000)
137 121
138 await loginUsingExternalToken(server, 'cyan', externalAuthToken, HttpStatusCode.BAD_REQUEST_400) 122 await server.login.loginUsingExternalToken({
123 username: 'cyan',
124 externalAuthToken,
125 expectedStatus: HttpStatusCode.BAD_REQUEST_400
126 })
139 127
140 await waitUntilLog(server, 'expired external auth token', 2) 128 await server.servers.waitUntilLog('expired external auth token', 2)
141 }) 129 })
142 130
143 it('Should auto login Cyan, create the user and use the token', async function () { 131 it('Should auto login Cyan, create the user and use the token', async function () {
@@ -157,9 +145,7 @@ describe('Test external auth plugins', function () {
157 } 145 }
158 146
159 { 147 {
160 const res = await getMyUserInformation(server.url, cyanAccessToken) 148 const body = await server.users.getMyInfo({ token: cyanAccessToken })
161
162 const body: User = res.body
163 expect(body.username).to.equal('cyan') 149 expect(body.username).to.equal('cyan')
164 expect(body.account.displayName).to.equal('cyan') 150 expect(body.account.displayName).to.equal('cyan')
165 expect(body.email).to.equal('cyan@example.com') 151 expect(body.email).to.equal('cyan@example.com')
@@ -181,9 +167,7 @@ describe('Test external auth plugins', function () {
181 } 167 }
182 168
183 { 169 {
184 const res = await getMyUserInformation(server.url, kefkaAccessToken) 170 const body = await server.users.getMyInfo({ token: kefkaAccessToken })
185
186 const body: User = res.body
187 expect(body.username).to.equal('kefka') 171 expect(body.username).to.equal('kefka')
188 expect(body.account.displayName).to.equal('Kefka Palazzo') 172 expect(body.account.displayName).to.equal('Kefka Palazzo')
189 expect(body.email).to.equal('kefka@example.com') 173 expect(body.email).to.equal('kefka@example.com')
@@ -193,43 +177,39 @@ describe('Test external auth plugins', function () {
193 177
194 it('Should refresh Cyan token, but not Kefka token', async function () { 178 it('Should refresh Cyan token, but not Kefka token', async function () {
195 { 179 {
196 const resRefresh = await refreshToken(server, cyanRefreshToken) 180 const resRefresh = await server.login.refreshToken({ refreshToken: cyanRefreshToken })
197 cyanAccessToken = resRefresh.body.access_token 181 cyanAccessToken = resRefresh.body.access_token
198 cyanRefreshToken = resRefresh.body.refresh_token 182 cyanRefreshToken = resRefresh.body.refresh_token
199 183
200 const res = await getMyUserInformation(server.url, cyanAccessToken) 184 const body = await server.users.getMyInfo({ token: cyanAccessToken })
201 const user: User = res.body 185 expect(body.username).to.equal('cyan')
202 expect(user.username).to.equal('cyan')
203 } 186 }
204 187
205 { 188 {
206 await refreshToken(server, kefkaRefreshToken, HttpStatusCode.BAD_REQUEST_400) 189 await server.login.refreshToken({ refreshToken: kefkaRefreshToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
207 } 190 }
208 }) 191 })
209 192
210 it('Should update Cyan profile', async function () { 193 it('Should update Cyan profile', async function () {
211 await updateMyUser({ 194 await server.users.updateMe({
212 url: server.url, 195 token: cyanAccessToken,
213 accessToken: cyanAccessToken,
214 displayName: 'Cyan Garamonde', 196 displayName: 'Cyan Garamonde',
215 description: 'Retainer to the king of Doma' 197 description: 'Retainer to the king of Doma'
216 }) 198 })
217 199
218 const res = await getMyUserInformation(server.url, cyanAccessToken) 200 const body = await server.users.getMyInfo({ token: cyanAccessToken })
219
220 const body: User = res.body
221 expect(body.account.displayName).to.equal('Cyan Garamonde') 201 expect(body.account.displayName).to.equal('Cyan Garamonde')
222 expect(body.account.description).to.equal('Retainer to the king of Doma') 202 expect(body.account.description).to.equal('Retainer to the king of Doma')
223 }) 203 })
224 204
225 it('Should logout Cyan', async function () { 205 it('Should logout Cyan', async function () {
226 await logout(server.url, cyanAccessToken) 206 await server.login.logout({ token: cyanAccessToken })
227 }) 207 })
228 208
229 it('Should have logged out Cyan', async function () { 209 it('Should have logged out Cyan', async function () {
230 await waitUntilLog(server, 'On logout cyan') 210 await server.servers.waitUntilLog('On logout cyan')
231 211
232 await getMyUserInformation(server.url, cyanAccessToken, HttpStatusCode.UNAUTHORIZED_401) 212 await server.users.getMyInfo({ token: cyanAccessToken, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
233 }) 213 })
234 214
235 it('Should login Cyan and keep the old existing profile', async function () { 215 it('Should login Cyan and keep the old existing profile', async function () {
@@ -247,9 +227,7 @@ describe('Test external auth plugins', function () {
247 cyanAccessToken = res.access_token 227 cyanAccessToken = res.access_token
248 } 228 }
249 229
250 const res = await getMyUserInformation(server.url, cyanAccessToken) 230 const body = await server.users.getMyInfo({ token: cyanAccessToken })
251
252 const body: User = res.body
253 expect(body.username).to.equal('cyan') 231 expect(body.username).to.equal('cyan')
254 expect(body.account.displayName).to.equal('Cyan Garamonde') 232 expect(body.account.displayName).to.equal('Cyan Garamonde')
255 expect(body.account.description).to.equal('Retainer to the king of Doma') 233 expect(body.account.description).to.equal('Retainer to the king of Doma')
@@ -257,12 +235,11 @@ describe('Test external auth plugins', function () {
257 }) 235 })
258 236
259 it('Should not update an external auth email', async function () { 237 it('Should not update an external auth email', async function () {
260 await updateMyUser({ 238 await server.users.updateMe({
261 url: server.url, 239 token: cyanAccessToken,
262 accessToken: cyanAccessToken,
263 email: 'toto@example.com', 240 email: 'toto@example.com',
264 currentPassword: 'toto', 241 currentPassword: 'toto',
265 statusCodeExpected: HttpStatusCode.BAD_REQUEST_400 242 expectedStatus: HttpStatusCode.BAD_REQUEST_400
266 }) 243 })
267 }) 244 })
268 245
@@ -271,18 +248,16 @@ describe('Test external auth plugins', function () {
271 248
272 await wait(5000) 249 await wait(5000)
273 250
274 await getMyUserInformation(server.url, kefkaAccessToken, HttpStatusCode.UNAUTHORIZED_401) 251 await server.users.getMyInfo({ token: kefkaAccessToken, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
275 }) 252 })
276 253
277 it('Should unregister external-auth-2 and do not login existing Kefka', async function () { 254 it('Should unregister external-auth-2 and do not login existing Kefka', async function () {
278 await updatePluginSettings({ 255 await server.plugins.updateSettings({
279 url: server.url,
280 accessToken: server.accessToken,
281 npmName: 'peertube-plugin-test-external-auth-one', 256 npmName: 'peertube-plugin-test-external-auth-one',
282 settings: { disableKefka: true } 257 settings: { disableKefka: true }
283 }) 258 })
284 259
285 await userLogin(server, { username: 'kefka', password: 'fake' }, HttpStatusCode.BAD_REQUEST_400) 260 await server.login.login({ user: { username: 'kefka', password: 'fake' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
286 261
287 await loginExternal({ 262 await loginExternal({
288 server, 263 server,
@@ -292,14 +267,12 @@ describe('Test external auth plugins', function () {
292 username: 'kefka' 267 username: 'kefka'
293 }, 268 },
294 username: 'kefka', 269 username: 'kefka',
295 statusCodeExpected: HttpStatusCode.NOT_FOUND_404 270 expectedStatus: HttpStatusCode.NOT_FOUND_404
296 }) 271 })
297 }) 272 })
298 273
299 it('Should have disabled this auth', async function () { 274 it('Should have disabled this auth', async function () {
300 const res = await getConfig(server.url) 275 const config = await server.config.getConfig()
301
302 const config: ServerConfig = res.body
303 276
304 const auths = config.plugin.registeredExternalAuths 277 const auths = config.plugin.registeredExternalAuths
305 expect(auths).to.have.lengthOf(7) 278 expect(auths).to.have.lengthOf(7)
@@ -309,11 +282,7 @@ describe('Test external auth plugins', function () {
309 }) 282 })
310 283
311 it('Should uninstall the plugin one and do not login Cyan', async function () { 284 it('Should uninstall the plugin one and do not login Cyan', async function () {
312 await uninstallPlugin({ 285 await server.plugins.uninstall({ npmName: 'peertube-plugin-test-external-auth-one' })
313 url: server.url,
314 accessToken: server.accessToken,
315 npmName: 'peertube-plugin-test-external-auth-one'
316 })
317 286
318 await loginExternal({ 287 await loginExternal({
319 server, 288 server,
@@ -323,12 +292,12 @@ describe('Test external auth plugins', function () {
323 username: 'cyan' 292 username: 'cyan'
324 }, 293 },
325 username: 'cyan', 294 username: 'cyan',
326 statusCodeExpected: HttpStatusCode.NOT_FOUND_404 295 expectedStatus: HttpStatusCode.NOT_FOUND_404
327 }) 296 })
328 297
329 await userLogin(server, { username: 'cyan', password: null }, HttpStatusCode.BAD_REQUEST_400) 298 await server.login.login({ user: { username: 'cyan', password: null }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
330 await userLogin(server, { username: 'cyan', password: '' }, HttpStatusCode.BAD_REQUEST_400) 299 await server.login.login({ user: { username: 'cyan', password: '' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
331 await userLogin(server, { username: 'cyan', password: 'fake' }, HttpStatusCode.BAD_REQUEST_400) 300 await server.login.login({ user: { username: 'cyan', password: 'fake' }, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
332 }) 301 })
333 302
334 it('Should not login kefka with another plugin', async function () { 303 it('Should not login kefka with another plugin', async function () {
@@ -337,7 +306,7 @@ describe('Test external auth plugins', function () {
337 npmName: 'test-external-auth-two', 306 npmName: 'test-external-auth-two',
338 authName: 'external-auth-4', 307 authName: 'external-auth-4',
339 username: 'kefka2', 308 username: 'kefka2',
340 statusCodeExpectedStep2: HttpStatusCode.BAD_REQUEST_400 309 expectedStatusStep2: HttpStatusCode.BAD_REQUEST_400
341 }) 310 })
342 311
343 await loginExternal({ 312 await loginExternal({
@@ -345,31 +314,24 @@ describe('Test external auth plugins', function () {
345 npmName: 'test-external-auth-two', 314 npmName: 'test-external-auth-two',
346 authName: 'external-auth-4', 315 authName: 'external-auth-4',
347 username: 'kefka', 316 username: 'kefka',
348 statusCodeExpectedStep2: HttpStatusCode.BAD_REQUEST_400 317 expectedStatusStep2: HttpStatusCode.BAD_REQUEST_400
349 }) 318 })
350 }) 319 })
351 320
352 it('Should not login an existing user', async function () { 321 it('Should not login an existing user', async function () {
353 await createUser({ 322 await server.users.create({ username: 'existing_user', password: 'super_password' })
354 url: server.url,
355 accessToken: server.accessToken,
356 username: 'existing_user',
357 password: 'super_password'
358 })
359 323
360 await loginExternal({ 324 await loginExternal({
361 server, 325 server,
362 npmName: 'test-external-auth-two', 326 npmName: 'test-external-auth-two',
363 authName: 'external-auth-6', 327 authName: 'external-auth-6',
364 username: 'existing_user', 328 username: 'existing_user',
365 statusCodeExpectedStep2: HttpStatusCode.BAD_REQUEST_400 329 expectedStatusStep2: HttpStatusCode.BAD_REQUEST_400
366 }) 330 })
367 }) 331 })
368 332
369 it('Should display the correct configuration', async function () { 333 it('Should display the correct configuration', async function () {
370 const res = await getConfig(server.url) 334 const config = await server.config.getConfig()
371
372 const config: ServerConfig = res.body
373 335
374 const auths = config.plugin.registeredExternalAuths 336 const auths = config.plugin.registeredExternalAuths
375 expect(auths).to.have.lengthOf(6) 337 expect(auths).to.have.lengthOf(6)
@@ -390,9 +352,8 @@ describe('Test external auth plugins', function () {
390 username: 'cid' 352 username: 'cid'
391 }) 353 })
392 354
393 const resLogout = await logout(server.url, resLogin.access_token) 355 const { redirectUrl } = await server.login.logout({ token: resLogin.access_token })
394 356 expect(redirectUrl).to.equal('https://example.com/redirectUrl')
395 expect(resLogout.body.redirectUrl).to.equal('https://example.com/redirectUrl')
396 }) 357 })
397 358
398 it('Should call the plugin\'s onLogout method with the request', async function () { 359 it('Should call the plugin\'s onLogout method with the request', async function () {
@@ -403,8 +364,7 @@ describe('Test external auth plugins', function () {
403 username: 'cid' 364 username: 'cid'
404 }) 365 })
405 366
406 const resLogout = await logout(server.url, resLogin.access_token) 367 const { redirectUrl } = await server.login.logout({ token: resLogin.access_token })
407 368 expect(redirectUrl).to.equal('https://example.com/redirectUrl?access_token=' + resLogin.access_token)
408 expect(resLogout.body.redirectUrl).to.equal('https://example.com/redirectUrl?access_token=' + resLogin.access_token)
409 }) 369 })
410}) 370})