Skip to content

Commit

Permalink
Merge pull request #761 from actions/juxtin/fix-allow-dependencies-li…
Browse files Browse the repository at this point in the history
…censes

Fix package-url parsing for allow-dependencies-licenses
  • Loading branch information
juxtin authored Apr 30, 2024
2 parents e58c696 + 49fbbe0 commit f3dac32
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 44 deletions.
24 changes: 24 additions & 0 deletions __tests__/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,30 @@ test('it raises an error if an empty allow list is specified', async () => {
)
})

test('it successfully parses allow-dependencies-licenses', async () => {
setInput(
'allow-dependencies-licenses',
'pkg:npm/@test/package@1.2.3,pkg:npm/example'
)
const config = await readConfig()
expect(config.allow_dependencies_licenses).toEqual([
'pkg:npm/@test/package@1.2.3',
'pkg:npm/example'
])
})

test('it raises an error when an invalid package-url is used for allow-dependencies-licenses', async () => {
setInput('allow-dependencies-licenses', 'not-a-purl')
await expect(readConfig()).rejects.toThrow(`Error parsing package-url`)
})

test('it raises an error when a nameless package-url is used for allow-dependencies-licenses', async () => {
setInput('allow-dependencies-licenses', 'pkg:npm/@namespace/')
await expect(readConfig()).rejects.toThrow(
`Error parsing package-url: name is required`
)
})

test('it raises an error when an invalid package-url is used for deny-packages', async () => {
setInput('deny-packages', 'not-a-purl')

Expand Down
1 change: 1 addition & 0 deletions __tests__/test-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export function clearInputs(): void {
'FAIL-ON-SEVERITY',
'FAIL-ON-SCOPES',
'ALLOW-LICENSES',
'ALLOW-DEPENDENCIES-LICENSES',
'DENY-LICENSES',
'ALLOW-GHSAS',
'LICENSE-CHECK',
Expand Down
51 changes: 32 additions & 19 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

23 changes: 0 additions & 23 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import * as core from '@actions/core'
import * as z from 'zod'
import {ConfigurationOptions, ConfigurationOptionsSchema} from './schemas'
import {isSPDXValid, octokitClient} from './utils'
import {parsePURL} from './purl'

type ConfigurationOptionsPartial = Partial<ConfigurationOptions>

Expand Down Expand Up @@ -53,7 +52,6 @@ function readInlineConfig(): ConfigurationOptionsPartial {
'warn-on-openssf-scorecard-level'
)

validatePURL(allow_dependencies_licenses)
validateLicenses('allow-licenses', allow_licenses)
validateLicenses('deny-licenses', deny_licenses)

Expand Down Expand Up @@ -184,11 +182,6 @@ function parseConfigFile(configData: string): ConfigurationOptionsPartial {
validateLicenses(key, data[key])
}

// validate purls from the allow-dependencies-licenses
if (key === 'allow-dependencies-licenses') {
validatePURL(data[key])
}

// get rid of the ugly dashes from the actions conventions
if (key.includes('-')) {
data[key.replace(/-/g, '_')] = data[key]
Expand Down Expand Up @@ -227,19 +220,3 @@ async function getRemoteConfig(configOpts: {
throw new Error('Error fetching remote config file')
}
}
function validatePURL(allow_dependencies_licenses: string[] | undefined): void {
//validate that the provided elements of the string are in valid purl format
if (allow_dependencies_licenses === undefined) {
return
}
const invalid_purls = allow_dependencies_licenses.filter(
purl => !parsePURL(purl).error
)

if (invalid_purls.length > 0) {
throw new Error(
`Invalid purl(s) in allow-dependencies-licenses: ${invalid_purls}`
)
}
return
}
18 changes: 17 additions & 1 deletion src/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@ const PackageURLWithNamespace = z
}
})

const PackageURLString = z.string().superRefine((value, context) => {
const purl = parsePURL(value)
if (purl.error) {
context.addIssue({
code: z.ZodIssueCode.custom,
message: `Error parsing package-url: ${purl.error}`
})
}
if (!purl.name) {
context.addIssue({
code: z.ZodIssueCode.custom,
message: `Error parsing package-url: name is required`
})
}
})

export const ChangeSchema = z.object({
change_type: z.enum(['added', 'removed']),
manifest: z.string(),
Expand Down Expand Up @@ -81,7 +97,7 @@ export const ConfigurationOptionsSchema = z
fail_on_scopes: z.array(z.enum(SCOPES)).default(['runtime']),
allow_licenses: z.array(z.string()).optional(),
deny_licenses: z.array(z.string()).optional(),
allow_dependencies_licenses: z.array(z.string()).optional(),
allow_dependencies_licenses: z.array(PackageURLString).optional(),
allow_ghsas: z.array(z.string()).default([]),
deny_packages: z.array(PackageURL).default([]),
deny_groups: z.array(PackageURLWithNamespace).default([]),
Expand Down

0 comments on commit f3dac32

Please sign in to comment.