From 291e8d3eed88fe714fb74ad897ac2c67347a85ff Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 25 Jul 2017 20:17:28 +0200 Subject: [PATCH] Add ability to limit user registrations --- client/src/app/core/config/config.service.ts | 2 +- client/src/app/core/menu/menu.component.html | 2 +- client/src/app/core/menu/menu.component.ts | 4 +-- config/default.yaml | 1 + config/test-1.yaml | 3 ++ server/controllers/api/config.ts | 15 ++++---- server/controllers/api/users.ts | 4 +-- server/helpers/utils.ts | 20 ++++++++++- server/initializers/constants.ts | 3 +- server/middlewares/config.ts | 20 ----------- server/middlewares/index.ts | 1 - server/middlewares/validators/users.ts | 15 ++++++-- server/tests/api/check-params/users.js | 8 ++++- server/tests/api/config.js | 38 ++++++++++++++++++-- shared/models/server-config.model.ts | 2 +- 15 files changed, 97 insertions(+), 41 deletions(-) delete mode 100644 server/middlewares/config.ts diff --git a/client/src/app/core/config/config.service.ts b/client/src/app/core/config/config.service.ts index b8cb15e84..acdc12cc6 100644 --- a/client/src/app/core/config/config.service.ts +++ b/client/src/app/core/config/config.service.ts @@ -10,7 +10,7 @@ export class ConfigService { private config: ServerConfig = { signup: { - enabled: false + allowed: false } } diff --git a/client/src/app/core/menu/menu.component.html b/client/src/app/core/menu/menu.component.html index 63a1c03c5..fb4c4a6a9 100644 --- a/client/src/app/core/menu/menu.component.html +++ b/client/src/app/core/menu/menu.component.html @@ -14,7 +14,7 @@ - + Signup diff --git a/client/src/app/core/menu/menu.component.ts b/client/src/app/core/menu/menu.component.ts index b725f64a7..669fc6572 100644 --- a/client/src/app/core/menu/menu.component.ts +++ b/client/src/app/core/menu/menu.component.ts @@ -36,8 +36,8 @@ export class MenuComponent implements OnInit { ) } - isRegistrationEnabled () { - return this.configService.getConfig().signup.enabled + isRegistrationAllowed () { + return this.configService.getConfig().signup.allowed } isUserAdmin () { diff --git a/config/default.yaml b/config/default.yaml index b4e7606cf..a97d3ff78 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -33,6 +33,7 @@ admin: signup: enabled: false + limit: 10 # When the limit is reached, registrations are disabled. -1 == unlimited # If enabled, the video will be transcoded to mp4 (x264) with "faststart" flag # Uses a lot of CPU! diff --git a/config/test-1.yaml b/config/test-1.yaml index e244a8797..d08a3bee6 100644 --- a/config/test-1.yaml +++ b/config/test-1.yaml @@ -20,3 +20,6 @@ storage: admin: email: 'admin1@example.com' + +signup: + limit: 4 diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts index 3e9aa77a5..f02a2bc58 100644 --- a/server/controllers/api/config.ts +++ b/server/controllers/api/config.ts @@ -1,6 +1,6 @@ import * as express from 'express' -import { CONFIG } from '../../initializers' +import { isSignupAllowed } from '../../helpers' import { ServerConfig } from '../../../shared' const configRouter = express.Router() @@ -9,12 +9,15 @@ configRouter.get('/', getConfig) // Get the client credentials for the PeerTube front end function getConfig (req: express.Request, res: express.Response, next: express.NextFunction) { - const json: ServerConfig = { - signup: { - enabled: CONFIG.SIGNUP.ENABLED + + isSignupAllowed().then(allowed => { + const json: ServerConfig = { + signup: { + allowed + } } - } - res.json(json) + res.json(json) + }) } // --------------------------------------------------------------------------- diff --git a/server/controllers/api/users.ts b/server/controllers/api/users.ts index 6c375cc5b..f50dbc9a3 100644 --- a/server/controllers/api/users.ts +++ b/server/controllers/api/users.ts @@ -6,7 +6,7 @@ import { logger, getFormatedObjects } from '../../helpers' import { authenticate, ensureIsAdmin, - ensureUserRegistrationEnabled, + ensureUserRegistrationAllowed, usersAddValidator, usersUpdateValidator, usersRemoveValidator, @@ -48,7 +48,7 @@ usersRouter.post('/', ) usersRouter.post('/register', - ensureUserRegistrationEnabled, + ensureUserRegistrationAllowed, usersAddValidator, createUser ) diff --git a/server/helpers/utils.ts b/server/helpers/utils.ts index 9c08afb71..f326210f3 100644 --- a/server/helpers/utils.ts +++ b/server/helpers/utils.ts @@ -1,6 +1,8 @@ import * as express from 'express' +import * as Promise from 'bluebird' import { pseudoRandomBytesPromise } from './core-utils' +import { CONFIG, database as db } from '../initializers' import { ResultList } from '../../shared' function badRequest (req: express.Request, res: express.Response, next: express.NextFunction) { @@ -30,10 +32,26 @@ function getFormatedObjects (objects: T[], object return res } +function isSignupAllowed () { + if (CONFIG.SIGNUP.ENABLED === false) { + return Promise.resolve(false) + } + + // No limit and signup is enabled + if (CONFIG.SIGNUP.LIMIT === -1) { + return Promise.resolve(true) + } + + return db.User.countTotal().then(totalUsers => { + return totalUsers < CONFIG.SIGNUP.LIMIT + }) +} + // --------------------------------------------------------------------------- export { badRequest, generateRandomString, - getFormatedObjects + getFormatedObjects, + isSignupAllowed } diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 928a3f570..314a05ab7 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -76,7 +76,8 @@ const CONFIG = { EMAIL: config.get('admin.email') }, SIGNUP: { - ENABLED: config.get('signup.enabled') + ENABLED: config.get('signup.enabled'), + LIMIT: config.get('signup.limit') }, TRANSCODING: { ENABLED: config.get('transcoding.enabled'), diff --git a/server/middlewares/config.ts b/server/middlewares/config.ts deleted file mode 100644 index 1481e66cc..000000000 --- a/server/middlewares/config.ts +++ /dev/null @@ -1,20 +0,0 @@ -import 'express-validator' -import * as express from 'express' - -import { CONFIG } from '../initializers' - -function ensureUserRegistrationEnabled (req: express.Request, res: express.Response, next: express.NextFunction) { - const registrationEnabled = CONFIG.SIGNUP.ENABLED - - if (registrationEnabled === true) { - return next() - } - - return res.status(400).send('User registration is not enabled.') -} - -// --------------------------------------------------------------------------- - -export { - ensureUserRegistrationEnabled -} diff --git a/server/middlewares/index.ts b/server/middlewares/index.ts index 9a3f849a7..d71dd2452 100644 --- a/server/middlewares/index.ts +++ b/server/middlewares/index.ts @@ -1,6 +1,5 @@ export * from './validators' export * from './admin' -export * from './config' export * from './oauth' export * from './pagination' export * from './pods' diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts index 38f8aed5b..71e529872 100644 --- a/server/middlewares/validators/users.ts +++ b/server/middlewares/validators/users.ts @@ -5,7 +5,7 @@ import * as validator from 'validator' import { database as db } from '../../initializers/database' import { checkErrors } from './utils' -import { logger } from '../../helpers' +import { isSignupAllowed, logger } from '../../helpers' import { VideoInstance } from '../../models' function usersAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) { @@ -88,11 +88,22 @@ function usersVideoRatingValidator (req: express.Request, res: express.Response, }) } +function ensureUserRegistrationAllowed (req: express.Request, res: express.Response, next: express.NextFunction) { + isSignupAllowed().then(allowed => { + if (allowed === false) { + return res.status(403).send('User registration is not enabled or user limit is reached.') + } + + return next() + }) +} + // --------------------------------------------------------------------------- export { usersAddValidator, usersRemoveValidator, usersUpdateValidator, - usersVideoRatingValidator + usersVideoRatingValidator, + ensureUserRegistrationAllowed } diff --git a/server/tests/api/check-params/users.js b/server/tests/api/check-params/users.js index 2c1189f7a..9e7115da1 100644 --- a/server/tests/api/check-params/users.js +++ b/server/tests/api/check-params/users.js @@ -513,7 +513,13 @@ describe('Test users API validators', function () { password: 'my super password 4' } - requestsUtils.makePostBodyRequest(serverWithRegistrationDisabled.url, registrationPath, serverWithRegistrationDisabled.accessToken, data, done, 400) + requestsUtils.makePostBodyRequest(serverWithRegistrationDisabled.url, registrationPath, serverWithRegistrationDisabled.accessToken, data, done, 403) + }) + }) + + describe('When registering multiple users on a server with users limit', function () { + it('Should fail when after 3 registrations', function (done) { + usersUtils.registerUser(server.url, 'user42', 'super password', 403, done) }) }) diff --git a/server/tests/api/config.js b/server/tests/api/config.js index e79e12823..f2c00f85a 100644 --- a/server/tests/api/config.js +++ b/server/tests/api/config.js @@ -8,6 +8,7 @@ const series = require('async/series') const serversUtils = require('../utils/servers') const configUtils = require('../utils/config') +const usersUtils = require('../utils/users') describe('Test config', function () { let server = null @@ -28,18 +29,51 @@ describe('Test config', function () { ], done) }) - it('Should have a correct config', function (done) { + it('Should have a correct config on a server with registration enabled', function (done) { configUtils.getConfig(server.url, function (err, res) { if (err) throw err const data = res.body - expect(data.signup.enabled).to.be.truthy + expect(data.signup.allowed).to.be.truthy done() }) }) + it('Should have a correct config on a server with registration enabled and a users limit', function (done) { + series([ + function (next) { + usersUtils.registerUser(server.url, 'user1', 'super password', done) + }, + + function (next) { + usersUtils.registerUser(server.url, 'user2', 'super password', done) + }, + + function (next) { + usersUtils.registerUser(server.url, 'user3', 'super password', done) + }, + + function (next) { + usersUtils.registerUser(server.url, 'user4', 'super password', done) + } + + ], function (err) { + if (err) throw err + + configUtils.getConfig(server.url, function (err, res) { + if (err) throw err + + const data = res.body + + expect(data.signup.allowed).to.be.truthy + + done() + }) + }) + }) + after(function (done) { process.kill(-server.app.pid) diff --git a/shared/models/server-config.model.ts b/shared/models/server-config.model.ts index a39156963..aab842905 100644 --- a/shared/models/server-config.model.ts +++ b/shared/models/server-config.model.ts @@ -1,5 +1,5 @@ export interface ServerConfig { signup: { - enabled: boolean + allowed: boolean } }