Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions src/commands/organization/cmd-organization-policy-license.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import path from 'node:path'

import { describe, expect } from 'vitest'

import constants from '../../../dist/constants.js'
import { cmdit, invokeNpm } from '../../../test/utils'

const { CLI } = constants

describe('socket organization policy license', async () => {
// Lazily access constants.rootBinPath.
const entryPath = path.join(constants.rootBinPath, `${CLI}.js`)

cmdit(
['organization', 'policy', 'license', '--help', '--config', '{}'],
'should support --help',
async cmd => {
const { code, stderr, stdout } = await invokeNpm(entryPath, cmd)
expect(stdout).toMatchInlineSnapshot(
`
"Retrieve the license policy of an organization.

Usage
$ socket organization policy license <org slug>

Options
--dryRun Do input validation for a command and exit 0 when input is ok
--help Print this help.
--json Output result as json
--markdown Output result as markdown

Your API token will need the \`license-policy:read\` permission otherwise
the request will fail with an authentication error.

Examples
$ socket organization policy license mycorp
$ socket organization policy license mycorp --json"
`
)
expect(`\n ${stderr}`).toMatchInlineSnapshot(`
"
_____ _ _ /---------------
| __|___ ___| |_ ___| |_ | Socket.dev CLI ver <redacted>
|__ | . | _| '_| -_| _| | Node: <redacted>, API token set: <redacted>
|_____|___|___|_,_|___|_|.dev | Command: \`socket organization policy license\`, cwd: <redacted>"
`)

expect(code, 'help should exit with code 2').toBe(2)
expect(stderr, 'banner includes base command').toContain(
'`socket organization policy license`'
)
}
)

cmdit(
['organization', 'policy', 'license', '--dry-run', '--config', '{}'],
'should reject dry run without proper args',
async cmd => {
const { code, stderr, stdout } = await invokeNpm(entryPath, cmd)
expect(stdout).toMatchInlineSnapshot(`""`)
expect(`\n ${stderr}`).toMatchInlineSnapshot(`
"
_____ _ _ /---------------
| __|___ ___| |_ ___| |_ | Socket.dev CLI ver <redacted>
|__ | . | _| '_| -_| _| | Node: <redacted>, API token set: <redacted>
|_____|___|___|_,_|___|_|.dev | Command: \`socket organization policy license\`, cwd: <redacted>

\\x1b[31m\\xd7\\x1b[39m \\x1b[41m\\x1b[1m\\x1b[37m Input error: \\x1b[39m\\x1b[22m\\x1b[49m \\x1b[1mPlease review the input requirements and try again\\x1b[22m:

- Org name as the first argument (\\x1b[31mmissing\\x1b[39m)"
`)

expect(code, 'dry-run should exit with code 2 if input bad').toBe(2)
}
)

cmdit(
[
'organization',
'policy',
'license',
'fakeorg',
'--dry-run',
'--config',
'{}'
],
'should be ok with org name and id',
async cmd => {
const { code, stderr, stdout } = await invokeNpm(entryPath, cmd)
expect(stdout).toMatchInlineSnapshot(`"[DryRun]: Bailing now"`)
expect(`\n ${stderr}`).toMatchInlineSnapshot(`
"
_____ _ _ /---------------
| __|___ ___| |_ ___| |_ | Socket.dev CLI ver <redacted>
|__ | . | _| '_| -_| _| | Node: <redacted>, API token set: <redacted>
|_____|___|___|_,_|___|_|.dev | Command: \`socket organization policy license\`, cwd: <redacted>"
`)

expect(code, 'dry-run should exit with code 0 if input ok').toBe(0)
}
)
})
93 changes: 93 additions & 0 deletions src/commands/organization/cmd-organization-policy-license.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { logger } from '@socketsecurity/registry/lib/logger'

import { handleLicensePolicy } from './handle-license-policy'
import constants from '../../constants'
import { commonFlags, outputFlags } from '../../flags'
import { getConfigValue } from '../../utils/config'
import { handleBadInput } from '../../utils/handle-bad-input'
import { meowOrExit } from '../../utils/meow-with-subcommands'
import { getFlagListOutput } from '../../utils/output-formatting'

import type { CliCommandConfig } from '../../utils/meow-with-subcommands'

const { DRY_RUN_BAIL_TEXT } = constants

