diff options
author | Chocobozzz <florian.bigard@gmail.com> | 2017-07-25 20:17:28 +0200 |
---|---|---|
committer | Chocobozzz <florian.bigard@gmail.com> | 2017-07-25 20:17:28 +0200 |
commit | 291e8d3eed88fe714fb74ad897ac2c67347a85ff (patch) | |
tree | 20b4f9b8500ab4d9651d2a067fcf2948a6bfc9a4 | |
parent | 3d09cdbf90902894c841d0a5ddb35eb772c53b8b (diff) | |
download | PeerTube-291e8d3eed88fe714fb74ad897ac2c67347a85ff.tar.gz PeerTube-291e8d3eed88fe714fb74ad897ac2c67347a85ff.tar.zst PeerTube-291e8d3eed88fe714fb74ad897ac2c67347a85ff.zip |
Add ability to limit user registrations
-rw-r--r-- | client/src/app/core/config/config.service.ts | 2 | ||||
-rw-r--r-- | client/src/app/core/menu/menu.component.html | 2 | ||||
-rw-r--r-- | client/src/app/core/menu/menu.component.ts | 4 | ||||
-rw-r--r-- | config/default.yaml | 1 | ||||
-rw-r--r-- | config/test-1.yaml | 3 | ||||
-rw-r--r-- | server/controllers/api/config.ts | 15 | ||||
-rw-r--r-- | server/controllers/api/users.ts | 4 | ||||
-rw-r--r-- | server/helpers/utils.ts | 20 | ||||
-rw-r--r-- | server/initializers/constants.ts | 3 | ||||
-rw-r--r-- | server/middlewares/config.ts | 20 | ||||
-rw-r--r-- | server/middlewares/index.ts | 1 | ||||
-rw-r--r-- | server/middlewares/validators/users.ts | 15 | ||||
-rw-r--r-- | server/tests/api/check-params/users.js | 8 | ||||
-rw-r--r-- | server/tests/api/config.js | 38 | ||||
-rw-r--r-- | shared/models/server-config.model.ts | 2 |
15 files changed, 97 insertions, 41 deletions
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 { | |||
10 | 10 | ||
11 | private config: ServerConfig = { | 11 | private config: ServerConfig = { |
12 | signup: { | 12 | signup: { |
13 | enabled: false | 13 | allowed: false |
14 | } | 14 | } |
15 | } | 15 | } |
16 | 16 | ||
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 @@ | |||
14 | </a> | 14 | </a> |
15 | </div> | 15 | </div> |
16 | 16 | ||
17 | <a *ngIf="!isLoggedIn && isRegistrationEnabled()" routerLink="/signup" routerLinkActive="active"> | 17 | <a *ngIf="!isLoggedIn && isRegistrationAllowed()" routerLink="/signup" routerLinkActive="active"> |
18 | <span class="hidden-xs glyphicon glyphicon-user"></span> | 18 | <span class="hidden-xs glyphicon glyphicon-user"></span> |
19 | Signup | 19 | Signup |
20 | </a> | 20 | </a> |
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 { | |||
36 | ) | 36 | ) |
37 | } | 37 | } |
38 | 38 | ||
39 | isRegistrationEnabled () { | 39 | isRegistrationAllowed () { |
40 | return this.configService.getConfig().signup.enabled | 40 | return this.configService.getConfig().signup.allowed |
41 | } | 41 | } |
42 | 42 | ||
43 | isUserAdmin () { | 43 | 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: | |||
33 | 33 | ||
34 | signup: | 34 | signup: |
35 | enabled: false | 35 | enabled: false |
36 | limit: 10 # When the limit is reached, registrations are disabled. -1 == unlimited | ||
36 | 37 | ||
37 | # If enabled, the video will be transcoded to mp4 (x264) with "faststart" flag | 38 | # If enabled, the video will be transcoded to mp4 (x264) with "faststart" flag |
38 | # Uses a lot of CPU! | 39 | # 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: | |||
20 | 20 | ||
21 | admin: | 21 | admin: |
22 | email: 'admin1@example.com' | 22 | email: 'admin1@example.com' |
23 | |||
24 | signup: | ||
25 | 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 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | 2 | ||
3 | import { CONFIG } from '../../initializers' | 3 | import { isSignupAllowed } from '../../helpers' |
4 | import { ServerConfig } from '../../../shared' | 4 | import { ServerConfig } from '../../../shared' |
5 | 5 | ||
6 | const configRouter = express.Router() | 6 | const configRouter = express.Router() |
@@ -9,12 +9,15 @@ configRouter.get('/', getConfig) | |||
9 | 9 | ||
10 | // Get the client credentials for the PeerTube front end | 10 | // Get the client credentials for the PeerTube front end |
11 | function getConfig (req: express.Request, res: express.Response, next: express.NextFunction) { | 11 | function getConfig (req: express.Request, res: express.Response, next: express.NextFunction) { |
12 | const json: ServerConfig = { | 12 | |
13 | signup: { | 13 | isSignupAllowed().then(allowed => { |
14 | enabled: CONFIG.SIGNUP.ENABLED | 14 | const json: ServerConfig = { |
15 | signup: { | ||
16 | allowed | ||
17 | } | ||
15 | } | 18 | } |
16 | } | 19 | res.json(json) |
17 | res.json(json) | 20 | }) |
18 | } | 21 | } |
19 | 22 | ||
20 | // --------------------------------------------------------------------------- | 23 | // --------------------------------------------------------------------------- |
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' | |||
6 | import { | 6 | import { |
7 | authenticate, | 7 | authenticate, |
8 | ensureIsAdmin, | 8 | ensureIsAdmin, |
9 | ensureUserRegistrationEnabled, | 9 | ensureUserRegistrationAllowed, |
10 | usersAddValidator, | 10 | usersAddValidator, |
11 | usersUpdateValidator, | 11 | usersUpdateValidator, |
12 | usersRemoveValidator, | 12 | usersRemoveValidator, |
@@ -48,7 +48,7 @@ usersRouter.post('/', | |||
48 | ) | 48 | ) |
49 | 49 | ||
50 | usersRouter.post('/register', | 50 | usersRouter.post('/register', |
51 | ensureUserRegistrationEnabled, | 51 | ensureUserRegistrationAllowed, |
52 | usersAddValidator, | 52 | usersAddValidator, |
53 | createUser | 53 | createUser |
54 | ) | 54 | ) |
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 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import * as Promise from 'bluebird' | ||
2 | 3 | ||
3 | import { pseudoRandomBytesPromise } from './core-utils' | 4 | import { pseudoRandomBytesPromise } from './core-utils' |
5 | import { CONFIG, database as db } from '../initializers' | ||
4 | import { ResultList } from '../../shared' | 6 | import { ResultList } from '../../shared' |
5 | 7 | ||
6 | function badRequest (req: express.Request, res: express.Response, next: express.NextFunction) { | 8 | function badRequest (req: express.Request, res: express.Response, next: express.NextFunction) { |
@@ -30,10 +32,26 @@ function getFormatedObjects<U, T extends FormatableToJSON> (objects: T[], object | |||
30 | return res | 32 | return res |
31 | } | 33 | } |
32 | 34 | ||
35 | function isSignupAllowed () { | ||
36 | if (CONFIG.SIGNUP.ENABLED === false) { | ||
37 | return Promise.resolve(false) | ||
38 | } | ||
39 | |||
40 | // No limit and signup is enabled | ||
41 | if (CONFIG.SIGNUP.LIMIT === -1) { | ||
42 | return Promise.resolve(true) | ||
43 | } | ||
44 | |||
45 | return db.User.countTotal().then(totalUsers => { | ||
46 | return totalUsers < CONFIG.SIGNUP.LIMIT | ||
47 | }) | ||
48 | } | ||
49 | |||
33 | // --------------------------------------------------------------------------- | 50 | // --------------------------------------------------------------------------- |
34 | 51 | ||
35 | export { | 52 | export { |
36 | badRequest, | 53 | badRequest, |
37 | generateRandomString, | 54 | generateRandomString, |
38 | getFormatedObjects | 55 | getFormatedObjects, |
56 | isSignupAllowed | ||
39 | } | 57 | } |
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 = { | |||
76 | EMAIL: config.get<string>('admin.email') | 76 | EMAIL: config.get<string>('admin.email') |
77 | }, | 77 | }, |
78 | SIGNUP: { | 78 | SIGNUP: { |
79 | ENABLED: config.get<boolean>('signup.enabled') | 79 | ENABLED: config.get<boolean>('signup.enabled'), |
80 | LIMIT: config.get<number>('signup.limit') | ||
80 | }, | 81 | }, |
81 | TRANSCODING: { | 82 | TRANSCODING: { |
82 | ENABLED: config.get<boolean>('transcoding.enabled'), | 83 | ENABLED: config.get<boolean>('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 @@ | |||
1 | import 'express-validator' | ||
2 | import * as express from 'express' | ||
3 | |||
4 | import { CONFIG } from '../initializers' | ||
5 | |||
6 | function ensureUserRegistrationEnabled (req: express.Request, res: express.Response, next: express.NextFunction) { | ||
7 | const registrationEnabled = CONFIG.SIGNUP.ENABLED | ||
8 | |||
9 | if (registrationEnabled === true) { | ||
10 | return next() | ||
11 | } | ||
12 | |||
13 | return res.status(400).send('User registration is not enabled.') | ||
14 | } | ||
15 | |||
16 | // --------------------------------------------------------------------------- | ||
17 | |||
18 | export { | ||
19 | ensureUserRegistrationEnabled | ||
20 | } | ||
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 @@ | |||
1 | export * from './validators' | 1 | export * from './validators' |
2 | export * from './admin' | 2 | export * from './admin' |
3 | export * from './config' | ||
4 | export * from './oauth' | 3 | export * from './oauth' |
5 | export * from './pagination' | 4 | export * from './pagination' |
6 | export * from './pods' | 5 | 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' | |||
5 | 5 | ||
6 | import { database as db } from '../../initializers/database' | 6 | import { database as db } from '../../initializers/database' |
7 | import { checkErrors } from './utils' | 7 | import { checkErrors } from './utils' |
8 | import { logger } from '../../helpers' | 8 | import { isSignupAllowed, logger } from '../../helpers' |
9 | import { VideoInstance } from '../../models' | 9 | import { VideoInstance } from '../../models' |
10 | 10 | ||
11 | function usersAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) { | 11 | function usersAddValidator (req: express.Request, res: express.Response, next: express.NextFunction) { |
@@ -88,11 +88,22 @@ function usersVideoRatingValidator (req: express.Request, res: express.Response, | |||
88 | }) | 88 | }) |
89 | } | 89 | } |
90 | 90 | ||
91 | function ensureUserRegistrationAllowed (req: express.Request, res: express.Response, next: express.NextFunction) { | ||
92 | isSignupAllowed().then(allowed => { | ||
93 | if (allowed === false) { | ||
94 | return res.status(403).send('User registration is not enabled or user limit is reached.') | ||
95 | } | ||
96 | |||
97 | return next() | ||
98 | }) | ||
99 | } | ||
100 | |||
91 | // --------------------------------------------------------------------------- | 101 | // --------------------------------------------------------------------------- |
92 | 102 | ||
93 | export { | 103 | export { |
94 | usersAddValidator, | 104 | usersAddValidator, |
95 | usersRemoveValidator, | 105 | usersRemoveValidator, |
96 | usersUpdateValidator, | 106 | usersUpdateValidator, |
97 | usersVideoRatingValidator | 107 | usersVideoRatingValidator, |
108 | ensureUserRegistrationAllowed | ||
98 | } | 109 | } |
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 () { | |||
513 | password: 'my super password 4' | 513 | password: 'my super password 4' |
514 | } | 514 | } |
515 | 515 | ||
516 | requestsUtils.makePostBodyRequest(serverWithRegistrationDisabled.url, registrationPath, serverWithRegistrationDisabled.accessToken, data, done, 400) | 516 | requestsUtils.makePostBodyRequest(serverWithRegistrationDisabled.url, registrationPath, serverWithRegistrationDisabled.accessToken, data, done, 403) |
517 | }) | ||
518 | }) | ||
519 | |||
520 | describe('When registering multiple users on a server with users limit', function () { | ||
521 | it('Should fail when after 3 registrations', function (done) { | ||
522 | usersUtils.registerUser(server.url, 'user42', 'super password', 403, done) | ||
517 | }) | 523 | }) |
518 | }) | 524 | }) |
519 | 525 | ||
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') | |||
8 | 8 | ||
9 | const serversUtils = require('../utils/servers') | 9 | const serversUtils = require('../utils/servers') |
10 | const configUtils = require('../utils/config') | 10 | const configUtils = require('../utils/config') |
11 | const usersUtils = require('../utils/users') | ||
11 | 12 | ||
12 | describe('Test config', function () { | 13 | describe('Test config', function () { |
13 | let server = null | 14 | let server = null |
@@ -28,18 +29,51 @@ describe('Test config', function () { | |||
28 | ], done) | 29 | ], done) |
29 | }) | 30 | }) |
30 | 31 | ||
31 | it('Should have a correct config', function (done) { | 32 | it('Should have a correct config on a server with registration enabled', function (done) { |
32 | configUtils.getConfig(server.url, function (err, res) { | 33 | configUtils.getConfig(server.url, function (err, res) { |
33 | if (err) throw err | 34 | if (err) throw err |
34 | 35 | ||
35 | const data = res.body | 36 | const data = res.body |
36 | 37 | ||
37 | expect(data.signup.enabled).to.be.truthy | 38 | expect(data.signup.allowed).to.be.truthy |
38 | 39 | ||
39 | done() | 40 | done() |
40 | }) | 41 | }) |
41 | }) | 42 | }) |
42 | 43 | ||
44 | it('Should have a correct config on a server with registration enabled and a users limit', function (done) { | ||
45 | series([ | ||
46 | function (next) { | ||
47 | usersUtils.registerUser(server.url, 'user1', 'super password', done) | ||
48 | }, | ||
49 | |||
50 | function (next) { | ||
51 | usersUtils.registerUser(server.url, 'user2', 'super password', done) | ||
52 | }, | ||
53 | |||
54 | function (next) { | ||
55 | usersUtils.registerUser(server.url, 'user3', 'super password', done) | ||
56 | }, | ||
57 | |||
58 | function (next) { | ||
59 | usersUtils.registerUser(server.url, 'user4', 'super password', done) | ||
60 | } | ||
61 | |||
62 | ], function (err) { | ||
63 | if (err) throw err | ||
64 | |||
65 | configUtils.getConfig(server.url, function (err, res) { | ||
66 | if (err) throw err | ||
67 | |||
68 | const data = res.body | ||
69 | |||
70 | expect(data.signup.allowed).to.be.truthy | ||
71 | |||
72 | done() | ||
73 | }) | ||
74 | }) | ||
75 | }) | ||
76 | |||
43 | after(function (done) { | 77 | after(function (done) { |
44 | process.kill(-server.app.pid) | 78 | process.kill(-server.app.pid) |
45 | 79 | ||
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 @@ | |||
1 | export interface ServerConfig { | 1 | export interface ServerConfig { |
2 | signup: { | 2 | signup: { |
3 | enabled: boolean | 3 | allowed: boolean |
4 | } | 4 | } |
5 | } | 5 | } |