0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2025-02-17 23:45:29 -05:00

feat: ability to restrict unpublish action to certain users #492

This is a PoC, it needs refactor and unit testing
This commit is contained in:
Juan Picado @jotadeveloper 2019-02-07 22:04:53 +01:00
parent 10370c6eeb
commit ef503257f3
No known key found for this signature in database
GPG key ID: 18AC54485952D158
5 changed files with 37 additions and 2 deletions

View file

@ -44,6 +44,7 @@ packages:
# scoped packages
access: $all
publish: $authenticated
unpublish: $authenticated
proxy: npmjs
'**':
@ -58,6 +59,8 @@ packages:
# (anyone can register by default, remember?)
publish: $authenticated
unpublish: $authenticated
# if package is not available locally, proxy requests to 'npmjs' registry
proxy: npmjs

View file

@ -24,10 +24,10 @@ export default function publish(router: Router, auth: IAuth, storage: IStorageHa
router.put('/:package/:_rev?/:revision?', can('publish'), media(mime.getType('json')), expectJson, publishPackage(storage, config));
// un-publishing an entire package
router.delete('/:package/-rev/*', can('publish'), unPublishPackage(storage));
router.delete('/:package/-rev/*', can('unpublish'), can('publish'), unPublishPackage(storage));
// removing a tarball
router.delete('/:package/-/:filename/-rev/:revision', can('publish'), removeTarball(storage));
router.delete('/:package/-/:filename/-rev/:revision', can('unpublish'), can('publish'), removeTarball(storage));
// uploading package tarball
router.put('/:package/-/:filename/*', can('publish'), media(HEADERS.OCTET_STREAM), uploadPackageTarball(storage));

View file

@ -72,6 +72,7 @@ export function getDefaultPlugins() {
allow_access: allow_action('access'),
allow_publish: allow_action('publish'),
allow_unpublish: allow_action('unpublish'),
};
}

View file

@ -190,6 +190,35 @@ class Auth implements IAuth {
})();
}
allow_unpublish({ packageName, packageVersion }: AuthPluginPackage, user: string, callback: Callback) {
const plugins = this.plugins.slice(0);
const self = this;
// $FlowFixMe
const pkg = Object.assign({ name: packageName, version: packageVersion }, getMatchedPackagesSpec(packageName, this.config.packages));
this.logger.trace({ packageName }, 'allow unpublish for @{packageName}');
(function next() {
const plugin = plugins.shift();
if (_.isFunction(plugin.allow_unpublish) === false) {
return next();
}
plugin.allow_unpublish(user, pkg, (err, ok: boolean) => {
if (err) {
self.logger.trace({ packageName }, 'forbidden unpublish for @{packageName}');
return callback(err);
}
if (ok) {
self.logger.trace({ packageName }, 'allowed unpublish for @{packageName}');
return callback(null, ok);
}
next(); // cb(null, false) causes next plugin to roll
});
})();
}
/**
* Allow user to publish a package.
*/

View file

@ -123,6 +123,8 @@ export function normalisePackageAccess(packages: PackageList): PackageList {
delete normalizedPkgs[pkg].allow_publish;
normalizedPkgs[pkg].proxy = normalizeUserList(packages[pkg].proxy_access, packages[pkg].proxy);
delete normalizedPkgs[pkg].proxy_access;
// $FlowFixMe
normalizedPkgs[pkg].unpublish = normalizeUserList([], packages[pkg].unpublish);
}
}