Commit b379759f authored by Chocobozzz's avatar Chocobozzz Committed by Chocobozzz
Browse files

Add signup approval API tests

parent 3e5716dd
......@@ -79,6 +79,7 @@ describe('Test config API validators', function () {
signup: {
enabled: false,
limit: 5,
requiresApproval: false,
requiresEmailVerification: false,
minimumAge: 16
},
......@@ -313,6 +314,7 @@ describe('Test config API validators', function () {
signup: {
enabled: true,
limit: 5,
requiresApproval: true,
requiresEmailVerification: true
}
}
......
......@@ -2,7 +2,14 @@
import { MockSmtpServer } from '@server/tests/shared'
import { HttpStatusCode } from '@shared/models'
import { cleanupTests, ContactFormCommand, createSingleServer, killallServers, PeerTubeServer } from '@shared/server-commands'
import {
cleanupTests,
ConfigCommand,
ContactFormCommand,
createSingleServer,
killallServers,
PeerTubeServer
} from '@shared/server-commands'
describe('Test contact form API validators', function () {
let server: PeerTubeServer
......@@ -38,7 +45,7 @@ describe('Test contact form API validators', function () {
await killallServers([ server ])
// Contact form is disabled
await server.run({ smtp: { hostname: '127.0.0.1', port: emailPort }, contact_form: { enabled: false } })
await server.run({ ...ConfigCommand.getEmailOverrideConfig(emailPort), contact_form: { enabled: false } })
await command.send({ ...defaultBody, expectedStatus: HttpStatusCode.CONFLICT_409 })
})
......@@ -48,7 +55,7 @@ describe('Test contact form API validators', function () {
await killallServers([ server ])
// Email & contact form enabled
await server.run({ smtp: { hostname: '127.0.0.1', port: emailPort } })
await server.run(ConfigCommand.getEmailOverrideConfig(emailPort))
await command.send({ ...defaultBody, fromEmail: 'badEmail', expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
await command.send({ ...defaultBody, fromEmail: 'badEmail@', expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
......
......@@ -15,6 +15,7 @@ import './metrics'
import './my-user'
import './plugins'
import './redundancy'
import './registrations'
import './search'
import './services'
import './transcoding'
......@@ -23,7 +24,7 @@ import './upload-quota'
import './user-notifications'
import './user-subscriptions'
import './users-admin'
import './users'
import './users-emails'
import './video-blacklist'
import './video-captions'
import './video-channel-syncs'
......
import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@server/tests/shared'
import { omit } from '@shared/core-utils'
import { HttpStatusCode, UserRole } from '@shared/models'
import { cleanupTests, createSingleServer, makePostBodyRequest, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands'
describe('Test registrations API validators', function () {
let server: PeerTubeServer
let userToken: string
let moderatorToken: string
// ---------------------------------------------------------------
before(async function () {
this.timeout(30000)
server = await createSingleServer(1)
await setAccessTokensToServers([ server ])
await server.config.enableSignup(false);
({ token: moderatorToken } = await server.users.generate('moderator', UserRole.MODERATOR));
({ token: userToken } = await server.users.generate('user', UserRole.USER))
})
describe('Register', function () {
const registrationPath = '/api/v1/users/register'
const registrationRequestPath = '/api/v1/users/registrations/request'
const baseCorrectParams = {
username: 'user3',
displayName: 'super user',
email: 'test3@example.com',
password: 'my super password',
registrationReason: 'my super registration reason'
}
describe('When registering a new user or requesting user registration', function () {
async function check (fields: any, expectedStatus = HttpStatusCode.BAD_REQUEST_400) {
await makePostBodyRequest({ url: server.url, path: registrationPath, fields, expectedStatus })
await makePostBodyRequest({ url: server.url, path: registrationRequestPath, fields, expectedStatus })
}
it('Should fail with a too small username', async function () {
const fields = { ...baseCorrectParams, username: '' }
await check(fields)
})
it('Should fail with a too long username', async function () {
const fields = { ...baseCorrectParams, username: 'super'.repeat(50) }
await check(fields)
})
it('Should fail with an incorrect username', async function () {
const fields = { ...baseCorrectParams, username: 'my username' }
await check(fields)
})
it('Should fail with a missing email', async function () {
const fields = omit(baseCorrectParams, [ 'email' ])
await check(fields)
})
it('Should fail with an invalid email', async function () {
const fields = { ...baseCorrectParams, email: 'test_example.com' }
await check(fields)
})
it('Should fail with a too small password', async function () {
const fields = { ...baseCorrectParams, password: 'bla' }
await check(fields)
})
it('Should fail with a too long password', async function () {
const fields = { ...baseCorrectParams, password: 'super'.repeat(61) }
await check(fields)
})
it('Should fail if we register a user with the same username', async function () {
const fields = { ...baseCorrectParams, username: 'root' }
await check(fields, HttpStatusCode.CONFLICT_409)
})
it('Should fail with a "peertube" username', async function () {
const fields = { ...baseCorrectParams, username: 'peertube' }
await check(fields, HttpStatusCode.CONFLICT_409)
})
it('Should fail if we register a user with the same email', async function () {
const fields = { ...baseCorrectParams, email: 'admin' + server.internalServerNumber + '@example.com' }
await check(fields, HttpStatusCode.CONFLICT_409)
})
it('Should fail with a bad display name', async function () {
const fields = { ...baseCorrectParams, displayName: 'a'.repeat(150) }
await check(fields)
})
it('Should fail with a bad channel name', async function () {
const fields = { ...baseCorrectParams, channel: { name: '[]azf', displayName: 'toto' } }
await check(fields)
})
it('Should fail with a bad channel display name', async function () {
const fields = { ...baseCorrectParams, channel: { name: 'toto', displayName: '' } }
await check(fields)
})
it('Should fail with a channel name that is the same as username', async function () {
const source = { username: 'super_user', channel: { name: 'super_user', displayName: 'display name' } }
const fields = { ...baseCorrectParams, ...source }
await check(fields)
})
it('Should fail with an existing channel', async function () {
const attributes = { name: 'existing_channel', displayName: 'hello', description: 'super description' }
await server.channels.create({ attributes })
const fields = { ...baseCorrectParams, channel: { name: 'existing_channel', displayName: 'toto' } }
await check(fields, HttpStatusCode.CONFLICT_409)
})
it('Should fail on a server with registration disabled', async function () {
this.timeout(60000)
await server.config.updateCustomSubConfig({
newConfig: {
signup: {
enabled: false
}
}
})
await server.registrations.register({ username: 'user4', expectedStatus: HttpStatusCode.FORBIDDEN_403 })
await server.registrations.requestRegistration({
username: 'user4',
registrationReason: 'reason',
expectedStatus: HttpStatusCode.FORBIDDEN_403
})
})
it('Should fail if the user limit is reached', async function () {
this.timeout(60000)
const { total } = await server.users.list()
await server.config.updateCustomSubConfig({ newConfig: { signup: { limit: total } } })
await server.registrations.register({ username: 'user42', expectedStatus: HttpStatusCode.FORBIDDEN_403 })
await server.registrations.requestRegistration({
username: 'user42',
registrationReason: 'reason',
expectedStatus: HttpStatusCode.FORBIDDEN_403
})
})
})
describe('On direct registration', function () {
it('Should succeed with the correct params', async function () {
await server.config.enableSignup(false)
const fields = {
username: 'user_direct_1',
displayName: 'super user direct 1',
email: 'user_direct_1@example.com',
password: 'my super password',
channel: { name: 'super_user_direct_1_channel', displayName: 'super user direct 1 channel' }
}
await makePostBodyRequest({ url: server.url, path: registrationPath, fields, expectedStatus: HttpStatusCode.NO_CONTENT_204 })
})
it('Should fail if the instance requires approval', async function () {
this.timeout(60000)
await server.config.enableSignup(true)
await server.registrations.register({ username: 'user42', expectedStatus: HttpStatusCode.FORBIDDEN_403 })
})
})
describe('On registration request', function () {
before(async function () {
this.timeout(60000)
await server.config.enableSignup(true)
})
it('Should fail with an invalid registration reason', async function () {
for (const registrationReason of [ '', 't', 't'.repeat(5000) ]) {
await server.registrations.requestRegistration({
username: 'user_request_1',
registrationReason,
expectedStatus: HttpStatusCode.BAD_REQUEST_400
})
}
})
it('Should succeed with the correct params', async function () {
await server.registrations.requestRegistration({
username: 'user_request_2',
registrationReason: 'tt',
channel: {
displayName: 'my user request 2 channel',
name: 'user_request_2_channel'
}
})
})
it('Should fail if the user is already awaiting registration approval', async function () {
await server.registrations.requestRegistration({
username: 'user_request_2',
registrationReason: 'tt',
channel: {
displayName: 'my user request 42 channel',
name: 'user_request_42_channel'
},
expectedStatus: HttpStatusCode.CONFLICT_409
})
})
it('Should fail if the channel is already awaiting registration approval', async function () {
await server.registrations.requestRegistration({
username: 'user42',
registrationReason: 'tt',
channel: {
displayName: 'my user request 2 channel',
name: 'user_request_2_channel'
},
expectedStatus: HttpStatusCode.CONFLICT_409
})
})
it('Should fail if the instance does not require approval', async function () {
this.timeout(60000)
await server.config.enableSignup(false)
await server.registrations.requestRegistration({
username: 'user42',
registrationReason: 'toto',
expectedStatus: HttpStatusCode.BAD_REQUEST_400
})
})
})
})
describe('Registrations accept/reject', function () {
let id1: number
let id2: number
before(async function () {
this.timeout(60000)
await server.config.enableSignup(true);
({ id: id1 } = await server.registrations.requestRegistration({ username: 'request_2', registrationReason: 'toto' }));
({ id: id2 } = await server.registrations.requestRegistration({ username: 'request_3', registrationReason: 'toto' }))
})
it('Should fail to accept/reject registration without token', async function () {
const options = { id: id1, moderationResponse: 'tt', token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }
await server.registrations.accept(options)
await server.registrations.reject(options)
})
it('Should fail to accept/reject registration with a non moderator user', async function () {
const options = { id: id1, moderationResponse: 'tt', token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }
await server.registrations.accept(options)
await server.registrations.reject(options)
})
it('Should fail to accept/reject registration with a bad registration id', async function () {
{
const options = { id: 't' as any, moderationResponse: 'tt', token: moderatorToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }
await server.registrations.accept(options)
await server.registrations.reject(options)
}
{
const options = { id: 42, moderationResponse: 'tt', token: moderatorToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }
await server.registrations.accept(options)
await server.registrations.reject(options)
}
})
it('Should fail to accept/reject registration with a bad moderation resposne', async function () {
for (const moderationResponse of [ '', 't', 't'.repeat(5000) ]) {
const options = { id: id1, moderationResponse, token: moderatorToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }
await server.registrations.accept(options)
await server.registrations.reject(options)
}
})
it('Should succeed to accept a registration', async function () {
await server.registrations.accept({ id: id1, moderationResponse: 'tt', token: moderatorToken })
})
it('Should succeed to reject a registration', async function () {
await server.registrations.reject({ id: id2, moderationResponse: 'tt', token: moderatorToken })
})
it('Should fail to accept/reject a registration that was already accepted/rejected', async function () {
for (const id of [ id1, id2 ]) {
const options = { id, moderationResponse: 'tt', token: moderatorToken, expectedStatus: HttpStatusCode.CONFLICT_409 }
await server.registrations.accept(options)
await server.registrations.reject(options)
}
})
})
describe('Registrations deletion', function () {
let id1: number
let id2: number
let id3: number
before(async function () {
({ id: id1 } = await server.registrations.requestRegistration({ username: 'request_4', registrationReason: 'toto' }));
({ id: id2 } = await server.registrations.requestRegistration({ username: 'request_5', registrationReason: 'toto' }));
({ id: id3 } = await server.registrations.requestRegistration({ username: 'request_6', registrationReason: 'toto' }))
await server.registrations.accept({ id: id2, moderationResponse: 'tt' })
await server.registrations.reject({ id: id3, moderationResponse: 'tt' })
})
it('Should fail to delete registration without token', async function () {
await server.registrations.delete({ id: id1, token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
})
it('Should fail to delete registration with a non moderator user', async function () {
await server.registrations.delete({ id: id1, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
})
it('Should fail to delete registration with a bad registration id', async function () {
await server.registrations.delete({ id: 't' as any, token: moderatorToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 })
await server.registrations.delete({ id: 42, token: moderatorToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
})
it('Should succeed with the correct params', async function () {
await server.registrations.delete({ id: id1, token: moderatorToken })
await server.registrations.delete({ id: id2, token: moderatorToken })
await server.registrations.delete({ id: id3, token: moderatorToken })
})
})
describe('Listing registrations', function () {
const path = '/api/v1/users/registrations'
it('Should fail with a bad start pagination', async function () {
await checkBadStartPagination(server.url, path, server.accessToken)
})
it('Should fail with a bad count pagination', async function () {
await checkBadCountPagination(server.url, path, server.accessToken)
})
it('Should fail with an incorrect sort', async function () {
await checkBadSortPagination(server.url, path, server.accessToken)
})
it('Should fail with a non authenticated user', async function () {
await server.registrations.list({
token: null,
expectedStatus: HttpStatusCode.UNAUTHORIZED_401
})
})
it('Should fail with a non admin user', async function () {
await server.registrations.list({
token: userToken,
expectedStatus: HttpStatusCode.FORBIDDEN_403
})
})
it('Should succeed with the correct params', async function () {
await server.registrations.list({
token: moderatorToken,
search: 'toto'
})
})
})
after(async function () {
await cleanupTests([ server ])
})
})
......@@ -42,7 +42,7 @@ describe('Test upload quota', function () {
this.timeout(30000)
const user = { username: 'registered' + randomInt(1, 1500), password: 'password' }
await server.users.register(user)
await server.registrations.register(user)
const userToken = await server.login.getAccessToken(user)
const attributes = { fixture: 'video_short2.webm' }
......@@ -57,7 +57,7 @@ describe('Test upload quota', function () {
this.timeout(30000)
const user = { username: 'registered' + randomInt(1, 1500), password: 'password' }
await server.users.register(user)
await server.registrations.register(user)
const userToken = await server.login.getAccessToken(user)
const attributes = { fixture: 'video_short2.webm' }
......
......@@ -5,6 +5,7 @@ import { omit } from '@shared/core-utils'
import { HttpStatusCode, UserAdminFlag, UserRole } from '@shared/models'
import {
cleanupTests,
ConfigCommand,
createSingleServer,
killallServers,
makeGetRequest,
......@@ -156,13 +157,7 @@ describe('Test users admin API validators', function () {
await killallServers([ server ])
const config = {
smtp: {
hostname: '127.0.0.1',
port: emailPort
}
}
await server.run(config)
await server.run(ConfigCommand.getEmailOverrideConfig(emailPort))
const fields = {
...baseCorrectParams,
......
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
import { MockSmtpServer } from '@server/tests/shared'
import { HttpStatusCode, UserRole } from '@shared/models'
import { cleanupTests, createSingleServer, makePostBodyRequest, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands'
describe('Test users API validators', function () {
let server: PeerTubeServer
// ---------------------------------------------------------------
before(async function () {
this.timeout(30000)
server = await createSingleServer(1, {
rates_limit: {
ask_send_email: {
max: 10
}
}
})
await setAccessTokensToServers([ server ])
await server.config.enableSignup(true)
await server.users.generate('moderator2', UserRole.MODERATOR)
await server.registrations.requestRegistration({
username: 'request1',
registrationReason: 'tt'
})
})
describe('When asking a password reset', function () {
const path = '/api/v1/users/ask-reset-password'
it('Should fail with a missing email', async function () {
const fields = {}
await makePostBodyRequest({ url: server.url, path, fields })
})
it('Should fail with an invalid email', async function () {
const fields = { email: 'hello' }
await makePostBodyRequest({ url: server.url, path, fields })
})
it('Should success with the correct params', async function () {
const fields = { email: 'admin@example.com' }
await makePostBodyRequest({
url: server.url,
path,
fields,
expectedStatus: HttpStatusCode.NO_CONTENT_204
})
})
})
describe('When asking for an account verification email', function () {
const path = '/api/v1/users/ask-send-verify-email'
it('Should fail with a missing email', async function () {
const fields = {}
await makePostBodyRequest({ url: server.url, path, fields })
})
it('Should fail with an invalid email', async function () {
const fields = { email: 'hello' }