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

fix(middleware): pass version to allow check (#4846)

* fix(middleware): pass version to allow check

* add tests
This commit is contained in:
Marc Bernard 2024-09-25 17:13:31 -04:00 committed by GitHub
parent a3cf3e7921
commit e85069010f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 75 additions and 43 deletions

View file

@ -0,0 +1,5 @@
---
'@verdaccio/middleware': patch
---
fix(middleware): pass version to allow check

View file

@ -1,8 +1,12 @@
import buildDebug from 'debug';
import { API_ERROR, errorUtils } from '@verdaccio/core'; import { API_ERROR, errorUtils } from '@verdaccio/core';
import { getVersionFromTarball } from '@verdaccio/utils'; import { getVersionFromTarball } from '@verdaccio/utils';
import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types'; import { $NextFunctionVer, $RequestExtend, $ResponseExtend } from '../types';
const debug = buildDebug('verdaccio:middleware:allow');
export function allow<T>( export function allow<T>(
auth: T, auth: T,
options = { options = {
@ -21,22 +25,33 @@ export function allow<T>(
: req.params.package; : req.params.package;
const packageVersion = req.params.filename const packageVersion = req.params.filename
? getVersionFromTarball(req.params.filename) ? getVersionFromTarball(req.params.filename)
: req.params.version
? req.params.version
: undefined; : undefined;
const remote = req.remote_user; const remote_user = req.remote_user;
debug(
'check if user %o can %o package %o version %o',
remote_user?.name,
action,
packageName,
packageVersion
);
beforeAll?.( beforeAll?.(
{ action, user: remote?.name }, { action, user: remote_user?.name },
`[middleware/allow][@{action}] allow for @{user}` `[middleware/allow][@{action}] allow for @{user}`
); );
auth['allow_' + action]( auth['allow_' + action](
{ packageName, packageVersion }, { packageName, packageVersion },
remote, remote_user,
function (error, allowed): void { function (error, allowed): void {
req.resume(); req.resume();
if (error) { if (error) {
debug('user is NOT allowed to %o', action);
next(error); next(error);
} else if (allowed) { } else if (allowed) {
debug('user is allowed to %o', action);
afterAll?.( afterAll?.(
{ action, user: remote?.name }, { action, user: remote_user?.name },
`[middleware/allow][@{action}] allowed for @{user}` `[middleware/allow][@{action}] allowed for @{user}`
); );
next(); next();

View file

@ -1,22 +1,16 @@
import request from 'supertest'; import request from 'supertest';
import { HTTP_STATUS } from '@verdaccio/core'; import { HTTP_STATUS } from '@verdaccio/core';
import { logger, setup } from '@verdaccio/logger';
import { allow } from '../src'; import { allow } from '../src';
import { getApp } from './helper'; import { getApp } from './helper';
setup({});
test('should allow request', async () => { test('should allow request', async () => {
const can = allow( const can = allow({
{
allow_publish: (params, remove, cb) => { allow_publish: (params, remove, cb) => {
return cb(null, true); return cb(null, true);
}, },
}, });
logger
);
const app = getApp([]); const app = getApp([]);
// @ts-ignore // @ts-ignore
app.get('/:package', can('publish'), (req, res) => { app.get('/:package', can('publish'), (req, res) => {
@ -27,14 +21,11 @@ test('should allow request', async () => {
}); });
test('should allow scope request', async () => { test('should allow scope request', async () => {
const can = allow( const can = allow({
{
allow_publish: (params, remove, cb) => { allow_publish: (params, remove, cb) => {
return cb(null, true); return cb(null, true);
}, },
}, });
logger
);
const app = getApp([]); const app = getApp([]);
// @ts-ignore // @ts-ignore
app.get('/:package/:scope', can('publish'), (req, res) => { app.get('/:package/:scope', can('publish'), (req, res) => {
@ -45,14 +36,11 @@ test('should allow scope request', async () => {
}); });
test('should allow filename request', async () => { test('should allow filename request', async () => {
const can = allow( const can = allow({
{
allow_publish: (params, remove, cb) => { allow_publish: (params, remove, cb) => {
return cb(null, true); return cb(null, true);
}, },
}, });
logger
);
const app = getApp([]); const app = getApp([]);
// @ts-ignore // @ts-ignore
app.get('/:filename', can('publish'), (req, res) => { app.get('/:filename', can('publish'), (req, res) => {
@ -63,14 +51,11 @@ test('should allow filename request', async () => {
}); });
test('should not allow request', async () => { test('should not allow request', async () => {
const can = allow( const can = allow({
{
allow_publish: (params, remove, cb) => { allow_publish: (params, remove, cb) => {
return cb(null, false); return cb(null, false);
}, },
}, });
logger
);
const app = getApp([]); const app = getApp([]);
// @ts-ignore // @ts-ignore
app.get('/sec', can('publish'), (req, res) => { app.get('/sec', can('publish'), (req, res) => {
@ -81,17 +66,44 @@ test('should not allow request', async () => {
}); });
test('should handle error request', async () => { test('should handle error request', async () => {
const can = allow( const can = allow({
{
allow_publish: (params, remove, cb) => { allow_publish: (params, remove, cb) => {
return cb(Error('foo error')); return cb(Error('foo error'));
}, },
}, });
logger
);
const app = getApp([]); const app = getApp([]);
// @ts-ignore // @ts-ignore
app.get('/err', can('publish')); app.get('/err', can('publish'));
return request(app).get('/err').expect(HTTP_STATUS.INTERNAL_ERROR); return request(app).get('/err').expect(HTTP_STATUS.INTERNAL_ERROR);
}); });
test('should allow request with version', async () => {
const can = allow({
allow_publish: (params, remove, cb) => {
return params.packageVersion === '1.0.0' ? cb(null, true) : cb(null, false);
},
});
const app = getApp([]);
// @ts-ignore
app.get('/:package/:version', can('publish'), (req, res) => {
res.status(HTTP_STATUS.OK).json({});
});
return request(app).get('/pacman/1.0.0').expect(HTTP_STATUS.OK);
});
test('should not allow request with version', async () => {
const can = allow({
allow_publish: (params, remove, cb) => {
return params.packageVersion === '1.0.0' ? cb(null, true) : cb(null, false);
},
});
const app = getApp([]);
// @ts-ignore
app.get('/:package/:version', can('publish'), (req, res) => {
res.status(HTTP_STATUS.OK).json({});
});
return request(app).get('/pacman/2.0.0').expect(HTTP_STATUS.INTERNAL_ERROR);
});