Skip to content

Commit c6be752

Browse files
committed
feat: block tgz
1 parent 4012f58 commit c6be752

File tree

3 files changed

+60
-2
lines changed

3 files changed

+60
-2
lines changed

app/core/service/PackageVersionService.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import { PackageVersionRepository } from '../../repository/PackageVersionReposit
55
import { getScopeAndName } from '../../common/PackageUtil';
66
import { SqlRange } from '../entity/SqlRange';
77
import { BugVersionService } from './BugVersionService';
8-
import type { PackageJSONType } from '../../repository/PackageRepository';
8+
import type { PackageJSONType, PackageRepository } from '../../repository/PackageRepository';
99
import { DistRepository } from '../../repository/DistRepository';
1010
import { BugVersionAdvice } from '../entity/BugVersion';
11+
import { PackageVersionBlockRepository } from '../../repository/PackageVersionBlockRepository';
1112

1213
@SingletonProto({
1314
accessLevel: AccessLevel.PUBLIC,
@@ -16,6 +17,12 @@ export class PackageVersionService {
1617
@Inject()
1718
private packageVersionRepository: PackageVersionRepository;
1819

20+
@Inject()
21+
private packageRepository: PackageRepository;
22+
23+
@Inject()
24+
private packageVersionBlockRepository: PackageVersionBlockRepository;
25+
1926
@Inject()
2027
private readonly bugVersionService: BugVersionService;
2128

@@ -115,4 +122,13 @@ export class PackageVersionService {
115122
}
116123
return version;
117124
}
125+
126+
async findBlockInfo(fullname: string) {
127+
const [scope, name] = getScopeAndName(fullname);
128+
const pkg = await this.packageRepository.findPackage(scope, name);
129+
if (!pkg) {
130+
return null;
131+
}
132+
return await this.packageVersionBlockRepository.findPackageBlock(pkg.packageId);
133+
}
118134
}

app/port/controller/package/DownloadPackageVersionTar.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { PackageManagerService } from '../../../core/service/PackageManagerServi
1919
import { ProxyCacheService } from '../../../core/service/ProxyCacheService';
2020
import { PackageSyncerService } from '../../../core/service/PackageSyncerService';
2121
import { RegistryManagerService } from '../../../core/service/RegistryManagerService';
22+
import { PackageVersionService } from '../../../core/service/PackageVersionService';
2223

2324
@HTTPController()
2425
export class DownloadPackageVersionTarController extends AbstractController {
@@ -31,6 +32,8 @@ export class DownloadPackageVersionTarController extends AbstractController {
3132
@Inject()
3233
private packageSyncerService: PackageSyncerService;
3334
@Inject()
35+
private packageVersionService: PackageVersionService;
36+
@Inject()
3437
private nfsAdapter: NFSAdapter;
3538

3639
// Support OPTIONS Request on tgz download
@@ -55,6 +58,16 @@ export class DownloadPackageVersionTarController extends AbstractController {
5558
const version = this.getAndCheckVersionFromFilename(ctx, fullname, filenameWithVersion);
5659
const storeKey = `/packages/${fullname}/${version}/${filenameWithVersion}.tgz`;
5760
const downloadUrl = await this.nfsAdapter.getDownloadUrl(storeKey);
61+
62+
// block tgz only all versions have been blocked
63+
const blockInfo = await this.packageVersionService.findBlockInfo(fullname);
64+
if (blockInfo?.reason) {
65+
this.setCDNHeaders(ctx);
66+
ctx.logger.info('[PackageController:downloadVersionTar] %s@%s, block for %s',
67+
fullname, version, blockInfo.reason);
68+
throw this.createPackageBlockError(blockInfo.reason, fullname, version);
69+
}
70+
5871
if (this.config.cnpmcore.syncMode === SyncMode.all && downloadUrl) {
5972
// try nfs url first, avoid db query
6073
this.packageManagerService.plusPackageVersionCounter(fullname, version);
@@ -67,7 +80,6 @@ export class DownloadPackageVersionTarController extends AbstractController {
6780
let pkg;
6881
let packageVersion;
6982
try {
70-
pkg = await this.getPackageEntityByFullname(fullname, allowSync);
7183
packageVersion = await this.getPackageVersionEntity(pkg, version, allowSync);
7284
} catch (error) {
7385
if (this.config.cnpmcore.syncMode === SyncMode.proxy) {

test/port/controller/package/DownloadPackageVersionTarController.test.ts

+30
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@ import { app, mock } from 'egg-mock/bootstrap';
44
import { TestUtil } from '../../../../test/TestUtil';
55
import { NFSClientAdapter } from '../../../../app/infra/NFSClientAdapter';
66
import { SyncMode } from '../../../../app/common/constants';
7+
import { PackageManagerService } from '../../../../app/core/service/PackageManagerService';
78

89
describe('test/port/controller/package/DownloadPackageVersionTarController.test.ts', () => {
910
let publisher: any;
1011
let nfsClientAdapter: NFSClientAdapter;
12+
let packageManagerService: PackageManagerService;
1113
beforeEach(async () => {
1214
publisher = await TestUtil.createUser();
1315
nfsClientAdapter = await app.getEggObject(NFSClientAdapter);
16+
packageManagerService = await app.getEggObject(PackageManagerService);
1417
});
1518

1619
const scope = '@cnpm';
@@ -38,6 +41,8 @@ describe('test/port/controller/package/DownloadPackageVersionTarController.test.
3841
assert(res.status === 201);
3942
assert(res.body.ok === true);
4043
assert.match(res.body.rev, /^\d+\-\w{24}$/);
44+
45+
await packageManagerService.unblockPackageByFullname(scopedName);
4146
});
4247

4348
describe('[GET /:fullname/-/:name-:version.tgz] download()', () => {
@@ -56,6 +61,14 @@ describe('test/port/controller/package/DownloadPackageVersionTarController.test.
5661
assert(res.headers.location === `https://cdn.mock.com/packages/${scopedName}/1.0.0/${name}-1.0.0.tgz`);
5762
});
5863

64+
it('should block tgz', async () => {
65+
await packageManagerService.blockPackageByFullname(scopedName, 'test');
66+
const res = await app.httpRequest()
67+
.get(`/${scopedName}/-/testmodule-download-version-tar-1.0.0.tgz`)
68+
.expect(451);
69+
assert.equal(res.body.error, '[UNAVAILABLE_FOR_LEGAL_REASONS] @cnpm/[email protected] was blocked, reason: test');
70+
});
71+
5972
it('should support cors OPTIONS Request', async () => {
6073
mock(nfsClientAdapter, 'url', async (storeKey: string) => {
6174
return `https://cdn.mock.com${storeKey}`;
@@ -337,6 +350,14 @@ describe('test/port/controller/package/DownloadPackageVersionTarController.test.
337350
assert(res.headers.location === `https://cdn.mock.com/packages/${scopedName}/1.0.0/${name}-1.0.0.tgz`);
338351
});
339352

353+
it('should block tgz', async () => {
354+
await packageManagerService.blockPackageByFullname(scopedName, 'test');
355+
const res = await app.httpRequest()
356+
.get(`/${scopedName}/download/${scopedName}-1.0.0.tgz`)
357+
.expect(451);
358+
assert.equal(res.body.error, '[UNAVAILABLE_FOR_LEGAL_REASONS] @cnpm/[email protected] was blocked, reason: test');
359+
});
360+
340361
it('should download a version tar with streaming success', async () => {
341362
mock(nfsClientAdapter, 'url', 'not-function');
342363
const res = await app.httpRequest()
@@ -385,6 +406,15 @@ describe('test/port/controller/package/DownloadPackageVersionTarController.test.
385406
assert(res.headers.location === `https://cdn.mock.com/packages/${scopedName}/1.0.0/${name}-1.0.0.tgz`);
386407
});
387408

409+
it('should block tgz', async () => {
410+
await packageManagerService.blockPackageByFullname(scopedName, 'test');
411+
const res = await app.httpRequest()
412+
.get(`/${scopedName}/-/${scope}/${name}-1.0.0.tgz`)
413+
.expect(451);
414+
assert.equal(res.body.error, '[UNAVAILABLE_FOR_LEGAL_REASONS] @cnpm/[email protected] was blocked, reason: test');
415+
});
416+
417+
388418
it('should download a version tar with streaming success', async () => {
389419
mock(nfsClientAdapter, 'url', 'not-function');
390420
const res = await app.httpRequest()

0 commit comments

Comments
 (0)