diff --git a/lib/permissions.js b/lib/permissions.js index 545ef90..eca3e0d 100644 --- a/lib/permissions.js +++ b/lib/permissions.js @@ -7,6 +7,7 @@ const StreamZip = require('node-stream-zip'); const util = require('util'); const xml2js = require('xml2js'); const config = require('./config.js'); +const wcmatch = require('wildcard-match'); module.exports = { fetch: () => { @@ -27,7 +28,10 @@ module.exports = { zip.on('entry', async function (entry) { entries.push(entry.name); - let ok = !!applicable.find(file => entry.name.startsWith(file)); + let ok = !!applicable.find(file => { + const isMatch = wcmatch(file, { separator: '|' }) + return isMatch(entry.name) || entry.name.startsWith(file); + }); if (!ok) { this.emit('error', new Error(util.format('No permissions for %s', entry.name))); return @@ -56,7 +60,7 @@ module.exports = { log.info(util.format('Parsed %s with url=%s tag=%s GAV=%s:%s:%s', entry.name, url, tag, groupId, artifactId, version)); const expectedPath = groupId.replace(/[.]/g, '/') + '/' + artifactId + '/' + version + '/' + artifactId + '-' + version + '.pom'; if (tag !== hash) { - this.emit('error', new Error('Wrong commit hash in /project/scm/tag')); + this.emit('error', new Error(`Wrong commit hash in /project/scm/tag, expected ${tag}, got ${hash}`)); return } else if (!url.match('^https?://github[.]com/.+$')) { this.emit('error', new Error('Wrong URL in /project/scm/url')); diff --git a/package-lock.json b/package-lock.json index 2dd8487..e7955e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "incrementals-publisher", - "version": "1.3.0", + "version": "1.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1439,9 +1439,9 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "ipaddr.js": { "version": "1.9.1", @@ -1645,9 +1645,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "log-symbols": { @@ -1855,9 +1855,9 @@ "integrity": "sha512-sSHCgWfJ+Lui/u+0msF3oyCgvdkhxDbkCS6Q8uiJquzOimkJBvX6hl5aSSA7DR1XbMpdM8r7phjcF63sF4rkKg==" }, "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, "node-pre-gyp": { "version": "0.15.0", @@ -2644,6 +2644,11 @@ } } }, + "wildcard-match": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wildcard-match/-/wildcard-match-5.1.0.tgz", + "integrity": "sha512-Q02fSwOl4xPEyLLMs3TiAOBD735ELrdiczcCnvYAn5VRDAycmzYzc69BmWI1MGONfngCSq+5mgIaYMoGfICqQg==" + }, "winston": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", @@ -2772,9 +2777,9 @@ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, "yallist": { diff --git a/package.json b/package.json index 49a118f..4b43c45 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "incrementals-publisher", - "version": "1.3.0", + "version": "1.4.0", "description": "", "private": true, "main": "index.js", @@ -33,8 +33,9 @@ "express-async-wrap": "^1.0.0", "express-winston": "^4.0.5", "helmet": "^4.1.0", - "node-fetch": "^2.6.0", + "node-fetch": "^2.6.1", "node-stream-zip": "^1.11.3", + "wildcard-match": "^5.1.0", "winston": "^3.3.3", "xml2js": "^0.4.23" } diff --git a/test/fixtures-good-archive.zip b/test/fixtures-good-archive.zip index 2553345..3e0161f 100644 Binary files a/test/fixtures-good-archive.zip and b/test/fixtures-good-archive.zip differ diff --git a/test/fixtures-permissions-missing-path.json b/test/fixtures-permissions-missing-path.json new file mode 100644 index 0000000..314205f --- /dev/null +++ b/test/fixtures-permissions-missing-path.json @@ -0,0 +1,5 @@ +{ + "jenkinsci/bom": [ + "io/jenkins/tools/invalid-path" + ] +} diff --git a/test/fixtures-permissions-wildcard.json b/test/fixtures-permissions-wildcard.json new file mode 100644 index 0000000..037ea79 --- /dev/null +++ b/test/fixtures-permissions-wildcard.json @@ -0,0 +1,5 @@ +{ + "jenkinsci/bom": [ + "io/jenkins/tools/bom/bom-*" + ] +} diff --git a/test/fixtures-permissions.json b/test/fixtures-permissions.json index 29b4821..fde8396 100644 --- a/test/fixtures-permissions.json +++ b/test/fixtures-permissions.json @@ -555,6 +555,11 @@ ], "jenkinsci/bom": [ "io/jenkins/tools/bom/bom", + "io/jenkins/tools/bom/bom-2.222.x", + "io/jenkins/tools/bom/bom-2.235.x", + "io/jenkins/tools/bom/bom-2.249.x", + "io/jenkins/tools/bom/bom-2.263.x", + "io/jenkins/tools/bom/bom-2.277.x", "io/jenkins/tools/bom/parent" ], "jenkinsci/boot-clj-plugin": [ diff --git a/test/index-test.js b/test/index-test.js index 062db8b..e6c82d3 100644 --- a/test/index-test.js +++ b/test/index-test.js @@ -7,7 +7,7 @@ const {IncrementalsPlugin} = require('../IncrementalsPlugin.js'); const permissions = require('../lib/permissions'); const urlResults = { - 'https://repo.jenkins-ci.org/incrementals/io/jenkins/tools/bom/bom/2.176.1-rc63.55219da23b98/bom-2.176.1-rc63.55219da23b98.pom': { + 'https://repo.jenkins-ci.org/incrementals/io/jenkins/tools/bom/bom-2.222.x/29-rc793.5055257e4d28/bom-2.222.x-29-rc793.5055257e4d28.pom': { status: 404 }, 'https://ci.jenkins.io/job/Tools/job/bom/job/PR-22/5/api/json?tree=actions[revision[hash,pullHash]]': { @@ -18,7 +18,7 @@ const urlResults = { "_class": "jenkins.scm.api.SCMRevisionAction", "revision": { "_class": "org.jenkinsci.plugins.github_branch_source.PullRequestSCMRevision", - "pullHash": "55219da23b98739fa6b793b21b91555b36162856" + "pullHash": "5055257e4d28adea76fc34fdde4e025347405bae" } }] } @@ -34,7 +34,7 @@ const urlResults = { status: 200, results: () => require('./fixtures-permissions.json') }, - 'https://fake-repo.jenkins-ci.org/incrementals/io/jenkins/tools/bom/bom/2.176.1-rc63.55219da23b98/bom-2.176.1-rc63.55219da23b98.pom': { + 'https://fake-repo.jenkins-ci.org/incrementals/io/jenkins/tools/bom/bom-2.222.x/29-rc793.5055257e4d28/bom-2.222.x-29-rc793.5055257e4d28.pom': { status: 404, results: () => 'Not found' } @@ -147,7 +147,7 @@ describe('Handling incremental publisher webhook events', function() { it('should output an error', async function() { data.body.build_url = 'https://ci.jenkins.io/job/Tools/job/bom/job/PR-22/5/'; await run(); - assert.equal(ctx.res.body, 'Invalid archive retrieved from Jenkins, perhaps the plugin is not properly incrementalized?\nError: This is my error from https://ci.jenkins.io/job/Tools/job/bom/job/PR-22/5/artifact/**/*55219da23b98*/*55219da23b98*/*zip*/archive.zip'); + assert.equal(ctx.res.body, 'Invalid archive retrieved from Jenkins, perhaps the plugin is not properly incrementalized?\nError: This is my error from https://ci.jenkins.io/job/Tools/job/bom/job/PR-22/5/artifact/**/*5055257e4d28*/*5055257e4d28*/*zip*/archive.zip'); assert.equal(ctx.res.status, 400); }); }); diff --git a/test/permissions-test.js b/test/permissions-test.js index c676f12..e6b3721 100644 --- a/test/permissions-test.js +++ b/test/permissions-test.js @@ -33,13 +33,43 @@ describe('The Permissions helpers', function() { } ) }) + it('Fails with no permissions error', async function() { + const folderMetadataParsed = { + owner: 'jenkinsci', + repo: 'bom' + } + const buildMetadataParsed = { + hash: '5055257e4d28adea76fc34fdde4e025347405bae' + } + + const repoPath = path.join(folderMetadataParsed.owner, folderMetadataParsed.repo); + const entries = []; + let perms = { + status: 200, + json: () => require('./fixtures-permissions-missing-path.json') + } + assert.rejects( + () => Permissions.verify( + { info: () => true }, + repoPath, + path.resolve('./test/fixtures-good-archive.zip'), + entries, + perms, + buildMetadataParsed.hash + ), + { + name: 'Error', + message: 'ZIP error: Error: No permissions for io/jenkins/tools/bom/bom-2.222.x/29-rc793.5055257e4d28/bom-2.222.x-29-rc793.5055257e4d28.pom' + } + ) + }) it('Succeeds with good pom', async function() { const folderMetadataParsed = { owner: 'jenkinsci', repo: 'bom' } const buildMetadataParsed = { - hash: '55219da23b98739fa6b793b21b91555b36162856' + hash: '5055257e4d28adea76fc34fdde4e025347405bae' } const repoPath = path.join(folderMetadataParsed.owner, folderMetadataParsed.repo); @@ -58,4 +88,29 @@ describe('The Permissions helpers', function() { ); assert.equal(response, true) }) + it('Succeeds with wildcard path', async function() { + const folderMetadataParsed = { + owner: 'jenkinsci', + repo: 'bom' + } + const buildMetadataParsed = { + hash: '5055257e4d28adea76fc34fdde4e025347405bae' + } + + const repoPath = path.join(folderMetadataParsed.owner, folderMetadataParsed.repo); + const entries = []; + let perms = { + status: 200, + json: () => require('./fixtures-permissions-wildcard.json') + }; + const response = await Permissions.verify( + { info: () => true }, + repoPath, + path.resolve('./test/fixtures-good-archive.zip'), + entries, + perms, + buildMetadataParsed.hash + ); + assert.equal(response, true) + }) });