0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2025-04-01 02:42:23 -05:00

encrypt user+pass instead of tokens for now

This commit is contained in:
Alex Kocharin 2014-11-24 22:46:37 +03:00
parent 691bdb3a92
commit cf71b9dc9e
6 changed files with 113 additions and 54 deletions

View file

@ -11,7 +11,7 @@ function Auth(config) {
var self = Object.create(Auth.prototype)
self.config = config
self.logger = Logger.logger.child({ sub: 'auth' })
self.secret = config.secret || Crypto.pseudoRandomBytes(32)
self.secret = config.secret
var stuff = {
config: config,
@ -152,11 +152,17 @@ Auth.prototype.basic_middleware = function() {
return next( Error[400]('bad authorization header') )
var scheme = parts[0]
var credentials = Buffer(parts[1], 'base64').toString()
var index = credentials.indexOf(':')
if (scheme !== 'Basic' || index < 0)
if (scheme === 'Basic') {
var credentials = Buffer(parts[1], 'base64').toString()
} else if (scheme === 'Bearer') {
var credentials = self.aes_decrypt(Buffer(parts[1], 'base64')).toString('utf8')
if (!credentials) return next()
} else {
return next()
}
var index = credentials.indexOf(':')
if (index < 0) return next()
var user = credentials.slice(0, index)
var pass = credentials.slice(index + 1)
@ -229,15 +235,33 @@ Auth.prototype.cookie_middleware = function() {
var token = req.cookies.get('token')
if (token == null) return next()
try {
var user = self.decode_token(token, 60*60 /* 1 hour */)
/*try {
var user = self.decode_token(token, 60*60)
} catch(err) {
return next()
}
req.remote_user = AuthenticatedUser(user.u, user.g)
req.remote_user.token = token
next()
next()*/
var credentials = self.aes_decrypt(Buffer(token, 'base64')).toString('utf8')
if (!credentials) return next()
var index = credentials.indexOf(':')
if (index < 0) return next()
var user = credentials.slice(0, index)
var pass = credentials.slice(index + 1)
self.authenticate(user, pass, function(err, user) {
if (!err) {
req.remote_user = user
next()
} else {
req.remote_user = AnonymousUser()
next(err)
}
})
}
}
@ -276,6 +300,24 @@ Auth.prototype.decode_token = function(str, expire_time) {
return data
}
Auth.prototype.aes_encrypt = function(buf) {
var c = Crypto.createCipher('aes192', this.secret)
var b1 = c.update(buf)
var b2 = c.final()
return Buffer.concat([ b1, b2 ])
}
Auth.prototype.aes_decrypt = function(buf) {
try {
var c = Crypto.createDecipher('aes192', this.secret)
var b1 = c.update(buf)
var b2 = c.final()
} catch(_) {
return Buffer(0)
}
return Buffer.concat([ b1, b2 ])
}
function AnonymousUser() {
return {
name: undefined,

View file

@ -3,7 +3,7 @@ var Crypto = require('crypto')
var Error = require('http-errors')
var minimatch = require('minimatch')
var Path = require('path')
var LocalList = require('./local-list')
var LocalData = require('./local-data')
var Utils = require('./utils')
// [[a, [b, c]], d] -> [a, b, c, d]
@ -29,12 +29,21 @@ function Config(config) {
assert.equal(typeof(config), 'object', 'CONFIG: it doesn\'t look like a valid config file')
assert(self.storage, 'CONFIG: storage path not defined')
self.localList = LocalList(
self.localList = LocalData(
Path.join(
Path.resolve(Path.dirname(self.self_path), self.storage),
'.sinopia-db.json'
)
)
if (!self.secret) {
self.secret = self.localList.data.secret
if (!self.secret) {
self.secret = Crypto.pseudoRandomBytes(32).toString('hex')
self.localList.data.secret = self.secret
self.localList.sync()
}
}
var users = {all:true, anonymous:true, 'undefined':true, owner:true, none:true}

View file

@ -29,7 +29,7 @@ module.exports = function(config, auth, storage) {
app.param('anything', match(/.*/))
app.use(auth.basic_middleware())
app.use(auth.bearer_middleware())
//app.use(auth.bearer_middleware())
app.use(expressJson5({ strict: false, limit: config.max_body_size || '10mb' }))
app.use(Middleware.anti_loop(config))
@ -113,11 +113,15 @@ module.exports = function(config, auth, storage) {
})
app.put('/-/user/:org_couchdb_user/:_rev?/:revision?', function(req, res, next) {
var token = (req.body.name && req.body.password)
? auth.aes_encrypt(req.body.name + ':' + req.body.password).toString('base64')
: undefined
if (req.remote_user.name != null) {
res.status(201)
return next({
ok: "you are authenticated as '" + req.remote_user.name + "'",
token: auth.issue_token(req.remote_user),
//token: auth.issue_token(req.remote_user),
token: token,
})
} else {
if (typeof(req.body.name) !== 'string' || typeof(req.body.password) !== 'string') {
@ -141,7 +145,8 @@ module.exports = function(config, auth, storage) {
res.status(201)
return next({
ok: "user '" + req.body.name + "' created",
token: auth.issue_token(req.remote_user),
//token: auth.issue_token(req.remote_user),
token: token,
})
})
}

View file

@ -80,7 +80,10 @@ module.exports = function(config, auth, storage) {
auth.authenticate(req.body.user, req.body.pass, function(err, user) {
if (!err) {
req.remote_user = user
res.cookies.set('token', auth.issue_token(req.remote_user))
//res.cookies.set('token', auth.issue_token(req.remote_user))
var str = req.body.user + ':' + req.body.pass
res.cookies.set('token', auth.aes_encrypt(str).toString('base64'))
}
var base = config.url_prefix || req.protocol + '://' + req.get('host')

40
lib/local-data.js Normal file
View file

@ -0,0 +1,40 @@
var fs = require('fs')
module.exports = LocalData
function LocalData(path) {
var self = Object.create(LocalData.prototype)
self.path = path
try {
self.data = JSON.parse(fs.readFileSync(self.path, 'utf8'))
} catch(_) {
self.data = { list: [] }
}
return self
}
LocalData.prototype.add = function(name) {
if (this.data.list.indexOf(name) === -1) {
this.data.list.push(name)
this.sync()
}
}
LocalData.prototype.remove = function(name) {
var i = this.data.list.indexOf(name)
if (i !== -1) {
this.data.list.splice(i, 1)
}
this.sync()
}
LocalData.prototype.get = function() {
return this.data.list
}
LocalData.prototype.sync = function() {
// Uses sync to prevent ugly race condition
fs.writeFileSync(this.path, JSON.stringify(this.data))
}

View file

@ -1,40 +0,0 @@
var fs = require('fs')
module.exports = LocalList
function LocalList(path) {
var self = Object.create(LocalList.prototype)
self.path = path
try {
self.list = JSON.parse(fs.readFileSync(self.path, 'utf8')).list
} catch(_) {
self.list = []
}
return self
}
LocalList.prototype.add = function(name) {
if (this.list.indexOf(name) === -1) {
this.list.push(name)
this.sync()
}
}
LocalList.prototype.remove = function(name) {
var i = this.list.indexOf(name)
if (i !== -1) {
this.list.splice(i, 1)
}
this.sync()
}
LocalList.prototype.get = function() {
return this.list
}
LocalList.prototype.sync = function() {
// Uses sync to prevent ugly race condition
fs.writeFileSync(this.path, JSON.stringify({ list: this.list }))
}