add a bunch of tests for htpasswd

This commit is contained in:
Alex Kocharin 2014-07-23 01:45:28 +04:00
parent 490340fbb0
commit 3809d6eb32
10 changed files with 115 additions and 7 deletions

1
.gitignore vendored
View File

@ -5,5 +5,6 @@ sinopia-*.tgz
###
bin/storage*
bin/htpasswd
bin/*.yaml
test-storage*

View File

@ -5,6 +5,7 @@ sinopia-*.tgz
###
bin/storage*
bin/htpasswd
bin/*.yaml
test-storage*

View File

@ -171,7 +171,7 @@ Config.prototype.authenticate = function(user, password, cb) {
Config.prototype.add_user = function(user, password, cb) {
if (this.users && this.users[user]) return cb(new UError({
status: 409,
status: 403,
message: 'this user already exists',
}))

View File

@ -66,12 +66,12 @@ module.exports = function(path) {
function sanity_check() {
if (users[user]) {
return new UError({
status: 409,
status: 403,
message: 'this user already exists',
})
} else if (Object.keys(users).length >= maxusers) {
return new UError({
status: 409,
status: 403,
message: 'maximum amount of users reached',
})
}
@ -135,3 +135,7 @@ module.exports = function(path) {
return result
}
// exports for unit tests
module.exports._parse_htpasswd = parse_htpasswd
module.exports._verify_password = verify_password
module.exports._add_user_to_htpasswd = add_user_to_htpasswd

View File

@ -31,14 +31,14 @@ dependencies:
optionalDependencies:
fs-ext: '>= 0.3.2'
crypt3: 'sendanor/node-crypt3'
crypt3: '*'
devDependencies:
rimraf: '>= 2.2.5'
mocha: '>= 1.17.0'
# linting tools
eslint: '>= 0.6'
eslint: '~ 0.6.0'
# for debugging memory leaks, it'll be require()'d if
# installed, but I don't want it to be installed everytime
@ -56,7 +56,7 @@ keywords:
scripts:
test: mocha ./test/functional ./test/unit
lint: eslint -c ./.eslint.yaml ./lib
prepublish: js-yaml package.yaml > package.json
#prepublish: js-yaml package.yaml > package.json
# we depend on streams2 stuff
# it can be replaced with isaacs/readable-stream, ask if you need to use 0.8

View File

@ -0,0 +1,36 @@
var assert = require('assert')
var Server = require('./lib/server')
module.exports = function() {
var server = new Server('http://localhost:55551/')
describe('adduser', function() {
var user = String(Math.random())
var pass = String(Math.random())
before(function(cb) {
server.auth(user, pass, function(res, body) {
assert.equal(res.statusCode, 201)
assert(body.ok.match(/user .* created/))
cb()
})
})
it('creating new user', function(){})
it('should log in', function(cb) {
server.auth(user, pass, function(res, body) {
assert.equal(res.statusCode, 201)
assert(body.ok.match(/you are authenticated as/))
cb()
})
})
it('should not register more users', function(cb) {
server.auth(String(Math.random()), String(Math.random()), function(res, body) {
assert.equal(res.statusCode, 403)
assert(body.error.match(/maximum amount of users reached/))
cb()
})
})
})
}

View File

@ -4,6 +4,9 @@ users:
test:
password: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
users_file: ./test-storage/htpasswd
max_users: 1
uplinks:
express:
url: http://localhost:55550/

View File

@ -46,6 +46,7 @@ describe('Func', function() {
require('./race')()
require('./racycrash')()
require('./security')()
require('./adduser')()
require('./addtag')()
})

View File

@ -36,7 +36,13 @@ Server.prototype.auth = function(user, pass, cb) {
uri: '/-/user/org.couchdb.user:'+encodeURIComponent(user)+'/-rev/undefined',
method: 'PUT',
json: {
content: "doesn't matter, 'cause sinopia uses info from Authorization header anywayz",
name: user,
password: pass,
email: 'test@example.com',
_id: 'org.couchdb.user:' + user,
type: 'user',
roles: [],
date: new Date(),
}
}, prep(cb))
}

56
test/unit/htpasswd.js Normal file
View File

@ -0,0 +1,56 @@
var assert = require('assert')
, parse_htpasswd = require('../../lib/htpasswd')._parse_htpasswd
, verify_password = require('../../lib/htpasswd')._verify_password
, add_user_to_htpasswd = require('../../lib/htpasswd')._add_user_to_htpasswd
describe('parse_htpasswd', function() {
// TODO
})
describe('verify_password', function() {
it('should verify plain', function() {
assert(verify_password('user', 'pass', '{PLAIN}pass'))
assert(!verify_password('user', 'p', '{PLAIN}pass'))
})
it('should verify sha', function() {
assert(verify_password('user', 'pass', '{SHA}nU4eI71bcnBGqeO0t9tXvY1u5oQ='))
assert(!verify_password('user', 'p', '{SHA}nU4eI71bcnBGqeO0t9tXvY1u5oQ='))
})
it('should verify crypt', function() {
assert(verify_password('user', 'pass', 'ulINxGnqObi36'))
assert(!verify_password('user', 'p', 'ulINxGnqObi36'))
})
it('should verify crypt-sha', function() {
assert(verify_password('user', 'pass', '$6$Qx0eNSKPbxocgA==$ugjO0.z9yOFiaJXJK4ulvGYIxF/KZBV4lGqasArYPqPPT4orZ6NlnIE5KhtiOVs.5EoWxLg1sjp318G8RpI2x1'))
assert(!verify_password('user', 'p', '$6$Qx0eNSKPbxocgA==$ugjO0.z9yOFiaJXJK4ulvGYIxF/KZBV4lGqasArYPqPPT4orZ6NlnIE5KhtiOVs.5EoWxLg1sjp318G8RpI2x1'))
})
})
describe('add_user_to_htpasswd', function() {
it('should add user to empty file', function() {
var res = add_user_to_htpasswd('', 'user', 'passwd')
assert(res.match(/^user:[^:\n]+:autocreated [^\n]+\n$/))
})
it('should append user / newline checks', function() {
var res = add_user_to_htpasswd('testtest', 'user', 'passwd')
assert(res.match(/^testtest\nuser:[^:\n]+:autocreated [^\n]+\n$/))
var res = add_user_to_htpasswd('testtest\n', 'user', 'passwd')
assert(res.match(/^testtest\nuser:[^:\n]+:autocreated [^\n]+\n$/))
var res = add_user_to_htpasswd('testtest\n\n', 'user', 'passwd')
assert(res.match(/^testtest\n\nuser:[^:\n]+:autocreated [^\n]+\n$/))
})
it('should not append invalid users', function() {
assert.throws(function() {
add_user_to_htpasswd('', 'us:er', 'passwd')
}, /non-uri-safe/)
assert.throws(function() {
add_user_to_htpasswd('', 'us\ner', 'passwd')
}, /non-uri-safe/)
assert.throws(function() {
add_user_to_htpasswd('', 'us#er', 'passwd')
}, /non-uri-safe/)
})
})