@@ -11,7 +11,8 @@ import { localize } from '../../../shared/utilities/vsCodeUtils'
1111import { VueWebview , VueWebviewPanel } from '../../../webviews/main'
1212import { ExtContext } from '../../../shared/extensions'
1313import { telemetry } from '../../../shared/telemetry/telemetry'
14- import { AccessAnalyzer , SharedIniFileCredentials } from 'aws-sdk'
14+ import { AccessAnalyzerClient , ValidatePolicyCommand } from '@aws-sdk/client-accessanalyzer'
15+ import { fromIni } from '@aws-sdk/credential-providers'
1516import { ToolkitError } from '../../../shared/errors'
1617import { makeTemporaryToolkitFolder , tryRemoveFolder } from '../../../shared/filesystemUtilities'
1718import globals from '../../../shared/extensionGlobals'
@@ -23,7 +24,6 @@ import {
2324 PolicyChecksPolicyType ,
2425 PolicyChecksResult ,
2526 PolicyChecksUiClick ,
26- ValidatePolicyFindingType ,
2727} from './constants'
2828import { S3Client , parseS3Uri } from '../../../shared/clients/s3'
2929import { ExpiredTokenException } from '@aws-sdk/client-sso-oidc'
@@ -61,7 +61,7 @@ export class IamPolicyChecksWebview extends VueWebview {
6161
6262 public constructor (
6363 private readonly data : IamPolicyChecksInitialData ,
64- private client : AccessAnalyzer ,
64+ private client : AccessAnalyzerClient ,
6565 private readonly region : string ,
6666 public readonly onChangeInputPath = new vscode . EventEmitter < string > ( ) ,
6767 public readonly onChangeCheckNoNewAccessFilePath = new vscode . EventEmitter < string > ( ) ,
@@ -179,85 +179,94 @@ export class IamPolicyChecksWebview extends VueWebview {
179179 documentType,
180180 inputPolicyType : policyType ? policyType : 'None' ,
181181 } )
182- this . client . config . credentials = new SharedIniFileCredentials ( {
182+ this . client . config . credentials = fromIni ( {
183183 profile : `${ getProfileName ( ) } ` ,
184184 } ) // We need to detect changes in the user's credentials
185- this . client . validatePolicy (
186- {
187- policyDocument : IamPolicyChecksWebview . editedDocument ,
188- policyType : policyType === 'Identity' ? 'IDENTITY_POLICY' : 'RESOURCE_POLICY' ,
189- } ,
190- ( err , data ) => {
191- if ( err ) {
185+ this . client
186+ . send (
187+ new ValidatePolicyCommand ( {
188+ policyDocument : IamPolicyChecksWebview . editedDocument ,
189+ policyType : policyType === 'Identity' ? 'IDENTITY_POLICY' : 'RESOURCE_POLICY' ,
190+ } )
191+ )
192+ . then ( ( data ) => {
193+ if ( data . findings && data . findings . length > 0 ) {
192194 span . record ( {
193- findingsCount : 0 ,
195+ findingsCount : data . findings . length ,
194196 } )
195- if ( err instanceof ExpiredTokenException ) {
196- this . onValidatePolicyResponse . fire ( [
197- IamPolicyChecksConstants . InvalidAwsCredentials ,
198- getResultCssColor ( 'Error' ) ,
199- ] )
200- } else {
201- this . onValidatePolicyResponse . fire ( [ err . message , getResultCssColor ( 'Error' ) ] )
202- }
203- } else {
204- if ( data . findings . length > 0 ) {
205- span . record ( {
206- findingsCount : data . findings . length ,
207- } )
208- // eslint-disable-next-line unicorn/no-array-for-each
209- data . findings . forEach ( ( finding : AccessAnalyzer . ValidatePolicyFinding ) => {
210- const message = `${ finding . findingType } : ${ finding . issueCode } - ${ finding . findingDetails } Learn more: ${ finding . learnMoreLink } `
211- if ( ( finding . findingType as ValidatePolicyFindingType ) === 'ERROR' ) {
212- diagnostics . push (
213- new vscode . Diagnostic (
214- new vscode . Range (
215- finding . locations [ 0 ] . span . start . line ,
216- finding . locations [ 0 ] . span . start . offset ,
217- finding . locations [ 0 ] . span . end . line ,
218- finding . locations [ 0 ] . span . end . offset
219- ) ,
220- message ,
221- vscode . DiagnosticSeverity . Error
222- )
223- )
224- validatePolicyDiagnosticCollection . set (
225- IamPolicyChecksWebview . editedDocumentUri ,
226- diagnostics
197+ // eslint-disable-next-line unicorn/no-array-for-each
198+ data . findings . forEach ( ( finding ) => {
199+ const locationSpan = finding . locations ?. [ 0 ] . span
200+ if (
201+ ! locationSpan ?. start ?. line ||
202+ ! locationSpan . start . offset ||
203+ ! locationSpan . end ?. line ||
204+ ! locationSpan . end . offset
205+ ) {
206+ return
207+ }
208+ const message = `${ finding . findingType } : ${ finding . issueCode } - ${ finding . findingDetails } Learn more: ${ finding . learnMoreLink } `
209+ if ( finding . findingType === 'ERROR' ) {
210+ diagnostics . push (
211+ new vscode . Diagnostic (
212+ new vscode . Range (
213+ locationSpan . start . line ,
214+ locationSpan . start . offset ,
215+ locationSpan . end . line ,
216+ locationSpan . end . offset
217+ ) ,
218+ message ,
219+ vscode . DiagnosticSeverity . Error
227220 )
228- } else {
229- diagnostics . push (
230- new vscode . Diagnostic (
231- new vscode . Range (
232- finding . locations [ 0 ] . span . start . line ,
233- finding . locations [ 0 ] . span . start . offset ,
234- finding . locations [ 0 ] . span . end . line ,
235- finding . locations [ 0 ] . span . end . offset
236- ) ,
237- message ,
238- vscode . DiagnosticSeverity . Warning
239- )
221+ )
222+ validatePolicyDiagnosticCollection . set (
223+ IamPolicyChecksWebview . editedDocumentUri ,
224+ diagnostics
225+ )
226+ } else {
227+ diagnostics . push (
228+ new vscode . Diagnostic (
229+ new vscode . Range (
230+ locationSpan . start . line ,
231+ locationSpan . start . offset ,
232+ locationSpan . end . line ,
233+ locationSpan . end . offset
234+ ) ,
235+ message ,
236+ vscode . DiagnosticSeverity . Warning
240237 )
241- validatePolicyDiagnosticCollection . set (
242- IamPolicyChecksWebview . editedDocumentUri ,
243- diagnostics
244- )
245- }
246- } )
247- this . onValidatePolicyResponse . fire ( [
248- IamPolicyChecksConstants . ValidatePolicySuccessWithFindings ,
249- getResultCssColor ( 'Warning' ) ,
250- ] )
251- void vscode . commands . executeCommand ( 'workbench.actions.view.problems' )
252- } else {
253- this . onValidatePolicyResponse . fire ( [
254- IamPolicyChecksConstants . ValidatePolicySuccessNoFindings ,
255- getResultCssColor ( 'Success' ) ,
256- ] )
257- }
238+ )
239+ validatePolicyDiagnosticCollection . set (
240+ IamPolicyChecksWebview . editedDocumentUri ,
241+ diagnostics
242+ )
243+ }
244+ } )
245+ this . onValidatePolicyResponse . fire ( [
246+ IamPolicyChecksConstants . ValidatePolicySuccessWithFindings ,
247+ getResultCssColor ( 'Warning' ) ,
248+ ] )
249+ void vscode . commands . executeCommand ( 'workbench.actions.view.problems' )
250+ } else {
251+ this . onValidatePolicyResponse . fire ( [
252+ IamPolicyChecksConstants . ValidatePolicySuccessNoFindings ,
253+ getResultCssColor ( 'Success' ) ,
254+ ] )
255+ }
256+ } )
257+ . catch ( ( err ) => {
258+ span . record ( {
259+ findingsCount : 0 ,
260+ } )
261+ if ( err instanceof ExpiredTokenException ) {
262+ this . onValidatePolicyResponse . fire ( [
263+ IamPolicyChecksConstants . InvalidAwsCredentials ,
264+ getResultCssColor ( 'Error' ) ,
265+ ] )
266+ } else {
267+ this . onValidatePolicyResponse . fire ( [ err . message , getResultCssColor ( 'Error' ) ] )
258268 }
259- }
260- )
269+ } )
261270 } )
262271 return
263272 } else {
@@ -781,7 +790,7 @@ const Panel = VueWebview.compilePanel(IamPolicyChecksWebview)
781790export async function renderIamPolicyChecks ( context : ExtContext ) : Promise < VueWebviewPanel | undefined > {
782791 const logger : Logger = getLogger ( )
783792 try {
784- const client = new AccessAnalyzer ( { region : context . regionProvider . defaultRegionId } )
793+ const client = new AccessAnalyzerClient ( { region : context . regionProvider . defaultRegionId } )
785794 // Read from settings to auto-fill some inputs
786795 const checkNoNewAccessFilePath : string = vscode . workspace
787796 . getConfiguration ( )
0 commit comments