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:
parent
81486f412f
commit
e929e089d0
6 changed files with 93 additions and 2 deletions
|
@ -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
|
||||
|
|
|
@ -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
65
lib/htpasswd.js
Normal 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
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -31,6 +31,7 @@ dependencies:
|
|||
|
||||
optionalDependencies:
|
||||
fs-ext: '>= 0.3.2'
|
||||
crypt3: 'sendanor/node-crypt3'
|
||||
|
||||
devDependencies:
|
||||
rimraf: '>= 2.2.5'
|
||||
|
|
Loading…
Reference in a new issue