Add ability to limit user registrations

This commit is contained in:
Chocobozzz 2017-07-25 20:17:28 +02:00
parent 3d09cdbf90
commit 291e8d3eed
15 changed files with 97 additions and 41 deletions

View File

@ -10,7 +10,7 @@ export class ConfigService {
private config: ServerConfig = {
signup: {
enabled: false
allowed: false
}
}

View File

@ -14,7 +14,7 @@
</a>
</div>
<a *ngIf="!isLoggedIn && isRegistrationEnabled()" routerLink="/signup" routerLinkActive="active">
<a *ngIf="!isLoggedIn && isRegistrationAllowed()" routerLink="/signup" routerLinkActive="active">
<span class="hidden-xs glyphicon glyphicon-user"></span>
Signup
</a>

View File

@ -36,8 +36,8 @@ export class MenuComponent implements OnInit {
)
}
isRegistrationEnabled () {
return this.configService.getConfig().signup.enabled
isRegistrationAllowed () {
return this.configService.getConfig().signup.allowed
}
isUserAdmin () {

View File

@ -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!

View File

@ -20,3 +20,6 @@ storage:
admin:
email: 'admin1@example.com'
signup:
limit: 4

View File

@ -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)
})
}
// ---------------------------------------------------------------------------

View File

@ -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
)

View File

@ -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<U, T extends FormatableToJSON> (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
}

View File

@ -76,7 +76,8 @@ const CONFIG = {
EMAIL: config.get<string>('admin.email')
},
SIGNUP: {
ENABLED: config.get<boolean>('signup.enabled')
ENABLED: config.get<boolean>('signup.enabled'),
LIMIT: config.get<number>('signup.limit')
},
TRANSCODING: {
ENABLED: config.get<boolean>('transcoding.enabled'),

View File

@ -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
}

View File

@ -1,6 +1,5 @@
export * from './validators'
export * from './admin'
export * from './config'
export * from './oauth'
export * from './pagination'
export * from './pods'

View File

@ -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
}

View File

@ -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)
})
})

View File

@ -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)

View File

@ -1,5 +1,5 @@
export interface ServerConfig {
signup: {
enabled: boolean
allowed: boolean
}
}