0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-12-16 21:56:25 -05:00

basic support for .htpasswd

This commit is contained in:
Alex Kocharin 2014-06-26 20:21:23 +04:00
parent 81486f412f
commit e929e089d0
6 changed files with 93 additions and 2 deletions

View file

@ -1,5 +1,6 @@
var assert = require('assert')
, crypto = require('crypto')
, Path = require('path')
, minimatch = require('minimatch')
, utils = require('./utils')
@ -111,6 +112,15 @@ function Config(config) {
if (this.ignore_latest_tag == null) this.ignore_latest_tag = false
if (this.users_file) {
this.HTPasswd = require('./htpasswd')(
Path.resolve(
Path.dirname(this.self_path),
this.users_file
)
)
}
return this
}
@ -147,8 +157,15 @@ Config.prototype.get_package_setting = function(package, setting) {
}
Config.prototype.authenticate = function(user, password, cb) {
if (this.users[user] == null) return cb(null, false)
return cb(null, crypto.createHash('sha1').update(password).digest('hex') === this.users[user].password)
if (this.users != null) {
if (this.users[user] == null) return cb(null, false)
if (crypto.createHash('sha1').update(password).digest('hex') === this.users[user].password) return cb(null, true)
}
if (!this.HTPasswd) return cb(null, false)
this.HTPasswd.reload(function() {
cb(null, this.HTPasswd.verify(user, password))
}.bind(this))
}
module.exports = Config

View file

@ -7,6 +7,11 @@ users:
# crypto.createHash('sha1').update(pass).digest('hex')
password: __PASSWORD__
users_file: ./htpasswd
# set this to 0 to disable registration
#max_users: 1000
# a list of other known repositories we can talk to
uplinks:
npmjs:

65
lib/htpasswd.js Normal file
View file

@ -0,0 +1,65 @@
var fs = require('fs')
, crypto = require('crypto')
, fs_storage = require('./local-fs')
, UError = require('./error').UserError
try {
// optional, won't be available on windows
var crypt3 = require('crypt3')
} catch(err) {
crypt3 = function() {
return NaN
}
}
function parse_htpasswd(input) {
var result = {}
input.split('\n').forEach(function(line) {
var args = line.split(':', 3)
if (args.length > 1) result[args[0]] = args[1]
})
return result
}
function verify_password(user, passwd, hash) {
if (hash.indexOf('{PLAIN}') === 0) {
return passwd === hash.substr(7)
} else if (hash.indexOf('{SHA}') === 0) {
return crypto.createHash('sha1').update(passwd, 'binary').digest('base64') === hash.substr(5)
} else {
return crypt3(passwd, hash) === hash
}
}
module.exports = function(path) {
var result = {}
var users = {}
var last_time
result.add_user = function(user, passwd, cb) {
// TODO
}
result.verify = function(user, passwd) {
if (!users[user]) return false
return verify_password(user, passwd, users[user])
}
result.reload = function(callback) {
fs.open(path, 'r', function(err, fd) {
if (err) return callback(err)
fs.fstat(fd, function(err, st) {
if (err) return callback(err)
if (last_time === st.mtime) return callback()
var buffer = new Buffer(st.size)
fs.read(fd, buffer, 0, st.size, null, function(err, bytesRead, buffer) {
if (err) return callback(err)
if (bytesRead != st.size) return callback(new Error('st.size != bytesRead'))
users = parse_htpasswd(buffer.toString('utf8'))
callback()
})
})
})
}
return result
}

View file

@ -42,7 +42,9 @@ module.exports.expect_json = function expect_json(req, res, next) {
module.exports.basic_auth = function basic_auth(callback) {
return function(req, res, _next) {
req.pause()
function next(err) {
req.resume()
// uncomment this to reject users with bad auth headers
//return _next.apply(null, arguments)

View file

@ -339,6 +339,7 @@ Storage.prototype.search = function(startkey, options, callback) {
}
function merge_with_local_packages(err, res, body) {
if (err) return callback(err)
var j = 0
self.local.get_recent_packages(startkey, function(err, list) {

View file

@ -31,6 +31,7 @@ dependencies:
optionalDependencies:
fs-ext: '>= 0.3.2'
crypt3: 'sendanor/node-crypt3'
devDependencies:
rimraf: '>= 2.2.5'