Switch config management from rc to convict (fix #46)
This commit is contained in:
Родитель
d5f96e7308
Коммит
7c78ac5bf4
|
@ -17,7 +17,7 @@ module.exports = function (grunt) {
|
|||
pattern: 'This Source Code Form is subject to the terms of the Mozilla Public'
|
||||
},
|
||||
src: [
|
||||
'*.js',
|
||||
'{,config/}*.js',
|
||||
'{bans/,bin/,scripts/,test/}*'
|
||||
]
|
||||
},
|
||||
|
@ -37,7 +37,7 @@ module.exports = function (grunt) {
|
|||
reporter: require('jshint-stylish')
|
||||
},
|
||||
app: [
|
||||
'{,bans/,bin/,scripts/,test/}*.js'
|
||||
'{,bans/,bin/,config/,scripts/,test/}*.js'
|
||||
]
|
||||
}
|
||||
})
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var config = require('../config')
|
||||
var config = require('../config').root()
|
||||
|
||||
var LIFETIME = config.recordLifetimeSeconds
|
||||
var BLOCK_INTERVAL_MS = config.blockIntervalSeconds * 1000
|
||||
var RATE_LIMIT_INTERVAL_MS = config.rateLimitIntervalSeconds * 1000
|
||||
var LIFETIME = config.memcache.recordLifetimeSeconds
|
||||
var BLOCK_INTERVAL_MS = config.limits.blockIntervalSeconds * 1000
|
||||
var RATE_LIMIT_INTERVAL_MS = config.limits.rateLimitIntervalSeconds * 1000
|
||||
|
||||
var EmailRecord = require('../email_record')(RATE_LIMIT_INTERVAL_MS, BLOCK_INTERVAL_MS, config.maxEmails)
|
||||
var EmailRecord = require('../email_record')(RATE_LIMIT_INTERVAL_MS, BLOCK_INTERVAL_MS, config.limits.maxEmails)
|
||||
var IpRecord = require('../ip_record')(BLOCK_INTERVAL_MS)
|
||||
|
||||
module.exports = function (mc, log) {
|
||||
|
|
|
@ -4,16 +4,16 @@
|
|||
|
||||
var Memcached = require('memcached')
|
||||
var restify = require('restify')
|
||||
var config = require('../config')
|
||||
var log = require('../log')(config.logLevel, 'customs-server')
|
||||
var config = require('../config').root()
|
||||
var log = require('../log')(config.log.level, 'customs-server')
|
||||
var packageJson = require('../package.json')
|
||||
|
||||
var LIFETIME = config.recordLifetimeSeconds
|
||||
var BLOCK_INTERVAL_MS = config.blockIntervalSeconds * 1000
|
||||
var RATE_LIMIT_INTERVAL_MS = config.rateLimitIntervalSeconds * 1000
|
||||
var LIFETIME = config.memcache.recordLifetimeSeconds
|
||||
var BLOCK_INTERVAL_MS = config.limits.blockIntervalSeconds * 1000
|
||||
var RATE_LIMIT_INTERVAL_MS = config.limits.rateLimitIntervalSeconds * 1000
|
||||
|
||||
var IpEmailRecord = require('../ip_email_record')(RATE_LIMIT_INTERVAL_MS, config.maxBadLogins)
|
||||
var EmailRecord = require('../email_record')(RATE_LIMIT_INTERVAL_MS, BLOCK_INTERVAL_MS, config.maxEmails)
|
||||
var IpEmailRecord = require('../ip_email_record')(RATE_LIMIT_INTERVAL_MS, config.limits.maxBadLogins)
|
||||
var EmailRecord = require('../email_record')(RATE_LIMIT_INTERVAL_MS, BLOCK_INTERVAL_MS, config.limits.maxEmails)
|
||||
var IpRecord = require('../ip_record')(BLOCK_INTERVAL_MS)
|
||||
|
||||
var P = require('bluebird')
|
||||
|
@ -28,7 +28,7 @@ if (process.env.ASS_CODE_COVERAGE) {
|
|||
}
|
||||
|
||||
var mc = new Memcached(
|
||||
config.memcached,
|
||||
config.memcache.host + ':' + config.memcache.port,
|
||||
{
|
||||
timeout: 500,
|
||||
retries: 1,
|
||||
|
@ -264,8 +264,9 @@ api.get(
|
|||
)
|
||||
|
||||
api.listen(
|
||||
config.port,
|
||||
config.listen.port,
|
||||
config.listen.host,
|
||||
function () {
|
||||
log.info({ op: 'listening', port: config.port })
|
||||
log.info({ op: 'listening', host: config.listen.host, port: config.listen.port })
|
||||
}
|
||||
)
|
||||
|
|
21
config.js
21
config.js
|
@ -1,21 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
module.exports = require('rc')(
|
||||
'fxa_customs',
|
||||
{
|
||||
logLevel: 'trace',
|
||||
port: 7000,
|
||||
memcached: '127.0.0.1:11211',
|
||||
recordLifetimeSeconds: 900, // memcache record expiry
|
||||
blockIntervalSeconds: 60 * 60 * 24, // duration of a manual ban
|
||||
rateLimitIntervalSeconds: 60 * 15, // duration of automatic throttling
|
||||
maxEmails: 3, // number of emails sent within rateLimitIntervalSeconds before throttling
|
||||
maxBadLogins: 2, // number failed login attempts within rateLimitIntervalSeconds before throttling
|
||||
bans: {
|
||||
region: '',
|
||||
queueUrl: ''
|
||||
}
|
||||
}
|
||||
)
|
|
@ -0,0 +1,107 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
module.exports = function (fs, path, url, convict) {
|
||||
|
||||
var conf = convict({
|
||||
env: {
|
||||
doc: 'The current node.js environment',
|
||||
default: 'prod',
|
||||
format: [ 'dev', 'test', 'stage', 'prod' ],
|
||||
env: 'NODE_ENV'
|
||||
},
|
||||
log: {
|
||||
level: {
|
||||
default: 'trace',
|
||||
env: 'LOG_LEVEL'
|
||||
}
|
||||
},
|
||||
publicUrl: {
|
||||
format: 'url',
|
||||
// the real url is set by awsbox
|
||||
default: 'http://127.0.0.1:7000',
|
||||
env: 'PUBLIC_URL'
|
||||
},
|
||||
listen: {
|
||||
host: {
|
||||
doc: 'The ip address the server should bind',
|
||||
default: '127.0.0.1',
|
||||
format: 'ipaddress',
|
||||
env: 'IP_ADDRESS'
|
||||
},
|
||||
port: {
|
||||
doc: 'The port the server should bind',
|
||||
default: 7000,
|
||||
format: 'port',
|
||||
env: 'PORT'
|
||||
}
|
||||
},
|
||||
limits: {
|
||||
blockIntervalSeconds: {
|
||||
doc: 'Duration of a manual ban',
|
||||
default: 60 * 60 * 24,
|
||||
format: 'nat'
|
||||
},
|
||||
rateLimitIntervalSeconds: {
|
||||
doc: 'Duration of automatic throttling',
|
||||
default: 60 * 15,
|
||||
format: 'nat'
|
||||
},
|
||||
maxEmails: {
|
||||
doc: 'Number of emails sent within rateLimitIntervalSeconds before throttling',
|
||||
default: 3,
|
||||
format: 'nat'
|
||||
},
|
||||
maxBadLogins: {
|
||||
doc: 'Number failed login attempts within rateLimitIntervalSeconds before throttling',
|
||||
default: 2,
|
||||
format: 'nat'
|
||||
}
|
||||
},
|
||||
memcache: {
|
||||
host: {
|
||||
doc: 'Hostname / IP of the memcache server',
|
||||
default: '127.0.0.1',
|
||||
env: 'MEMCACHE_HOST'
|
||||
},
|
||||
port: {
|
||||
doc: 'Port of the memcache server',
|
||||
default: '11211',
|
||||
format: 'port',
|
||||
env: 'MEMCACHE_PORT'
|
||||
},
|
||||
recordLifetimeSeconds: {
|
||||
doc: 'Memcache record expiry',
|
||||
default: 900,
|
||||
format: 'nat'
|
||||
}
|
||||
},
|
||||
bans: {
|
||||
region: {
|
||||
doc: 'The region where the queues live, most likely the same region we are sending email e.g. us-east-1, us-west-2, ap-southeast-2',
|
||||
format: String,
|
||||
default: '',
|
||||
env: 'BANS_REGION'
|
||||
},
|
||||
queueUrl: {
|
||||
doc: 'The bounce queue URL to use (should include https://sqs.<region>.amazonaws.com/<account-id>/<queue-name>)',
|
||||
format: String,
|
||||
default: '',
|
||||
env: 'BANS_QUEUE_URL'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// handle configuration files. you can specify a CSV list of configuration
|
||||
// files to process, which will be overlayed in order, in the CONFIG_FILES
|
||||
// environment variable. By default, the ./config/<env>.json file is loaded.
|
||||
|
||||
var envConfig = path.join(__dirname, conf.get('env') + '.json')
|
||||
var files = (envConfig + ',' + process.env.CONFIG_FILES)
|
||||
.split(',').filter(fs.existsSync)
|
||||
conf.loadFile(files)
|
||||
conf.validate()
|
||||
|
||||
return conf
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var fs = require('fs')
|
||||
var path = require('path')
|
||||
var url = require('url')
|
||||
var convict = require('convict')
|
||||
|
||||
module.exports = require('./config')(fs, path, url, convict)
|
|
@ -19,8 +19,8 @@
|
|||
"aws-sdk": "2.0.0-rc.20",
|
||||
"bluebird": "1.2.2",
|
||||
"bunyan": "0.23.1",
|
||||
"convict": "0.4.2",
|
||||
"memcached": "0.2.8",
|
||||
"rc": "0.3.4",
|
||||
"restify": "2.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -12,7 +12,9 @@ var log = {
|
|||
}
|
||||
|
||||
var config = {
|
||||
blockIntervalSeconds: 1
|
||||
limits: {
|
||||
blockIntervalSeconds: 1
|
||||
}
|
||||
}
|
||||
|
||||
var TEST_IP = '192.0.2.1'
|
||||
|
@ -65,7 +67,7 @@ test(
|
|||
}
|
||||
)
|
||||
},
|
||||
config.blockIntervalSeconds * 1000
|
||||
config.limits.blockIntervalSeconds * 1000
|
||||
)
|
||||
}
|
||||
)
|
||||
|
@ -105,7 +107,7 @@ test(
|
|||
}
|
||||
)
|
||||
},
|
||||
config.blockIntervalSeconds * 1000
|
||||
config.limits.blockIntervalSeconds * 1000
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -5,15 +5,20 @@
|
|||
var Memcached = require('memcached')
|
||||
|
||||
var config = {
|
||||
memcached: '127.0.0.1:11211',
|
||||
blockIntervalSeconds: 1,
|
||||
rateLimitIntervalSeconds: 1,
|
||||
maxEmails: 3,
|
||||
maxBadLogins: 2
|
||||
memcache: {
|
||||
host: '127.0.0.1',
|
||||
port: '11211'
|
||||
},
|
||||
limits: {
|
||||
blockIntervalSeconds: 1,
|
||||
rateLimitIntervalSeconds: 1,
|
||||
maxEmails: 3,
|
||||
maxBadLogins: 2
|
||||
}
|
||||
}
|
||||
|
||||
var mc = new Memcached(
|
||||
config.memcached,
|
||||
config.memcache.host + ':' + config.memcache.port,
|
||||
{
|
||||
timeout: 500,
|
||||
retries: 1,
|
||||
|
@ -29,9 +34,9 @@ module.exports.mc = mc
|
|||
var TEST_EMAIL = 'test@example.com'
|
||||
var TEST_IP = '192.0.2.1'
|
||||
|
||||
var EmailRecord = require('../email_record')(config.rateLimitIntervalSeconds * 1000, config.blockIntervalSeconds * 1000, config.maxEmails)
|
||||
var IpEmailRecord = require('../ip_email_record')(config.rateLimitIntervalSeconds * 1000, config.maxBadLogins)
|
||||
var IpRecord = require('../ip_record')(config.blockIntervalSeconds * 1000)
|
||||
var EmailRecord = require('../email_record')(config.limits.rateLimitIntervalSeconds * 1000, config.limits.blockIntervalSeconds * 1000, config.limits.maxEmails)
|
||||
var IpEmailRecord = require('../ip_email_record')(config.limits.rateLimitIntervalSeconds * 1000, config.limits.maxBadLogins)
|
||||
var IpRecord = require('../ip_record')(config.limits.blockIntervalSeconds * 1000)
|
||||
|
||||
function blockedEmailCheck(cb) {
|
||||
setTimeout( // give memcache time to flush the writes
|
||||
|
|
|
@ -10,7 +10,9 @@ var TEST_EMAIL = 'test@example.com'
|
|||
var TEST_IP = '192.0.2.1'
|
||||
|
||||
var config = {
|
||||
port: 7000
|
||||
listen: {
|
||||
port: 7000
|
||||
}
|
||||
}
|
||||
var testServer = new TestServer(config)
|
||||
|
||||
|
@ -38,7 +40,7 @@ test(
|
|||
)
|
||||
|
||||
var client = restify.createJsonClient({
|
||||
url: 'http://127.0.0.1:' + config.port
|
||||
url: 'http://127.0.0.1:' + config.listen.port
|
||||
});
|
||||
|
||||
test(
|
||||
|
|
|
@ -10,7 +10,9 @@ var TEST_EMAIL = 'test@example.com'
|
|||
var TEST_IP = '192.0.2.1'
|
||||
|
||||
var config = {
|
||||
port: 7000
|
||||
listen: {
|
||||
port: 7000
|
||||
}
|
||||
}
|
||||
var testServer = new TestServer(config)
|
||||
|
||||
|
@ -38,7 +40,7 @@ test(
|
|||
)
|
||||
|
||||
var client = restify.createJsonClient({
|
||||
url: 'http://127.0.0.1:' + config.port
|
||||
url: 'http://127.0.0.1:' + config.listen.port
|
||||
});
|
||||
|
||||
test(
|
||||
|
|
|
@ -9,7 +9,9 @@ var TEST_EMAIL = 'test@example.com'
|
|||
var TEST_IP = '192.0.2.1'
|
||||
|
||||
var config = {
|
||||
port: 7000
|
||||
listen: {
|
||||
port: 7000
|
||||
}
|
||||
}
|
||||
var testServer = new TestServer(config)
|
||||
|
||||
|
@ -25,7 +27,7 @@ test(
|
|||
)
|
||||
|
||||
var client = restify.createJsonClient({
|
||||
url: 'http://127.0.0.1:' + config.port
|
||||
url: 'http://127.0.0.1:' + config.listen.port
|
||||
});
|
||||
|
||||
['accountCreate', 'accountLogin', 'passwordChange'].forEach(function (action) {
|
||||
|
|
|
@ -9,7 +9,9 @@ var TEST_EMAIL = 'test@example.com'
|
|||
var TEST_IP = '192.0.2.1'
|
||||
|
||||
var config = {
|
||||
port: 7000
|
||||
listen: {
|
||||
port: 7000
|
||||
}
|
||||
}
|
||||
var testServer = new TestServer(config)
|
||||
|
||||
|
@ -25,7 +27,7 @@ test(
|
|||
)
|
||||
|
||||
var client = restify.createJsonClient({
|
||||
url: 'http://127.0.0.1:' + config.port
|
||||
url: 'http://127.0.0.1:' + config.listen.port
|
||||
});
|
||||
|
||||
test(
|
||||
|
|
|
@ -10,7 +10,9 @@ var TEST_EMAIL = 'test@example.com'
|
|||
var TEST_IP = '192.0.2.1'
|
||||
|
||||
var config = {
|
||||
port: 7000
|
||||
listen: {
|
||||
port: 7000
|
||||
}
|
||||
}
|
||||
|
||||
var testServer = new TestServer(config)
|
||||
|
@ -39,7 +41,7 @@ test(
|
|||
)
|
||||
|
||||
var client = restify.createJsonClient({
|
||||
url: 'http://127.0.0.1:' + config.port
|
||||
url: 'http://127.0.0.1:' + config.listen.port
|
||||
});
|
||||
|
||||
test(
|
||||
|
|
|
@ -10,8 +10,9 @@ var TEST_EMAIL = 'test@example.com'
|
|||
var TEST_IP = '192.0.2.1'
|
||||
|
||||
var config = {
|
||||
port: 7000,
|
||||
rateLimitIntervalSeconds: 1
|
||||
listen: {
|
||||
port: 7000
|
||||
}
|
||||
}
|
||||
|
||||
var testServer = new TestServer(config)
|
||||
|
@ -40,7 +41,7 @@ test(
|
|||
)
|
||||
|
||||
var client = restify.createJsonClient({
|
||||
url: 'http://127.0.0.1:' + config.port
|
||||
url: 'http://127.0.0.1:' + config.listen.port
|
||||
});
|
||||
|
||||
test(
|
||||
|
|
|
@ -8,7 +8,9 @@ var TestServer = require('../test_server')
|
|||
var TEST_EMAIL = 'test@example.com'
|
||||
|
||||
var config = {
|
||||
port: 7000
|
||||
listen: {
|
||||
port: 7000
|
||||
}
|
||||
}
|
||||
var testServer = new TestServer(config)
|
||||
|
||||
|
@ -24,7 +26,7 @@ test(
|
|||
)
|
||||
|
||||
var client = restify.createJsonClient({
|
||||
url: 'http://127.0.0.1:' + config.port
|
||||
url: 'http://127.0.0.1:' + config.listen.port
|
||||
});
|
||||
|
||||
test(
|
||||
|
|
|
@ -7,7 +7,9 @@ var TestServer = require('../test_server')
|
|||
var packageJson = require('../../package.json')
|
||||
|
||||
var config = {
|
||||
port: 7000
|
||||
listen: {
|
||||
port: 7000
|
||||
}
|
||||
}
|
||||
var testServer = new TestServer(config)
|
||||
|
||||
|
@ -23,7 +25,7 @@ test(
|
|||
)
|
||||
|
||||
var client = restify.createJsonClient({
|
||||
url: 'http://127.0.0.1:' + config.port
|
||||
url: 'http://127.0.0.1:' + config.listen.port
|
||||
});
|
||||
|
||||
test(
|
||||
|
|
|
@ -10,8 +10,12 @@ var TEST_EMAIL = 'test@example.com'
|
|||
var TEST_IP = '192.0.2.1'
|
||||
|
||||
var config = {
|
||||
port: 7000,
|
||||
rateLimitIntervalSeconds: 1
|
||||
listen: {
|
||||
port: 7000
|
||||
},
|
||||
limits: {
|
||||
rateLimitIntervalSeconds: 1
|
||||
}
|
||||
}
|
||||
|
||||
var testServer = new TestServer(config)
|
||||
|
@ -40,7 +44,7 @@ test(
|
|||
)
|
||||
|
||||
var client = restify.createJsonClient({
|
||||
url: 'http://127.0.0.1:' + config.port
|
||||
url: 'http://127.0.0.1:' + config.listen.port
|
||||
});
|
||||
|
||||
test(
|
||||
|
@ -85,7 +89,7 @@ test(
|
|||
}
|
||||
)
|
||||
},
|
||||
config.rateLimitIntervalSeconds * 1000
|
||||
config.limits.rateLimitIntervalSeconds * 1000
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -10,8 +10,12 @@ var TEST_EMAIL = 'test@example.com'
|
|||
var TEST_IP = '192.0.2.1'
|
||||
|
||||
var config = {
|
||||
port: 7000,
|
||||
rateLimitIntervalSeconds: 1
|
||||
listen: {
|
||||
port: 7000
|
||||
},
|
||||
limits: {
|
||||
rateLimitIntervalSeconds: 1
|
||||
}
|
||||
}
|
||||
|
||||
var testServer = new TestServer(config)
|
||||
|
@ -40,7 +44,7 @@ test(
|
|||
)
|
||||
|
||||
var client = restify.createJsonClient({
|
||||
url: 'http://127.0.0.1:' + config.port
|
||||
url: 'http://127.0.0.1:' + config.listen.port
|
||||
});
|
||||
|
||||
test(
|
||||
|
@ -95,7 +99,7 @@ test(
|
|||
}
|
||||
)
|
||||
},
|
||||
config.rateLimitIntervalSeconds * 1000
|
||||
config.limits.rateLimitIntervalSeconds * 1000
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -6,7 +6,7 @@ var cp = require('child_process')
|
|||
var request = require('request')
|
||||
|
||||
function TestServer(config) {
|
||||
this.url = 'http://127.0.0.1:' + config.port
|
||||
this.url = 'http://127.0.0.1:' + config.listen.port
|
||||
this.server = null
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче