From 41d1d075011174e73dccb74006181a92a618d7b4 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 13 Jul 2021 11:05:15 +0200 Subject: Introduce login command --- shared/extra-utils/users/index.ts | 1 + shared/extra-utils/users/login-command.ts | 134 ++++++++++++++++++++++++++++++ shared/extra-utils/users/login.ts | 120 +------------------------- shared/extra-utils/users/notifications.ts | 4 +- shared/extra-utils/users/users.ts | 5 +- 5 files changed, 142 insertions(+), 122 deletions(-) create mode 100644 shared/extra-utils/users/login-command.ts (limited to 'shared/extra-utils/users') 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' export * from './accounts' export * from './blocklist-command' export * from './login' +export * from './login-command' export * from './notifications' export * from './notifications-command' export * 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 @@ +import { PeerTubeRequestError } from '@server/helpers/requests' +import { HttpStatusCode } from '@shared/core-utils' +import { PeerTubeProblemDocument } from '@shared/models' +import { unwrapBody } from '../requests' +import { AbstractCommand, OverrideCommandOptions } from '../shared' + +export class LoginCommand extends AbstractCommand { + + login (options: OverrideCommandOptions & { + client?: { id?: string, secret?: string } + user?: { username: string, password: string } + } = {}) { + const { client = this.server.client, user = this.server.user } = options + const path = '/api/v1/users/token' + + const body = { + client_id: client.id, + client_secret: client.secret, + username: user.username, + password: user.password, + response_type: 'code', + grant_type: 'password', + scope: 'upload' + } + + return unwrapBody<{ access_token: string, refresh_token: string } & PeerTubeProblemDocument>(this.postBodyRequest({ + ...options, + + path, + type: 'form', + fields: body, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + })) + } + + getAccessToken (user?: { username: string, password: string }): Promise + getAccessToken (username: string, password: string): Promise + async getAccessToken (arg1?: { username: string, password: string } | string, password?: string) { + let user: { username: string, password: string } + + if (!arg1) user = this.server.user + else if (typeof arg1 === 'object') user = arg1 + else user = { username: arg1, password } + + try { + const body = await this.login({ user }) + + return body.access_token + } catch (err) { + throw new Error('Cannot authenticate. Please check your username/password.') + } + } + + loginUsingExternalToken (options: OverrideCommandOptions & { + username: string + externalAuthToken: string + }) { + const { username, externalAuthToken } = options + const path = '/api/v1/users/token' + + const body = { + client_id: this.server.client.id, + client_secret: this.server.client.secret, + username: username, + response_type: 'code', + grant_type: 'password', + scope: 'upload', + externalAuthToken + } + + return this.postBodyRequest({ + ...options, + + path, + type: 'form', + fields: body, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + logout (options: OverrideCommandOptions & { + token: string + }) { + const path = '/api/v1/users/revoke-token' + + return unwrapBody<{ redirectUrl: string }>(this.postBodyRequest({ + ...options, + + path, + type: 'form', + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + })) + } + + refreshToken (options: OverrideCommandOptions & { + refreshToken: string + }) { + const path = '/api/v1/users/token' + + const body = { + client_id: this.server.client.id, + client_secret: this.server.client.secret, + refresh_token: options.refreshToken, + response_type: 'code', + grant_type: 'refresh_token' + } + + return this.postBodyRequest({ + ...options, + + path, + type: 'form', + fields: body, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + getClient (options: OverrideCommandOptions = {}) { + const path = '/api/v1/oauth-clients/local' + + return this.getRequestBody<{ client_id: string, client_secret: string }>({ + ...options, + + path, + host: this.server.host, + implicitToken: false, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } +} 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 @@ -import * as request from 'supertest' - import { ServerInfo } from '../server/servers' -import { getClient } from '../server/clients' -import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' - -type Client = { id?: string, secret?: string } -type User = { username: string, password: string } -type Server = { url?: string, client?: Client, user?: User } - -function login (url: string, client: Client, user: User, expectedStatus = HttpStatusCode.OK_200) { - const path = '/api/v1/users/token' - - const body = { - client_id: client.id, - client_secret: client.secret, - username: user.username, - password: user.password, - response_type: 'code', - grant_type: 'password', - scope: 'upload' - } - - return request(url) - .post(path) - .type('form') - .send(body) - .expect(expectedStatus) -} - -function logout (url: string, token: string, expectedStatus = HttpStatusCode.OK_200) { - const path = '/api/v1/users/revoke-token' - - return request(url) - .post(path) - .set('Authorization', 'Bearer ' + token) - .type('form') - .expect(expectedStatus) -} - -async function serverLogin (server: Server) { - const res = await login(server.url, server.client, server.user, HttpStatusCode.OK_200) - - return res.body.access_token as string -} - -function refreshToken (server: ServerInfo, refreshToken: string, expectedStatus = HttpStatusCode.OK_200) { - const path = '/api/v1/users/token' - - const body = { - client_id: server.client.id, - client_secret: server.client.secret, - refresh_token: refreshToken, - response_type: 'code', - grant_type: 'refresh_token' - } - - return request(server.url) - .post(path) - .type('form') - .send(body) - .expect(expectedStatus) -} - -async function userLogin (server: Server, user: User, expectedStatus = HttpStatusCode.OK_200) { - const res = await login(server.url, server.client, user, expectedStatus) - - return res.body.access_token as string -} - -async function getAccessToken (url: string, username: string, password: string) { - const resClient = await getClient(url) - const client = { - id: resClient.body.client_id, - secret: resClient.body.client_secret - } - - const user = { username, password } - - try { - const res = await login(url, client, user) - return res.body.access_token - } catch (err) { - throw new Error('Cannot authenticate. Please check your username/password.') - } -} function setAccessTokensToServers (servers: ServerInfo[]) { const tasks: Promise[] = [] for (const server of servers) { - const p = serverLogin(server).then(t => { server.accessToken = t }) + const p = server.loginCommand.getAccessToken() + .then(t => { server.accessToken = t }) tasks.push(p) } return Promise.all(tasks) } -function loginUsingExternalToken (server: Server, username: string, externalAuthToken: string, expectedStatus = HttpStatusCode.OK_200) { - const path = '/api/v1/users/token' - - const body = { - client_id: server.client.id, - client_secret: server.client.secret, - username: username, - response_type: 'code', - grant_type: 'password', - scope: 'upload', - externalAuthToken - } - - return request(server.url) - .post(path) - .type('form') - .send(body) - .expect(expectedStatus) -} - // --------------------------------------------------------------------------- export { - login, - logout, - serverLogin, - refreshToken, - userLogin, - getAccessToken, - setAccessTokensToServers, - Server, - Client, - User, - loginUsingExternalToken + setAccessTokensToServers } 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 import { MockSmtpServer } from '../mock-servers/mock-email' import { doubleFollow } from '../server/follows' import { flushAndRunMultipleServers, ServerInfo } from '../server/servers' -import { setAccessTokensToServers, userLogin } from './login' +import { setAccessTokensToServers } from './login' import { createUser, getMyUserInformation } from './users' function getAllNotificationsSettings (): UserNotificationSetting { @@ -662,7 +662,7 @@ async function prepareNotificationsTest (serversCount = 3, overrideConfigArg: an password: user.password, videoQuota: 10 * 1000 * 1000 }) - const userAccessToken = await userLogin(servers[0], user) + const userAccessToken = await servers[0].loginCommand.getAccessToken(user) await servers[0].notificationsCommand.updateMySettings({ token: userAccessToken, settings: getAllNotificationsSettings() }) 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' import { UserRole } from '../../models/users/user-role' import { makeGetRequest, makePostBodyRequest, makePutBodyRequest, updateImageRequest } from '../requests/requests' import { ServerInfo } from '../server/servers' -import { userLogin } from './login' function createUser (parameters: { url: string @@ -55,7 +54,7 @@ async function generateUser (server: ServerInfo, username: string) { const password = 'my super password' const resCreate = await createUser({ url: server.url, accessToken: server.accessToken, username: username, password: password }) - const token = await userLogin(server, { username, password }) + const token = await server.loginCommand.getAccessToken({ username, password }) const resMe = await getMyUserInformation(server.url, token) @@ -70,7 +69,7 @@ async function generateUserAccessToken (server: ServerInfo, username: string) { const password = 'my super password' await createUser({ url: server.url, accessToken: server.accessToken, username: username, password: password }) - return userLogin(server, { username, password }) + return server.loginCommand.getAccessToken({ username, password }) } function registerUser (url: string, username: string, password: string, specialStatus = HttpStatusCode.NO_CONTENT_204) { -- cgit v1.2.3