From 06f11aed35260cc103ee4fffa527b2977c06b897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Scha=CC=88fer?= <101886095+PeterSchafer@users.noreply.github.com> Date: Fri, 15 Dec 2023 15:22:04 +0100 Subject: [PATCH 1/9] feat: Support OAuth Client Credentials Grant --- cliv2/go.mod | 2 +- cliv2/go.sum | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cliv2/go.mod b/cliv2/go.mod index a06857b5e8..8c36f0cb04 100644 --- a/cliv2/go.mod +++ b/cliv2/go.mod @@ -13,7 +13,7 @@ require ( github.com/snyk/cli-extension-iac-rules v0.0.0-20230601153200-c572cfce46ce github.com/snyk/cli-extension-sbom v0.0.0-20231123083311-52b1cecc1a7a github.com/snyk/container-cli v0.0.0-20230920093251-fe865879a91f - github.com/snyk/go-application-framework v0.0.0-20231122083330-bbb0d2002b01 + github.com/snyk/go-application-framework v0.0.0-20231215150436-952511ac0d38 github.com/snyk/go-httpauth v0.0.0-20231117135515-eb445fea7530 github.com/snyk/snyk-iac-capture v0.6.5 github.com/snyk/snyk-ls v0.0.0-20231124091213-5a223c21e0aa diff --git a/cliv2/go.sum b/cliv2/go.sum index 9d204beccf..790fb023c2 100644 --- a/cliv2/go.sum +++ b/cliv2/go.sum @@ -255,8 +255,6 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cmars/go-application-framework v0.0.0-20231121235901-2a517c3dca80 h1:/ih3AkS+EPO51JoSgJCbS5D+5ErEEYQ5Kv3UDtBOhKU= -github.com/cmars/go-application-framework v0.0.0-20231121235901-2a517c3dca80/go.mod h1:Yz/qxFyfhf0xbA+z8Vzr5IM9IDG+BS+2PiGaP1yAsEw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -667,10 +665,10 @@ github.com/snyk/cli-extension-sbom v0.0.0-20231123083311-52b1cecc1a7a h1:oRrk9bv github.com/snyk/cli-extension-sbom v0.0.0-20231123083311-52b1cecc1a7a/go.mod h1:IwRGWjRuNkY08O7NJb7u3JuQkroEB8Qi1MlASpZVu1Q= github.com/snyk/container-cli v0.0.0-20230920093251-fe865879a91f h1:ghajT5PEiLP8XNFIdc7Yn4Th74RH/9Q++dDOp6Cb9eo= github.com/snyk/container-cli v0.0.0-20230920093251-fe865879a91f/go.mod h1:38w+dcAQp9eG3P5t2eNS9eG0reut10AeJjLv5lJ5lpM= -github.com/snyk/go-application-framework v0.0.0-20231121110922-9719383f0706 h1:z/g5P0kS7bedN07rNChlPEifKvAe9+hufGEEifPNcJg= -github.com/snyk/go-application-framework v0.0.0-20231121110922-9719383f0706/go.mod h1:Yz/qxFyfhf0xbA+z8Vzr5IM9IDG+BS+2PiGaP1yAsEw= -github.com/snyk/go-application-framework v0.0.0-20231122083330-bbb0d2002b01 h1:2WL20Lgh2YSifXNJ4zw3tZqX2Qa4CqM2C2m0+oWtKGw= -github.com/snyk/go-application-framework v0.0.0-20231122083330-bbb0d2002b01/go.mod h1:Yz/qxFyfhf0xbA+z8Vzr5IM9IDG+BS+2PiGaP1yAsEw= +github.com/snyk/go-application-framework v0.0.0-20231215140446-093495496045 h1:Ji6Q7C8IUid3gftz1i+uXpA2GPCwfYMYBq0qgecwSEU= +github.com/snyk/go-application-framework v0.0.0-20231215140446-093495496045/go.mod h1:Yz/qxFyfhf0xbA+z8Vzr5IM9IDG+BS+2PiGaP1yAsEw= +github.com/snyk/go-application-framework v0.0.0-20231215150436-952511ac0d38 h1:VvWmJ1b1u6d2TM5MZMt++WSW5thfos7XXm7RswrBU9M= +github.com/snyk/go-application-framework v0.0.0-20231215150436-952511ac0d38/go.mod h1:Yz/qxFyfhf0xbA+z8Vzr5IM9IDG+BS+2PiGaP1yAsEw= github.com/snyk/go-httpauth v0.0.0-20231117135515-eb445fea7530 h1:s9PHNkL6ueYRiAKNfd8OVxlUOqU3qY0VDbgCD1f6WQY= github.com/snyk/go-httpauth v0.0.0-20231117135515-eb445fea7530/go.mod h1:88KbbvGYlmLgee4OcQ19yr0bNpXpOr2kciOthaSzCAg= github.com/snyk/policy-engine v0.22.0 h1:od9pduGrXyfWO791X+8M1qmnvWUxaIXh0gBzGKqeseA= From 7828997c623b84c1dc90822ae0c7095906a66081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Scha=CC=88fer?= <101886095+PeterSchafer@users.noreply.github.com> Date: Fri, 15 Dec 2023 16:57:54 +0100 Subject: [PATCH 2/9] chore: improve help and remove obsolete test --- cliv2/cmd/cliv2/main.go | 10 ++++++---- test/jest/acceptance/cli-args.spec.ts | 1 - 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cliv2/cmd/cliv2/main.go b/cliv2/cmd/cliv2/main.go index 003e9877ac..2452778065 100644 --- a/cliv2/cmd/cliv2/main.go +++ b/cliv2/cmd/cliv2/main.go @@ -21,9 +21,6 @@ import ( "github.com/snyk/cli-extension-dep-graph/pkg/depgraph" "github.com/snyk/cli-extension-iac-rules/iacrules" "github.com/snyk/cli-extension-sbom/pkg/sbom" - "github.com/snyk/cli/cliv2/internal/cliv2" - "github.com/snyk/cli/cliv2/internal/constants" - "github.com/snyk/cli/cliv2/pkg/basic_workflows" "github.com/snyk/container-cli/pkg/container" "github.com/snyk/go-application-framework/pkg/analytics" "github.com/snyk/go-application-framework/pkg/app" @@ -37,6 +34,10 @@ import ( "github.com/snyk/go-httpauth/pkg/httpauth" "github.com/snyk/snyk-iac-capture/pkg/capture" snykls "github.com/snyk/snyk-ls/ls_extension" + + "github.com/snyk/cli/cliv2/internal/cliv2" + "github.com/snyk/cli/cliv2/internal/constants" + "github.com/snyk/cli/cliv2/pkg/basic_workflows" ) var internalOS string @@ -227,7 +228,8 @@ func sendAnalytics(analytics analytics.Analytics, debugLogger *zerolog.Logger) { func help(_ *cobra.Command, args []string) error { helpProvided = true - args = append(os.Args[1:], "--help") + args = utils.RemoveSimilar(os.Args[1:], "--") // remove all double dash arguments to avoid issues with the help command + args = append(args, "--help") return defaultCmd(args) } diff --git a/test/jest/acceptance/cli-args.spec.ts b/test/jest/acceptance/cli-args.spec.ts index 54d2a07af7..9523ddcb29 100644 --- a/test/jest/acceptance/cli-args.spec.ts +++ b/test/jest/acceptance/cli-args.spec.ts @@ -245,7 +245,6 @@ describe('cli args', () => { }); [ - 'auth', 'config', 'help', 'ignore', From 49bea3d113b793280bdf7572361848be0fdac4f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Scha=CC=88fer?= <101886095+PeterSchafer@users.noreply.github.com> Date: Wed, 20 Dec 2023 09:36:58 +0100 Subject: [PATCH 3/9] fix: adapt test expectation to new behaviour --- test/jest/acceptance/cli-args.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/jest/acceptance/cli-args.spec.ts b/test/jest/acceptance/cli-args.spec.ts index 9523ddcb29..b4fa598b88 100644 --- a/test/jest/acceptance/cli-args.spec.ts +++ b/test/jest/acceptance/cli-args.spec.ts @@ -246,7 +246,6 @@ describe('cli args', () => { [ 'config', - 'help', 'ignore', 'modules', 'monitor', From 19c24f9c0e9e8ccf8ce3ab804636d14d85eecbce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Scha=CC=88fer?= <101886095+PeterSchafer@users.noreply.github.com> Date: Wed, 20 Dec 2023 10:22:35 +0100 Subject: [PATCH 4/9] chore: added some basic oauth client cred tests --- test/acceptance/fake-server.ts | 11 ++++++++ test/jest/acceptance/auth.spec.ts | 45 +++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 test/jest/acceptance/auth.spec.ts diff --git a/test/acceptance/fake-server.ts b/test/acceptance/fake-server.ts index 70e201c89b..dff9b7ec62 100644 --- a/test/acceptance/fake-server.ts +++ b/test/acceptance/fake-server.ts @@ -577,6 +577,17 @@ export const fakeServer = (basePath: string, snykToken: string): FakeServer => { }, ); + app.post(basePath.replace('/v1', '') + '/oauth2/token', (req, res) => { + const fake_oauth_token = "{\"access_token\":\"access_token_value\",\"token_type\":\"b\",\"expiry\":\"3023-12-20T08:49:15.504539Z\"}"; + + // client credentials grant: expecting client id = a and client secret = b + if ( req.headers.authorization?.includes("Basic YTpi") ) { + res.status(200).send(fake_oauth_token); + } + + res.status(401).send({}); + }); + const listenPromise = (port: string | number) => { return new Promise((resolve) => { server = http.createServer(app).listen(Number(port), resolve); diff --git a/test/jest/acceptance/auth.spec.ts b/test/jest/acceptance/auth.spec.ts new file mode 100644 index 0000000000..164a089a42 --- /dev/null +++ b/test/jest/acceptance/auth.spec.ts @@ -0,0 +1,45 @@ +import { fakeServer } from '../../acceptance/fake-server'; +import { createProjectFromWorkspace } from '../util/createProject'; +import { runSnykCLI } from '../util/runSnykCLI'; + +jest.setTimeout(1000 * 60); + +describe('Auth', () => { + let server: ReturnType; + let env: Record; + + beforeAll((done) => { + const apiPath = '/api/v1'; + const apiPort = process.env.PORT || process.env.SNYK_PORT || '12345'; + env = { + ...process.env, + SNYK_API: 'http://localhost:' + apiPort + apiPath, + SNYK_DISABLE_ANALYTICS: '1', + }; + + server = fakeServer(apiPath, env.SNYK_TOKEN); + server.listen(apiPort, () => done()); + }); + + afterEach(() => { + server.restore(); + }); + + afterAll((done) => { + server.close(() => done()); + }); + + it('successfully uses oauth client credentials grant to authenticate', async () => { + const {code} = await runSnykCLI(`auth --auth-type=oauth --client-id a --client-secret b`, { + env, + }); + expect(code).toEqual(0); + }); + + it('fails to us oauth client credentials grant to authenticate', async () => { + const {code} = await runSnykCLI(`auth --auth-type=oauth --client-id wrong --client-secret b`, { + env, + }); + expect(code).toEqual(2); + }); +}); \ No newline at end of file From 409cb7647d67f64a162a1732bd34f50270915dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Scha=CC=88fer?= <101886095+PeterSchafer@users.noreply.github.com> Date: Wed, 20 Dec 2023 10:37:31 +0100 Subject: [PATCH 5/9] chore: run formatter --- test/acceptance/fake-server.ts | 5 +++-- test/jest/acceptance/auth.spec.ts | 21 +++++++++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/test/acceptance/fake-server.ts b/test/acceptance/fake-server.ts index dff9b7ec62..644471a037 100644 --- a/test/acceptance/fake-server.ts +++ b/test/acceptance/fake-server.ts @@ -578,10 +578,11 @@ export const fakeServer = (basePath: string, snykToken: string): FakeServer => { ); app.post(basePath.replace('/v1', '') + '/oauth2/token', (req, res) => { - const fake_oauth_token = "{\"access_token\":\"access_token_value\",\"token_type\":\"b\",\"expiry\":\"3023-12-20T08:49:15.504539Z\"}"; + const fake_oauth_token = + '{"access_token":"access_token_value","token_type":"b","expiry":"3023-12-20T08:49:15.504539Z"}'; // client credentials grant: expecting client id = a and client secret = b - if ( req.headers.authorization?.includes("Basic YTpi") ) { + if (req.headers.authorization?.includes('Basic YTpi')) { res.status(200).send(fake_oauth_token); } diff --git a/test/jest/acceptance/auth.spec.ts b/test/jest/acceptance/auth.spec.ts index 164a089a42..f3c53cd405 100644 --- a/test/jest/acceptance/auth.spec.ts +++ b/test/jest/acceptance/auth.spec.ts @@ -1,5 +1,4 @@ import { fakeServer } from '../../acceptance/fake-server'; -import { createProjectFromWorkspace } from '../util/createProject'; import { runSnykCLI } from '../util/runSnykCLI'; jest.setTimeout(1000 * 60); @@ -30,16 +29,22 @@ describe('Auth', () => { }); it('successfully uses oauth client credentials grant to authenticate', async () => { - const {code} = await runSnykCLI(`auth --auth-type=oauth --client-id a --client-secret b`, { - env, - }); + const { code } = await runSnykCLI( + `auth --auth-type=oauth --client-id a --client-secret b`, + { + env, + }, + ); expect(code).toEqual(0); }); it('fails to us oauth client credentials grant to authenticate', async () => { - const {code} = await runSnykCLI(`auth --auth-type=oauth --client-id wrong --client-secret b`, { - env, - }); + const { code } = await runSnykCLI( + `auth --auth-type=oauth --client-id wrong --client-secret b`, + { + env, + }, + ); expect(code).toEqual(2); }); -}); \ No newline at end of file +}); From 730827ce44c4d972cd22050d80843215a910850e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Scha=CC=88fer?= <101886095+PeterSchafer@users.noreply.github.com> Date: Wed, 20 Dec 2023 12:19:39 +0100 Subject: [PATCH 6/9] chore: remove test token to not interfer with other tests --- test/jest/acceptance/auth.spec.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/jest/acceptance/auth.spec.ts b/test/jest/acceptance/auth.spec.ts index f3c53cd405..0affffcd1d 100644 --- a/test/jest/acceptance/auth.spec.ts +++ b/test/jest/acceptance/auth.spec.ts @@ -36,6 +36,14 @@ describe('Auth', () => { }, ); expect(code).toEqual(0); + + // delete test token + await runSnykCLI( + `config unset INTERNAL_OAUTH_TOKEN_STORAGE`, + { + env, + }, + ); }); it('fails to us oauth client credentials grant to authenticate', async () => { From 4e3dbc42ddcb4974f66adc7d3a0c79e6fb465bf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Scha=CC=88fer?= <101886095+PeterSchafer@users.noreply.github.com> Date: Wed, 20 Dec 2023 13:35:14 +0100 Subject: [PATCH 7/9] chore: cleanup after auth test --- test/jest/acceptance/auth.spec.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/test/jest/acceptance/auth.spec.ts b/test/jest/acceptance/auth.spec.ts index 0affffcd1d..64223b1f5c 100644 --- a/test/jest/acceptance/auth.spec.ts +++ b/test/jest/acceptance/auth.spec.ts @@ -38,12 +38,9 @@ describe('Auth', () => { expect(code).toEqual(0); // delete test token - await runSnykCLI( - `config unset INTERNAL_OAUTH_TOKEN_STORAGE`, - { - env, - }, - ); + await runSnykCLI(`config unset INTERNAL_OAUTH_TOKEN_STORAGE`, { + env, + }); }); it('fails to us oauth client credentials grant to authenticate', async () => { From 2bdf6134771a80a602c142cb98bb42dacabc8287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Scha=CC=88fer?= <101886095+PeterSchafer@users.noreply.github.com> Date: Fri, 22 Dec 2023 17:25:00 +0100 Subject: [PATCH 8/9] fix: add missing return --- test/acceptance/fake-server.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/acceptance/fake-server.ts b/test/acceptance/fake-server.ts index 644471a037..41c8fd4be3 100644 --- a/test/acceptance/fake-server.ts +++ b/test/acceptance/fake-server.ts @@ -584,6 +584,7 @@ export const fakeServer = (basePath: string, snykToken: string): FakeServer => { // client credentials grant: expecting client id = a and client secret = b if (req.headers.authorization?.includes('Basic YTpi')) { res.status(200).send(fake_oauth_token); + return; } res.status(401).send({}); From e38006e05a8b0ff1b4acee2369186fa11f2f08e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Scha=CC=88fer?= <101886095+PeterSchafer@users.noreply.github.com> Date: Fri, 22 Dec 2023 17:28:32 +0100 Subject: [PATCH 9/9] chore: use final GAF commit --- cliv2/go.mod | 2 +- cliv2/go.sum | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/cliv2/go.mod b/cliv2/go.mod index 8c36f0cb04..d754c864b9 100644 --- a/cliv2/go.mod +++ b/cliv2/go.mod @@ -13,7 +13,7 @@ require ( github.com/snyk/cli-extension-iac-rules v0.0.0-20230601153200-c572cfce46ce github.com/snyk/cli-extension-sbom v0.0.0-20231123083311-52b1cecc1a7a github.com/snyk/container-cli v0.0.0-20230920093251-fe865879a91f - github.com/snyk/go-application-framework v0.0.0-20231215150436-952511ac0d38 + github.com/snyk/go-application-framework v0.0.0-20231222162659-c767e4a7440b github.com/snyk/go-httpauth v0.0.0-20231117135515-eb445fea7530 github.com/snyk/snyk-iac-capture v0.6.5 github.com/snyk/snyk-ls v0.0.0-20231124091213-5a223c21e0aa diff --git a/cliv2/go.sum b/cliv2/go.sum index 790fb023c2..54e170a132 100644 --- a/cliv2/go.sum +++ b/cliv2/go.sum @@ -665,10 +665,8 @@ github.com/snyk/cli-extension-sbom v0.0.0-20231123083311-52b1cecc1a7a h1:oRrk9bv github.com/snyk/cli-extension-sbom v0.0.0-20231123083311-52b1cecc1a7a/go.mod h1:IwRGWjRuNkY08O7NJb7u3JuQkroEB8Qi1MlASpZVu1Q= github.com/snyk/container-cli v0.0.0-20230920093251-fe865879a91f h1:ghajT5PEiLP8XNFIdc7Yn4Th74RH/9Q++dDOp6Cb9eo= github.com/snyk/container-cli v0.0.0-20230920093251-fe865879a91f/go.mod h1:38w+dcAQp9eG3P5t2eNS9eG0reut10AeJjLv5lJ5lpM= -github.com/snyk/go-application-framework v0.0.0-20231215140446-093495496045 h1:Ji6Q7C8IUid3gftz1i+uXpA2GPCwfYMYBq0qgecwSEU= -github.com/snyk/go-application-framework v0.0.0-20231215140446-093495496045/go.mod h1:Yz/qxFyfhf0xbA+z8Vzr5IM9IDG+BS+2PiGaP1yAsEw= -github.com/snyk/go-application-framework v0.0.0-20231215150436-952511ac0d38 h1:VvWmJ1b1u6d2TM5MZMt++WSW5thfos7XXm7RswrBU9M= -github.com/snyk/go-application-framework v0.0.0-20231215150436-952511ac0d38/go.mod h1:Yz/qxFyfhf0xbA+z8Vzr5IM9IDG+BS+2PiGaP1yAsEw= +github.com/snyk/go-application-framework v0.0.0-20231222162659-c767e4a7440b h1:NNiXGaKELaFmejlw5BOWf8dVThl8iisU9Yhx+FSUrL4= +github.com/snyk/go-application-framework v0.0.0-20231222162659-c767e4a7440b/go.mod h1:Yz/qxFyfhf0xbA+z8Vzr5IM9IDG+BS+2PiGaP1yAsEw= github.com/snyk/go-httpauth v0.0.0-20231117135515-eb445fea7530 h1:s9PHNkL6ueYRiAKNfd8OVxlUOqU3qY0VDbgCD1f6WQY= github.com/snyk/go-httpauth v0.0.0-20231117135515-eb445fea7530/go.mod h1:88KbbvGYlmLgee4OcQ19yr0bNpXpOr2kciOthaSzCAg= github.com/snyk/policy-engine v0.22.0 h1:od9pduGrXyfWO791X+8M1qmnvWUxaIXh0gBzGKqeseA=