// TODO: secret toplevel alias `socket license policy`?
const config: CliCommandConfig = {
commandName: 'license',
description: 'Retrieve the license policy of an organization.',
hidden: true,
flags: {
...commonFlags,
...outputFlags
},
help: (command, _config) => `
Usage
$ ${command} <org slug>

Options
${getFlagListOutput(config.flags, 6)}

Your API token will need the \`license-policy:read\` permission otherwise
the request will fail with an authentication error.

Examples
$ ${command} mycorp
$ ${command} mycorp --json
`
}

export const cmdOrganizationPolicyLicense = {
description: config.description,
hidden: config.hidden,
run
}

async function run(
argv: string[] | readonly string[],
importMeta: ImportMeta,
{ parentName }: { parentName: string }
): Promise<void> {
const cli = meowOrExit({
argv,
config,
importMeta,
parentName
})

const json = Boolean(cli.flags['json'])
const markdown = Boolean(cli.flags['markdown'])

const defaultOrgSlug = getConfigValue('defaultOrg')
const orgSlug = defaultOrgSlug || cli.input[0] || ''

const wasBadInput = handleBadInput(
{
hide: defaultOrgSlug,
test: orgSlug,
message: 'Org name as the first argument',
pass: 'ok',
fail: 'missing'
},
{
hide: !json || !markdown,
test: !json || !markdown,
message: 'The json and markdown flags cannot be both set, pick one',
pass: 'ok',
fail: 'omit one'
}
)
if (wasBadInput) {
return
}

if (cli.flags['dryRun']) {
logger.log(DRY_RUN_BAIL_TEXT)
return
}

await handleLicensePolicy(
orgSlug,
json ? 'json' : markdown ? 'markdown' : 'text'
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { cmdit, invokeNpm } from '../../../test/utils'

const { CLI } = constants

describe('socket organization list', async () => {
describe('socket organization policy security', async () => {
// Lazily access constants.rootBinPath.
const entryPath = path.join(constants.rootBinPath, `${CLI}.js`)

Expand Down
4 changes: 3 additions & 1 deletion src/commands/organization/cmd-organization-policy.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { cmdOrganizationPolicyLicense } from './cmd-organization-policy-license'
import { cmdOrganizationPolicyPolicy } from './cmd-organization-policy-security'
import { meowWithSubcommands } from '../../utils/meow-with-subcommands'

Expand All @@ -15,7 +16,8 @@ export const cmdOrganizationPolicy: CliSubcommand = {
async run(argv, importMeta, { parentName }) {
await meowWithSubcommands(
{
security: cmdOrganizationPolicyPolicy
security: cmdOrganizationPolicyPolicy,
license: cmdOrganizationPolicyLicense
},
{
argv,
Expand Down
45 changes: 45 additions & 0 deletions src/commands/organization/fetch-license-policy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import constants from '../../constants'
import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api'
import { AuthError } from '../../utils/errors'
import { getDefaultToken, setupSdk } from '../../utils/sdk'

import type { SocketSdkReturnType } from '@socketsecurity/sdk'

export async function fetchLicensePolicy(
orgSlug: string
): Promise<SocketSdkReturnType<'getOrgLicensePolicy'>['data'] | undefined> {
const apiToken = getDefaultToken()
if (!apiToken) {
throw new AuthError(
'User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.'
)
}

return await fetchLicensePolicyWithToken(apiToken, orgSlug)
}

async function fetchLicensePolicyWithToken(
apiToken: string,
orgSlug: string
): Promise<SocketSdkReturnType<'getOrgLicensePolicy'>['data'] | undefined> {
// Lazily access constants.spinner.
const { spinner } = constants

const sockSdk = await setupSdk(apiToken)

spinner.start('Fetching organization license policy...')

const result = await handleApiCall(
sockSdk.getOrgLicensePolicy(orgSlug),
'looking up organization quota'
)

spinner.successAndStop('Received organization license policy response.')

if (!result.success) {
handleUnsuccessfulApiResponse('getOrgLicensePolicy', result)
return
}

return result.data
}
4 changes: 2 additions & 2 deletions src/commands/organization/fetch-security-policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ async function fetchSecurityPolicyWithToken(

const sockSdk = await setupSdk(apiToken)

spinner.start('Fetching organization quota...')
spinner.start('Fetching organization security policy...')

const result = await handleApiCall(
sockSdk.getOrgSecurityPolicy(orgSlug),
'looking up organization quota'
)

spinner?.successAndStop('Received organization quota response.')
spinner?.successAndStop('Received organization security policy response.')

if (!result.success) {
handleUnsuccessfulApiResponse('getOrgSecurityPolicy', result)
Expand Down
102 changes: 0 additions & 102 deletions src/commands/organization/get-license-policy.ts

This file was deleted.

Loading
Loading