From a425c5e2ffb9628171f0efa9af409b3536f49675 Mon Sep 17 00:00:00 2001 From: Alex Kocharin Date: Sun, 16 Nov 2014 20:44:46 +0300 Subject: [PATCH] add scoped packages draft --- conf/default.yaml | 5 +++++ lib/index-api.js | 6 ++++-- lib/index-web.js | 3 ++- lib/local-storage.js | 2 +- lib/middleware.js | 11 +++++++++++ lib/utils.js | 13 +++++++++++++ test/functional/index.js | 2 +- 7 files changed, 37 insertions(+), 5 deletions(-) diff --git a/conf/default.yaml b/conf/default.yaml index 7b3aa2b56..ecf0767c9 100644 --- a/conf/default.yaml +++ b/conf/default.yaml @@ -22,6 +22,11 @@ uplinks: url: https://registry.npmjs.org/ packages: + '@*/*': + # scoped packages + allow_access: $all + allow_publish: $authenticated + '*': # allow all users (including non-authenticated users) to read and # publish all packages diff --git a/lib/index-api.js b/lib/index-api.js index b3faf01bc..b79392c3b 100644 --- a/lib/index-api.js +++ b/lib/index-api.js @@ -2,12 +2,14 @@ var Cookies = require('cookies') var express = require('express') var expressJson5 = require('express-json5') var Error = require('http-errors') +var Path = require('path') var Middleware = require('./middleware') var Utils = require('./utils') var expect_json = Middleware.expect_json var match = Middleware.match var media = Middleware.media var validate_name = Middleware.validate_name +var validate_pkg = Middleware.validate_package module.exports = function(config, auth, storage) { var app = express.Router() @@ -15,7 +17,7 @@ module.exports = function(config, auth, storage) { // validate all of these params as a package name // this might be too harsh, so ask if it causes trouble - app.param('package', validate_name) + app.param('package', validate_pkg) app.param('filename', validate_name) app.param('tag', validate_name) app.param('version', validate_name) @@ -209,7 +211,7 @@ module.exports = function(config, auth, storage) { // at this point document is either created or existed before var t1 = Object.keys(metadata._attachments)[0] - create_tarball(t1, metadata._attachments[t1], function(err) { + create_tarball(Path.basename(t1), metadata._attachments[t1], function(err) { if (err) return next(err) var t2 = Object.keys(metadata.versions)[0] diff --git a/lib/index-web.js b/lib/index-web.js index c5d8463eb..f3261bd2d 100644 --- a/lib/index-web.js +++ b/lib/index-web.js @@ -9,6 +9,7 @@ var Search = require('./search') var Middleware = require('./middleware') var match = Middleware.match var validate_name = Middleware.validate_name +var validate_pkg = Middleware.validate_package module.exports = function(config, auth, storage) { var app = express.Router() @@ -16,7 +17,7 @@ module.exports = function(config, auth, storage) { // validate all of these params as a package name // this might be too harsh, so ask if it causes trouble - app.param('package', validate_name) + app.param('package', validate_pkg) app.param('filename', validate_name) app.param('version', validate_name) app.param('anything', match(/.*/)) diff --git a/lib/local-storage.js b/lib/local-storage.js index 7002c0f38..d0b673161 100644 --- a/lib/local-storage.js +++ b/lib/local-storage.js @@ -291,8 +291,8 @@ Storage.prototype.change_package = function(name, metadata, revision, callback) } Storage.prototype.remove_tarball = function(name, filename, revision, callback) { - var self = this assert(Utils.validate_name(filename)) + var self = this self.update_package(name, function updater(data, cb) { if (data._attachments[filename]) { diff --git a/lib/middleware.js b/lib/middleware.js index 3ba771452..a80b36192 100644 --- a/lib/middleware.js +++ b/lib/middleware.js @@ -24,6 +24,17 @@ module.exports.validate_name = function validate_name(req, res, next, value, nam } } +module.exports.validate_package = function validate_package(req, res, next, value, name) { + if (value.charAt(0) === '-') { + // special case in couchdb usually + next('route') + } else if (utils.validate_package(value)) { + next() + } else { + next( Error[403]('invalid ' + name) ) + } +} + module.exports.media = function media(expect) { return function(req, res, next) { if (req.headers['content-type'] !== expect) { diff --git a/lib/utils.js b/lib/utils.js index 3de2f3fe5..e6912b0d0 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -3,6 +3,19 @@ var Semver = require('semver') var URL = require('url') var Logger = require('./logger') +module.exports.validate_package = function(name) { + name = name.split('/', 2) + if (name.length === 1) { + // normal package + return module.exports.validate_name(name[0]) + } else { + // scoped package + return name[0][0] === '@' + && module.exports.validate_name(name[0].slice(1)) + && module.exports.validate_name(name[1]) + } +} + // from normalize-package-data/lib/fixer.js module.exports.validate_name = function(name) { if (typeof(name) !== 'string') return false diff --git a/test/functional/index.js b/test/functional/index.js index 5841a43e7..82ea5677f 100644 --- a/test/functional/index.js +++ b/test/functional/index.js @@ -41,7 +41,7 @@ describe('Func', function() { async.map([server, server2], function(server, cb) { server.auth('test', 'test', function(res, body) { assert.equal(res.statusCode, 201) - assert.notEqual(body.ok.indexOf('"test"'), -1) + assert.notEqual(body.ok.indexOf("'test'"), -1) cb() }) }, cb)