Skip to content

Commit

Permalink
Implement IamPolicyCheck unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kevluu-aws committed Sep 11, 2024
1 parent a71fffe commit b42242a
Show file tree
Hide file tree
Showing 2 changed files with 813 additions and 16 deletions.
33 changes: 17 additions & 16 deletions packages/core/src/awsService/accessanalyzer/vue/iamPolicyChecks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import * as fs from 'fs'
import * as path from 'path'
import { getLogger, Logger } from '../../../shared/logger'
import { localize } from '../../../shared/utilities/vsCodeUtils'
import { VueWebview } from '../../../webviews/main'
import { VueWebview, VueWebviewPanel } from '../../../webviews/main'
import { ExtContext } from '../../../shared/extensions'
import { telemetry } from '../../../shared/telemetry/telemetry'
import { AccessAnalyzer, SharedIniFileCredentials } from 'aws-sdk'
Expand All @@ -31,8 +31,8 @@ import { ExpiredTokenException } from '@aws-sdk/client-sso-oidc'

const defaultTerraformConfigPath = 'resources/policychecks-tf-default.yaml'
// Diagnostics for Custom checks are shared
const customPolicyCheckDiagnosticCollection = vscode.languages.createDiagnosticCollection('customPolicyCheck')
const validatePolicyDiagnosticCollection = vscode.languages.createDiagnosticCollection('validatePolicy')
export const customPolicyCheckDiagnosticCollection = vscode.languages.createDiagnosticCollection('customPolicyCheck')
export const validatePolicyDiagnosticCollection = vscode.languages.createDiagnosticCollection('validatePolicy')

export interface IamPolicyChecksInitialData {
checkNoNewAccessFilePath: string
Expand All @@ -56,7 +56,7 @@ export class IamPolicyChecksWebview extends VueWebview {
public static readonly sourcePath: string = 'src/awsService/accessanalyzer/vue/index.js'
public readonly id = 'iamPolicyChecks'
private static editedDocumentUri: vscode.Uri
private static editedDocumentFileName: string
public static editedDocumentFileName: string
private static editedDocument: string

public constructor(
Expand Down Expand Up @@ -715,9 +715,9 @@ export class IamPolicyChecksWebview extends VueWebview {
}

public pushCustomCheckDiagnostic(diagnostics: vscode.Diagnostic[], finding: any, isBlocking: boolean) {
const message = `${finding.findingType}: ${finding.message} - Resource name: ${finding.resourceName}, Policy name: ${finding.policyName}`
let message = `${finding.findingType}: ${finding.message} - Resource name: ${finding.resourceName}, Policy name: ${finding.policyName}`
if (message.includes('existingPolicyDocument')) {
message.replace('existingPolicyDocument', 'reference document')
message = message.replace('existingPolicyDocument', 'reference document')
}
if (finding.details.reasons) {
finding.details.reasons.forEach((reason: any) => {
Expand All @@ -744,7 +744,7 @@ export class IamPolicyChecksWebview extends VueWebview {

const Panel = VueWebview.compilePanel(IamPolicyChecksWebview)

export async function renderIamPolicyChecks(context: ExtContext): Promise<void> {
export async function renderIamPolicyChecks(context: ExtContext): Promise<VueWebviewPanel | undefined> {
const logger: Logger = getLogger()
try {
const client = new AccessAnalyzer({ region: context.regionProvider.defaultRegionId })
Expand Down Expand Up @@ -795,13 +795,14 @@ export async function renderIamPolicyChecks(context: ExtContext): Promise<void>
viewColumn: vscode.ViewColumn.Beside,
title: localize('AWS.iamPolicyChecks.title', 'IAM Policy Checks'),
})
return wv
} catch (err) {
logger.error(err as Error)
}
}

// Helper function to get document contents from a path
async function _readCustomChecksFile(input: string): Promise<string> {
export async function _readCustomChecksFile(input: string): Promise<string> {
if (fs.existsSync(input)) {
return fs.readFileSync(input).toString()
} else {
Expand All @@ -823,7 +824,7 @@ async function _readCustomChecksFile(input: string): Promise<string> {
}

//Check if Cfn and Tf tools are installed
function arePythonToolsInstalled(): boolean {
export function arePythonToolsInstalled(): boolean {
const logger: Logger = getLogger()
let cfnToolInstalled = true
let tfToolInstalled = true
Expand All @@ -846,12 +847,12 @@ function arePythonToolsInstalled(): boolean {
return cfnToolInstalled && tfToolInstalled
}

function isProcessNotFoundErr(errMsg: string) {
export function isProcessNotFoundErr(errMsg: string) {
return errMsg.includes('command not found') || errMsg.includes('ENOENT')
}

// Since TypeScript can only get the CLI tool's error output as a string, we have to parse and sanitize it ourselves
function parseCliErrorMessage(message: string, documentType: PolicyChecksDocumentType): string {
export function parseCliErrorMessage(message: string, documentType: PolicyChecksDocumentType): string {
const cfnMatch = message.match(/ERROR: .*/)
const botoMatch = message.match(/(?<=botocore\.exceptions\.).*/) // Boto errors have a special match
const terraformMatch = message.match(/AttributeError:.*/) // Terraform CLI responds with a different error schema... this catches invalid .json plans
Expand All @@ -876,7 +877,7 @@ function parseCliErrorMessage(message: string, documentType: PolicyChecksDocumen
return message
}

function getCheckNoNewAccessErrorMessage(finding: any) {
export function getCheckNoNewAccessErrorMessage(finding: any) {
if (finding.findingType === 'ERROR') {
if (
finding.message.includes(
Expand All @@ -888,7 +889,7 @@ function getCheckNoNewAccessErrorMessage(finding: any) {
}
}

function getResultCssColor(resultType: PolicyChecksResult): string {
export function getResultCssColor(resultType: PolicyChecksResult): string {
switch (resultType) {
case 'Success':
return 'var(--vscode-terminal-ansiGreen)'
Expand All @@ -899,17 +900,17 @@ function getResultCssColor(resultType: PolicyChecksResult): string {
}
}

function isCloudFormationTemplate(document: string): boolean {
export function isCloudFormationTemplate(document: string): boolean {
const cfnFileTypes = ['.yaml', '.yml', '.json']
return cfnFileTypes.some((t) => document.endsWith(t))
}

function isTerraformPlan(document: string) {
export function isTerraformPlan(document: string) {
const terraformPlanFileTypes = ['.json']
return terraformPlanFileTypes.some((t) => document.endsWith(t))
}

function isJsonPolicyLanguage(document: string) {
export function isJsonPolicyLanguage(document: string) {
const policyLanguageFileTypes = ['.json']
return policyLanguageFileTypes.some((t) => document.endsWith(t))
}
Expand Down
Loading

0 comments on commit b42242a

Please sign in to comment.