Skip to content

Commit b72611f

Browse files
committed
adding a patched object to bypass auth
1 parent 22337b7 commit b72611f

File tree

4 files changed

+169
-93
lines changed

4 files changed

+169
-93
lines changed

packages/amazonq/test/e2e_new/amazonq/utils/authUtils.ts

Lines changed: 90 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
* SPDX-License-Identifier: Apache-2.0
44
*/
5-
import { Workbench, By, WebviewView } from 'vscode-extension-tester'
6-
import { findItemByText, printElementHTML, sleep, waitForElements } from './generalUtils'
5+
import { Workbench, WebviewView, By } from 'vscode-extension-tester'
6+
import { printElementHTML, sleep } from './generalUtils'
77
import { testContext } from './testContext'
8-
import { isRunningInGitHubActionsE2E } from './ciUtils'
9-
import { authenticateForCI } from './ciOidcClient'
108

119
/* Completes the entire Amazon Q login flow
1210
@@ -18,34 +16,78 @@ Currently, the function will
1816
1917
TO-DO: Currently this signInToAmazonQ is not fully autonomous as we ran into a blocker when the browser window pops up */
2018
export async function signInToAmazonQ(): Promise<void> {
21-
if (isRunningInGitHubActionsE2E()) {
22-
console.log('CI Environment detected: Using automated authentication')
23-
await authenticateForCI()
24-
25-
// Set up minimal test context for CI
26-
const workbench = new Workbench()
27-
testContext.workbench = workbench
28-
// Skip webview setup for CI as authentication is handled by Lambda
29-
await workbench.executeCommand('Amazon Q: Open Chat')
30-
console.log('THIS WORKED 1')
31-
const editorView = workbench.getEditorView()
32-
console.log('THIS WORKED 2')
33-
await editorView.closeAllEditors()
34-
console.log('THIS WORKED 3')
35-
const webviewView = new WebviewView()
36-
console.log('THIS WORKED 4')
37-
await webviewView.switchToFrame()
38-
console.log('THIS WORKED 5')
39-
40-
testContext.webviewView = webviewView
41-
console.log('IT WORKED')
42-
const body = webviewView.findElement(By.css('*'))
43-
const body2 = workbench.findElement(By.css('*'))
44-
await printElementHTML(body)
45-
await printElementHTML(body2)
46-
//if were not getting the print that we're expecting josh's registerhook works the moment the browser popup happens so we can probs use that
47-
return
48-
}
19+
// if (isRunningInGitHubActionsE2E()) {
20+
// console.log('CI Environment detected: Using automated authentication')
21+
// const workbench = new Workbench()
22+
// await workbench.executeCommand('Amazon Q: Open Chat')
23+
24+
// await sleep(5000)
25+
// let webviewView = new WebviewView()
26+
// await webviewView.switchToFrame()
27+
28+
// const selectableItems = await waitForElements(webviewView, By.css('.selectable-item'))
29+
// if (selectableItems.length === 0) {
30+
// throw new Error('No selectable login options found')
31+
// }
32+
33+
// // find the button / input + click the button / input
34+
// const companyItem = await findItemByText(selectableItems, 'Company account')
35+
// await companyItem.click()
36+
37+
// const signInContinue = await webviewView.findWebElement(By.css('#connection-selection-continue-button'))
38+
// await signInContinue.click()
39+
40+
// const startUrlInput = await webviewView.findWebElement(By.id('startUrl'))
41+
// await startUrlInput.clear()
42+
// await startUrlInput.sendKeys('https://amzn.awsapps.com/start')
43+
44+
// const UrlContinue = await webviewView.findWebElement(By.css('button.continue-button.topMargin'))
45+
// await UrlContinue.click()
46+
47+
// await sleep(3000)
48+
// await authenticateForCI()
49+
// console.log('Waiting for manual authentication...')
50+
// await sleep(12000)
51+
// console.log('Manual authentication should be done')
52+
53+
// await webviewView.switchBack()
54+
55+
// const editorView = workbench.getEditorView()
56+
// await editorView.closeAllEditors()
57+
// webviewView = new WebviewView()
58+
// await webviewView.switchToFrame()
59+
// const body = webviewView.findElement(By.css('*'))
60+
// const body2 = workbench.findElement(By.css('*'))
61+
// await printElementHTML(body)
62+
// await printElementHTML(body2)
63+
64+
// testContext.workbench = workbench
65+
// testContext.webviewView = webviewView
66+
67+
// // // Set up minimal test context for CI
68+
// // const workbench = new Workbench()
69+
// // testContext.workbench = workbench
70+
// // // Skip webview setup for CI as authentication is handled by Lambda
71+
// // await workbench.executeCommand('Amazon Q: Open Chat')
72+
// // console.log('THIS WORKED 1')
73+
// // const editorView = workbench.getEditorView()
74+
// // console.log('THIS WORKED 2')
75+
// // await editorView.closeAllEditors()
76+
// // console.log('THIS WORKED 3')
77+
// // const webviewView = new WebviewView()
78+
// // console.log('THIS WORKED 4')
79+
// // await webviewView.switchToFrame()
80+
// // console.log('THIS WORKED 5')
81+
82+
// // testContext.webviewView = webviewView
83+
// // console.log('IT WORKED')
84+
// // const body = webviewView.findElement(By.css('*'))
85+
// // const body2 = workbench.findElement(By.css('*'))
86+
// // await printElementHTML(body)
87+
// // await printElementHTML(body2)
88+
// //if were not getting the print that we're expecting josh's registerhook works the moment the browser popup happens so we can probs use that
89+
// return
90+
// }
4991

5092
// Normal manual authentication flow for local development
5193
const workbench = new Workbench()
@@ -55,25 +97,26 @@ export async function signInToAmazonQ(): Promise<void> {
5597
let webviewView = new WebviewView()
5698
await webviewView.switchToFrame()
5799

58-
const selectableItems = await waitForElements(webviewView, By.css('.selectable-item'))
59-
if (selectableItems.length === 0) {
60-
throw new Error('No selectable login options found')
61-
}
100+
// const selectableItems = await waitForElements(webviewView, By.css('.selectable-item'))
101+
// if (selectableItems.length === 0) {
102+
// throw new Error('No selectable login options found')
103+
// }
62104

63-
// find the button / input + click the button / input
64-
const companyItem = await findItemByText(selectableItems, 'Company account')
65-
await companyItem.click()
105+
// // find the button / input + click the button / input
106+
// const companyItem = await findItemByText(selectableItems, 'Company account')
107+
// await companyItem.click()
66108

67-
const signInContinue = await webviewView.findWebElement(By.css('#connection-selection-continue-button'))
68-
await signInContinue.click()
109+
// const signInContinue = await webviewView.findWebElement(By.css('#connection-selection-continue-button'))
110+
// await signInContinue.click()
69111

70-
const startUrlInput = await webviewView.findWebElement(By.id('startUrl'))
71-
await startUrlInput.clear()
72-
await startUrlInput.sendKeys('https://amzn.awsapps.com/start')
73-
74-
const UrlContinue = await webviewView.findWebElement(By.css('button.continue-button.topMargin'))
75-
await UrlContinue.click()
112+
// const startUrlInput = await webviewView.findWebElement(By.id('startUrl'))
113+
// await startUrlInput.clear()
114+
// await startUrlInput.sendKeys('https://amzn.awsapps.com/start')
76115

116+
// const UrlContinue = await webviewView.findWebElement(By.css('button.continue-button.topMargin'))
117+
// await UrlContinue.click()
118+
const body = webviewView.findElement(By.css('*'))
119+
await printElementHTML(body)
77120
console.log('Waiting for manual authentication...')
78121
await sleep(12000)
79122
console.log('Manual authentication should be done')

packages/amazonq/test/e2e_new/amazonq/utils/ciUtils.ts

Lines changed: 13 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -59,44 +59,21 @@ export async function invokeAuthLambda(userCode: string, verificationUri: string
5959
.promise()
6060
}
6161

62-
// export function registerAuthHook(secret: string, lambdaId = process.env['AUTH_UTIL_LAMBDA_ARN']) {
63-
// return getTestWindow().onDidShowMessage((message: { items: string | any[] }) => {
64-
// if (message.items.length > 0 && message.items[0].title.match(new RegExp(proceedToBrowser))) {
65-
// if (!lambdaId) {
66-
// const baseMessage = 'Browser login flow was shown during testing without an authorizer function'
67-
// if (process.env['AWS_TOOLKIT_AUTOMATION'] === 'local') {
68-
// throw new Error(`${baseMessage}. You may need to login manually before running tests.`)
69-
// } else {
70-
// throw new Error(`${baseMessage}. Check that environment variables are set correctly.`)
71-
// }
72-
// }
62+
// export async function registerAuthHook(secret: string, lambdaId = process.env['AUTH_UTIL_LAMBDA_ARN']) {
63+
// // Latest eg: 'https://nkomonen.awsapps.com/start/#/device?user_code=JXZC-NVRK'
64+
// const urlString = 'https://oidc.us-east-1.amazonaws.com/authorize?response_type=code&client_id=-yit8OUGd-Hnuxi-wde3dHVzLWVhc3QtMQ&redirect_uri=http://127.0.0.1:53085/oauth/callback&scopes=codewhisperer:completions,codewhisperer:analysis,codewhisperer:conversations,codewhisperer:transformations,codewhisperer:taskassist&state=2f35c7c1-0398-489d-8839-26323587cab6&code_challenge=iL8MZPd_SldEB3B4Y0tKrPjHGRlFt5_r3FYziVNbm9g&code_challenge_method=S256'
7365

74-
// const openStub = patchObject(vscode.env, 'openExternal', async (target: { toString: (arg0: boolean) => any }) => {
75-
// try {
76-
// // Latest eg: 'https://nkomonen.awsapps.com/start/#/device?user_code=JXZC-NVRK'
77-
// const urlString = target.toString(true)
66+
// // Drop the user_code parameter since the auth lambda does not support it yet, and keeping it
67+
// // would trigger a slightly different UI flow which breaks the automation.
68+
// // TODO: If the auth lambda supports user_code in the parameters then we can skip this step
69+
// const verificationUri = urlString.split('?')[0]
7870

79-
// // Drop the user_code parameter since the auth lambda does not support it yet, and keeping it
80-
// // would trigger a slightly different UI flow which breaks the automation.
81-
// // TODO: If the auth lambda supports user_code in the parameters then we can skip this step
82-
// const verificationUri = urlString.split('?')[0]
71+
// const params = urlString.split('?')[1]
72+
// const userCode = new URLSearchParams(params).get('user_code')
8373

84-
// const params = urlString.split('?')[1]
85-
// const userCode = new URLSearchParams(params).get('user_code')
86-
87-
// await invokeLambda(lambdaId, {
88-
// secret,
89-
// userCode,
90-
// verificationUri,
91-
// })
92-
// } finally {
93-
// openStub.dispose()
94-
// }
95-
96-
// return true
97-
// })
98-
99-
// message.items[0].select()
100-
// }
74+
// await invokeLambda(lambdaId, {
75+
// secret,
76+
// userCode,
77+
// verificationUri,
10178
// })
10279
// }

packages/amazonq/test/e2e_new/amazonq/utils/setup.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,13 @@
55
import { signInToAmazonQ } from './authUtils'
66
import { testContext } from './testContext'
77
import { closeAllTabs } from './cleanupUtils'
8-
import { isRunningInGitHubActionsE2E } from './ciUtils'
98

109
before(async function () {
1110
this.timeout(60000)
1211

13-
if (isRunningInGitHubActionsE2E()) {
14-
console.log('\n\n*** CI AUTHENTICATION MODE ***')
15-
console.log('Using Lambda function for automated authentication\n\n')
16-
// CI authentication will be handled during the auth flow
17-
} else {
18-
console.log('\n\n*** MANUAL INTERVENTION REQUIRED ***')
19-
console.log('When prompted, you must manually click to open the browser and complete authentication')
20-
console.log('You have 60 seconds to complete this step\n\n')
21-
}
12+
console.log('\n\n*** MANUAL INTERVENTION REQUIRED ***')
13+
console.log('When prompted, you must manually click to open the browser and complete authentication')
14+
console.log('You have 60 seconds to complete this step\n\n')
2215

2316
await signInToAmazonQ()
2417
const webviewView = testContext.webviewView

packages/core/src/auth/activation.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,97 @@ import { initializeCredentialsProviderManager } from './utils'
1111
import { isAmazonQ, isSageMaker } from '../shared/extensionUtilities'
1212
import { getLogger } from '../shared/logger/logger'
1313
import { getErrorMsg } from '../shared/errors'
14+
import { invokeLambda, patchObject } from '../test/setupUtil'
1415

1516
export interface SagemakerCookie {
1617
authMode?: 'Sso' | 'Iam'
1718
}
1819

20+
// when the extension starts up, it runs this code, have it isolated here
21+
// first, verify with logs before or after auth, if thats true, if all those environment variables
22+
// once
23+
/**
24+
* Based on the debugging messages, this code gets activated the moment i press opne
25+
*
26+
*
27+
*/
1928
export async function initialize(loginManager: LoginManager): Promise<void> {
29+
console.log('INITIALIZATION START')
30+
getLogger().info('[DEBUG] Auth activation initialize() called')
31+
32+
if (true) {
33+
console.log('AUTH LAMBDA HAS BEEN TRIGGERED')
34+
registerAuthHook('amazonq-test-account')
35+
return
36+
}
37+
2038
if (isAmazonQ() && isSageMaker()) {
39+
getLogger().info('[DEBUG] Running in Amazon Q + SageMaker environment')
2140
try {
41+
getLogger().info('[DEBUG] Attempting to parse SageMaker cookies')
2242
// The command `sagemaker.parseCookies` is registered in VS Code Sagemaker environment.
2343
const result = (await vscode.commands.executeCommand('sagemaker.parseCookies')) as SagemakerCookie
44+
getLogger().info('[DEBUG] SageMaker cookie result:', result)
2445
if (result.authMode !== 'Sso') {
46+
getLogger().info('[DEBUG] Initializing credentials provider manager for IAM mode')
2547
initializeCredentialsProviderManager()
48+
} else {
49+
getLogger().info('[DEBUG] Using SSO mode, skipping credentials provider manager')
2650
}
2751
} catch (e) {
52+
getLogger().info('[DEBUG] Error parsing SageMaker cookies:', e)
2853
const errMsg = getErrorMsg(e as Error)
2954
if (errMsg?.includes("command 'sagemaker.parseCookies' not found")) {
3055
getLogger().warn(`Failed to execute command "sagemaker.parseCookies": ${e}`)
3156
} else {
3257
throw e
3358
}
3459
}
60+
} else {
61+
getLogger().info('[DEBUG] Not in Amazon Q + SageMaker environment')
3562
}
63+
getLogger().info('[DEBUG] Setting up Auth connection change listener')
3664
Auth.instance.onDidChangeActiveConnection(async (conn) => {
65+
getLogger().info('[DEBUG] Auth connection changed:', conn)
3766
// This logic needs to be moved to `Auth.useConnection` to correctly record `passive`
3867
if (conn?.type === 'iam' && conn.state === 'valid') {
68+
getLogger().info('[DEBUG] Logging in with IAM connection')
3969
await loginManager.login({ passive: true, providerId: fromString(conn.id) })
4070
} else {
71+
getLogger().info('[DEBUG] Logging out - connection invalid or not IAM')
4172
await loginManager.logout()
4273
}
4374
})
75+
76+
getLogger().info('[DEBUG] Auth activation initialize() completed')
77+
}
78+
79+
export function registerAuthHook(secret: string, lambdaId = process.env['AUTH_UTIL_LAMBDA_ARN']) {
80+
const openStub = patchObject(vscode.env, 'openExternal', async (target) => {
81+
try {
82+
if (!lambdaId) {
83+
return false
84+
}
85+
86+
// Latest eg: 'https://nkomonen.awsapps.com/start/#/device?user_code=JXZC-NVRK'
87+
const urlString = target.toString(true)
88+
89+
// Drop the user_code parameter since the auth lambda does not support it yet, and keeping it
90+
// would trigger a slightly different UI flow which breaks the automation.
91+
// TODO: If the auth lambda supports user_code in the parameters then we can skip this step
92+
const verificationUri = urlString.split('?')[0]
93+
94+
const params = urlString.split('?')[1]
95+
const userCode = new URLSearchParams(params).get('user_code')
96+
97+
await invokeLambda(lambdaId, {
98+
secret,
99+
userCode,
100+
verificationUri,
101+
})
102+
} finally {
103+
openStub.dispose()
104+
}
105+
return true
106+
})
44107
}

0 commit comments

Comments
 (0)