aboutsummaryrefslogtreecommitdiffhomepage
path: root/shared/extra-utils/users
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-07-13 11:05:15 +0200
committerChocobozzz <me@florianbigard.com>2021-07-20 15:27:18 +0200
commit41d1d075011174e73dccb74006181a92a618d7b4 (patch)
tree4dc1af0e266977f062cf9716837d04de1cdd628d /shared/extra-utils/users
parent6c5065a011b099618681a37bd77eaa7bd3db752e (diff)
downloadPeerTube-41d1d075011174e73dccb74006181a92a618d7b4.tar.gz
PeerTube-41d1d075011174e73dccb74006181a92a618d7b4.tar.zst
PeerTube-41d1d075011174e73dccb74006181a92a618d7b4.zip
Introduce login command
Diffstat (limited to 'shared/extra-utils/users')
-rw-r--r--shared/extra-utils/users/index.ts1
-rw-r--r--shared/extra-utils/users/login-command.ts134
-rw-r--r--shared/extra-utils/users/login.ts120
-rw-r--r--shared/extra-utils/users/notifications.ts4
-rw-r--r--shared/extra-utils/users/users.ts5
5 files changed, 142 insertions, 122 deletions
diff --git a/shared/extra-utils/users/index.ts b/shared/extra-utils/users/index.ts
index ed166c756..b200ae705 100644
--- a/shared/extra-utils/users/index.ts
+++ b/shared/extra-utils/users/index.ts
@@ -2,6 +2,7 @@ export * from './accounts-command'
2export * from './accounts' 2export * from './accounts'
3export * from './blocklist-command' 3export * from './blocklist-command'
4export * from './login' 4export * from './login'
5export * from './login-command'
5export * from './notifications' 6export * from './notifications'
6export * from './notifications-command' 7export * from './notifications-command'
7export * from './subscriptions-command' 8export * from './subscriptions-command'
diff --git a/shared/extra-utils/users/login-command.ts b/shared/extra-utils/users/login-command.ts
new file mode 100644
index 000000000..97efcb766
--- /dev/null
+++ b/shared/extra-utils/users/login-command.ts
@@ -0,0 +1,134 @@
1import { PeerTubeRequestError } from '@server/helpers/requests'
2import { HttpStatusCode } from '@shared/core-utils'
3import { PeerTubeProblemDocument } from '@shared/models'
4import { unwrapBody } from '../requests'
5import { AbstractCommand, OverrideCommandOptions } from '../shared'
6
7export class LoginCommand extends AbstractCommand {
8
9 login (options: OverrideCommandOptions & {
10 client?: { id?: string, secret?: string }
11 user?: { username: string, password: string }
12 } = {}) {
13 const { client = this.server.client, user = this.server.user } = options
14 const path = '/api/v1/users/token'
15
16 const body = {
17 client_id: client.id,
18 client_secret: client.secret,
19 username: user.username,
20 password: user.password,
21 response_type: 'code',
22 grant_type: 'password',
23 scope: 'upload'
24 }
25
26 return unwrapBody<{ access_token: string, refresh_token: string } & PeerTubeProblemDocument>(this.postBodyRequest({
27 ...options,
28
29 path,
30 type: 'form',
31 fields: body,
32 implicitToken: false,
33 defaultExpectedStatus: HttpStatusCode.OK_200
34 }))
35 }
36
37 getAccessToken (user?: { username: string, password: string }): Promise<string>
38 getAccessToken (username: string, password: string): Promise<string>
39 async getAccessToken (arg1?: { username: string, password: string } | string, password?: string) {
40 let user: { username: string, password: string }
41
42 if (!arg1) user = this.server.user
43 else if (typeof arg1 === 'object') user = arg1
44 else user = { username: arg1, password }
45
46 try {
47 const body = await this.login({ user })
48
49 return body.access_token
50 } catch (err) {
51 throw new Error('Cannot authenticate. Please check your username/password.')
52 }
53 }
54
55 loginUsingExternalToken (options: OverrideCommandOptions & {
56 username: string
57 externalAuthToken: string
58 }) {
59 const { username, externalAuthToken } = options
60 const path = '/api/v1/users/token'
61
62 const body = {
63 client_id: this.server.client.id,
64 client_secret: this.server.client.secret,
65 username: username,
66 response_type: 'code',
67 grant_type: 'password',
68 scope: 'upload',
69 externalAuthToken
70 }
71
72 return this.postBodyRequest({
73 ...options,
74
75 path,
76 type: 'form',
77 fields: body,
78 implicitToken: false,
79 defaultExpectedStatus: HttpStatusCode.OK_200
80 })
81 }
82
83 logout (options: OverrideCommandOptions & {
84 token: string
85 }) {
86 const path = '/api/v1/users/revoke-token'
87
88 return unwrapBody<{ redirectUrl: string }>(this.postBodyRequest({
89 ...options,
90
91 path,
92 type: 'form',
93 implicitToken: false,
94 defaultExpectedStatus: HttpStatusCode.OK_200
95 }))
96 }
97
98 refreshToken (options: OverrideCommandOptions & {
99 refreshToken: string
100 }) {
101 const path = '/api/v1/users/token'
102
103 const body = {
104 client_id: this.server.client.id,
105 client_secret: this.server.client.secret,
106 refresh_token: options.refreshToken,
107 response_type: 'code',
108 grant_type: 'refresh_token'
109 }
110
111 return this.postBodyRequest({
112 ...options,
113
114 path,
115 type: 'form',
116 fields: body,
117 implicitToken: false,
118 defaultExpectedStatus: HttpStatusCode.OK_200
119 })
120 }
121
122 getClient (options: OverrideCommandOptions = {}) {
123 const path = '/api/v1/oauth-clients/local'
124
125 return this.getRequestBody<{ client_id: string, client_secret: string }>({
126 ...options,
127
128 path,
129 host: this.server.host,
130 implicitToken: false,
131 defaultExpectedStatus: HttpStatusCode.OK_200
132 })
133 }
134}
diff --git a/shared/extra-utils/users/login.ts b/shared/extra-utils/users/login.ts
index c14367542..d4ee8e517 100644
--- a/shared/extra-utils/users/login.ts
+++ b/shared/extra-utils/users/login.ts
@@ -1,133 +1,19 @@
1import * as request from 'supertest'
2
3import { ServerInfo } from '../server/servers' 1import { ServerInfo } from '../server/servers'
4import { getClient } from '../server/clients'
5import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
6
7type Client = { id?: string, secret?: string }
8type User = { username: string, password: string }
9type Server = { url?: string, client?: Client, user?: User }
10
11function login (url: string, client: Client, user: User, expectedStatus = HttpStatusCode.OK_200) {
12 const path = '/api/v1/users/token'
13
14 const body = {
15 client_id: client.id,
16 client_secret: client.secret,
17 username: user.username,
18 password: user.password,
19 response_type: 'code',
20 grant_type: 'password',
21 scope: 'upload'
22 }
23
24 return request(url)
25 .post(path)
26 .type('form')
27 .send(body)
28 .expect(expectedStatus)
29}
30
31function logout (url: string, token: string, expectedStatus = HttpStatusCode.OK_200) {
32 const path = '/api/v1/users/revoke-token'
33
34 return request(url)
35 .post(path)
36 .set('Authorization', 'Bearer ' + token)
37 .type('form')
38 .expect(expectedStatus)
39}
40
41async function serverLogin (server: Server) {
42 const res = await login(server.url, server.client, server.user, HttpStatusCode.OK_200)
43
44 return res.body.access_token as string
45}
46
47function refreshToken (server: ServerInfo, refreshToken: string, expectedStatus = HttpStatusCode.OK_200) {
48 const path = '/api/v1/users/token'
49
50 const body = {
51 client_id: server.client.id,
52 client_secret: server.client.secret,
53 refresh_token: refreshToken,
54 response_type: 'code',
55 grant_type: 'refresh_token'
56 }
57
58 return request(server.url)
59 .post(path)
60 .type('form')
61 .send(body)
62 .expect(expectedStatus)
63}
64
65async function userLogin (server: Server, user: User, expectedStatus = HttpStatusCode.OK_200) {
66 const res = await login(server.url, server.client, user, expectedStatus)
67
68 return res.body.access_token as string
69}
70
71async function getAccessToken (url: string, username: string, password: string) {
72 const resClient = await getClient(url)
73 const client = {
74 id: resClient.body.client_id,
75 secret: resClient.body.client_secret
76 }
77
78 const user = { username, password }
79
80 try {
81 const res = await login(url, client, user)
82 return res.body.access_token
83 } catch (err) {
84 throw new Error('Cannot authenticate. Please check your username/password.')
85 }
86}
87 2
88function setAccessTokensToServers (servers: ServerInfo[]) { 3function setAccessTokensToServers (servers: ServerInfo[]) {
89 const tasks: Promise<any>[] = [] 4 const tasks: Promise<any>[] = []
90 5
91 for (const server of servers) { 6 for (const server of servers) {
92 const p = serverLogin(server).then(t => { server.accessToken = t }) 7 const p = server.loginCommand.getAccessToken()
8 .then(t => { server.accessToken = t })
93 tasks.push(p) 9 tasks.push(p)
94 } 10 }
95 11
96 return Promise.all(tasks) 12 return Promise.all(tasks)
97} 13}
98 14
99function loginUsingExternalToken (server: Server, username: string, externalAuthToken: string, expectedStatus = HttpStatusCode.OK_200) {
100 const path = '/api/v1/users/token'
101
102 const body = {
103 client_id: server.client.id,
104 client_secret: server.client.secret,
105 username: username,
106 response_type: 'code',
107 grant_type: 'password',
108 scope: 'upload',
109 externalAuthToken
110 }
111
112 return request(server.url)
113 .post(path)
114 .type('form')
115 .send(body)
116 .expect(expectedStatus)
117}
118
119// --------------------------------------------------------------------------- 15// ---------------------------------------------------------------------------
120 16
121export { 17export {
122 login, 18 setAccessTokensToServers
123 logout,
124 serverLogin,
125 refreshToken,
126 userLogin,
127 getAccessToken,
128 setAccessTokensToServers,
129 Server,
130 Client,
131 User,
132 loginUsingExternalToken
133} 19}
diff --git a/shared/extra-utils/users/notifications.ts b/shared/extra-utils/users/notifications.ts
index 81f0729fa..79cb6f617 100644
--- a/shared/extra-utils/users/notifications.ts
+++ b/shared/extra-utils/users/notifications.ts
@@ -7,7 +7,7 @@ import { UserNotification, UserNotificationSetting, UserNotificationSettingValue
7import { MockSmtpServer } from '../mock-servers/mock-email' 7import { MockSmtpServer } from '../mock-servers/mock-email'
8import { doubleFollow } from '../server/follows' 8import { doubleFollow } from '../server/follows'
9import { flushAndRunMultipleServers, ServerInfo } from '../server/servers' 9import { flushAndRunMultipleServers, ServerInfo } from '../server/servers'
10import { setAccessTokensToServers, userLogin } from './login' 10import { setAccessTokensToServers } from './login'
11import { createUser, getMyUserInformation } from './users' 11import { createUser, getMyUserInformation } from './users'
12 12
13function getAllNotificationsSettings (): UserNotificationSetting { 13function getAllNotificationsSettings (): UserNotificationSetting {
@@ -662,7 +662,7 @@ async function prepareNotificationsTest (serversCount = 3, overrideConfigArg: an
662 password: user.password, 662 password: user.password,
663 videoQuota: 10 * 1000 * 1000 663 videoQuota: 10 * 1000 * 1000
664 }) 664 })
665 const userAccessToken = await userLogin(servers[0], user) 665 const userAccessToken = await servers[0].loginCommand.getAccessToken(user)
666 666
667 await servers[0].notificationsCommand.updateMySettings({ token: userAccessToken, settings: getAllNotificationsSettings() }) 667 await servers[0].notificationsCommand.updateMySettings({ token: userAccessToken, settings: getAllNotificationsSettings() })
668 await servers[0].notificationsCommand.updateMySettings({ settings: getAllNotificationsSettings() }) 668 await servers[0].notificationsCommand.updateMySettings({ settings: getAllNotificationsSettings() })
diff --git a/shared/extra-utils/users/users.ts b/shared/extra-utils/users/users.ts
index 0f15962ad..835ad08ba 100644
--- a/shared/extra-utils/users/users.ts
+++ b/shared/extra-utils/users/users.ts
@@ -7,7 +7,6 @@ import { UserRegister } from '../../models/users/user-register.model'
7import { UserRole } from '../../models/users/user-role' 7import { UserRole } from '../../models/users/user-role'
8import { makeGetRequest, makePostBodyRequest, makePutBodyRequest, updateImageRequest } from '../requests/requests' 8import { makeGetRequest, makePostBodyRequest, makePutBodyRequest, updateImageRequest } from '../requests/requests'
9import { ServerInfo } from '../server/servers' 9import { ServerInfo } from '../server/servers'
10import { userLogin } from './login'
11 10
12function createUser (parameters: { 11function createUser (parameters: {
13 url: string 12 url: string
@@ -55,7 +54,7 @@ async function generateUser (server: ServerInfo, username: string) {
55 const password = 'my super password' 54 const password = 'my super password'
56 const resCreate = await createUser({ url: server.url, accessToken: server.accessToken, username: username, password: password }) 55 const resCreate = await createUser({ url: server.url, accessToken: server.accessToken, username: username, password: password })
57 56
58 const token = await userLogin(server, { username, password }) 57 const token = await server.loginCommand.getAccessToken({ username, password })
59 58
60 const resMe = await getMyUserInformation(server.url, token) 59 const resMe = await getMyUserInformation(server.url, token)
61 60
@@ -70,7 +69,7 @@ async function generateUserAccessToken (server: ServerInfo, username: string) {
70 const password = 'my super password' 69 const password = 'my super password'
71 await createUser({ url: server.url, accessToken: server.accessToken, username: username, password: password }) 70 await createUser({ url: server.url, accessToken: server.accessToken, username: username, password: password })
72 71
73 return userLogin(server, { username, password }) 72 return server.loginCommand.getAccessToken({ username, password })
74} 73}
75 74
76function registerUser (url: string, username: string, password: string, specialStatus = HttpStatusCode.NO_CONTENT_204) { 75function registerUser (url: string, username: string, password: string, specialStatus = HttpStatusCode.NO_CONTENT_204) {