Skip to content

Commit fc22c17

Browse files
Merge master into feature/emr
2 parents 5fee09d + 4a27d8b commit fc22c17

File tree

5 files changed

+41
-13
lines changed

5 files changed

+41
-13
lines changed

packages/amazonq/test/unit/codewhisperer/util/authUtil.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,11 @@ describe('AuthUtil', async function () {
233233
// Switch to unsupported connection
234234
const cwAuthUpdatedConnection = captureEventOnce(authUtil.secondaryAuth.onDidChangeActiveConnection)
235235
await auth.useConnection(unsupportedConn)
236+
// This is triggered when the main Auth connection is switched
236237
await cwAuthUpdatedConnection
238+
// This is triggered by registerAuthListener() when it saves the previous active connection as a fallback.
239+
// TODO in a refactor see if we can simplify multiple multiple triggers on the same event.
240+
await captureEventOnce(authUtil.secondaryAuth.onDidChangeActiveConnection)
237241

238242
// Is using the fallback connection
239243
assert.ok(authUtil.isConnected())

packages/core/src/auth/auth.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1022,9 +1022,20 @@ export class Auth implements AuthService, ConnectionManager {
10221022
}
10231023
}
10241024

1025+
/**
1026+
* Auth uses its own state, separate from the default {@link globalState}
1027+
* that is normally used throughout the codebase.
1028+
*
1029+
* IMPORTANT: Anything involving auth should ONLY use this state since the state
1030+
* can vary on certain conditions. So if you see something explicitly using
1031+
* globalState verify if it should actually be using that.
1032+
*/
1033+
public getStateMemento: () => vscode.Memento = () => Auth._getStateMemento()
1034+
private static _getStateMemento = once(() => getEnvironmentSpecificMemento())
1035+
10251036
static #instance: Auth | undefined
10261037
public static get instance() {
1027-
return (this.#instance ??= new Auth(new ProfileStore(getEnvironmentSpecificMemento())))
1038+
return (this.#instance ??= new Auth(new ProfileStore(Auth._getStateMemento())))
10281039
}
10291040

10301041
private getSsoProfileLabel(profile: SsoProfile) {

packages/core/src/auth/secondaryAuth.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
import globals from '../shared/extensionGlobals'
7-
86
import * as vscode from 'vscode'
97
import { getLogger } from '../shared/logger'
108
import { cast, Optional } from '../shared/utilities/typeConstructors'
@@ -18,6 +16,7 @@ import { AuthStatus, telemetry } from '../shared/telemetry/telemetry'
1816
import { asStringifiedStack } from '../shared/telemetry/spans'
1917
import { withTelemetryContext } from '../shared/telemetry/util'
2018
import { isNetworkError } from '../shared/errors'
19+
import globals from '../shared/extensionGlobals'
2120

2221
export type ToolId = 'codecatalyst' | 'codewhisperer' | 'testId'
2322

@@ -214,10 +213,14 @@ export class SecondaryAuth<T extends Connection = Connection> {
214213
return !!this.activeConnection && this.auth.getConnectionState(this.activeConnection) === 'invalid'
215214
}
216215

216+
public get state() {
217+
return this.auth.getStateMemento()
218+
}
219+
217220
public async saveConnection(conn: T) {
218221
// TODO: fix this
219222
// eslint-disable-next-line aws-toolkits/no-banned-usages
220-
await globals.context.globalState.update(this.key, conn.id)
223+
await this.state.update(this.key, conn.id)
221224
this.#savedConnection = conn
222225
this.#onDidChangeActiveConnection.fire(this.activeConnection)
223226
}
@@ -251,7 +254,7 @@ export class SecondaryAuth<T extends Connection = Connection> {
251254
public async clearSavedConnection() {
252255
// TODO: fix this
253256
// eslint-disable-next-line aws-toolkits/no-banned-usages
254-
await globals.context.globalState.update(this.key, undefined)
257+
await this.state.update(this.key, undefined)
255258
this.#savedConnection = undefined
256259
this.#onDidChangeActiveConnection.fire(this.activeConnection)
257260
}
@@ -326,9 +329,6 @@ export class SecondaryAuth<T extends Connection = Connection> {
326329
* Provides telemetry if called by restoreConnection() (or another auth_modifyConnection context)
327330
*/
328331
private async _loadSavedConnection() {
329-
// TODO: fix this
330-
// eslint-disable-next-line aws-toolkits/no-banned-usages
331-
const globalState = globals.context.globalState
332332
const id = this.getStateConnectionId()
333333
if (id === undefined) {
334334
return
@@ -337,10 +337,10 @@ export class SecondaryAuth<T extends Connection = Connection> {
337337
const conn = await this.auth.getConnection({ id })
338338
if (conn === undefined) {
339339
getLogger().warn(`auth (${this.toolId}): removing saved connection "${this.key}" as it no longer exists`)
340-
await globalState.update(this.key, undefined)
340+
await this.state.update(this.key, undefined)
341341
} else if (!this.isUsable(conn)) {
342342
getLogger().warn(`auth (${this.toolId}): saved connection "${this.key}" is not valid`)
343-
await globalState.update(this.key, undefined)
343+
await this.state.update(this.key, undefined)
344344
} else {
345345
const getAuthStatus = (state: ReturnType<typeof this.auth.getConnectionState>): AuthStatus => {
346346
return state === 'invalid' ? 'expired' : 'connected'
@@ -377,7 +377,7 @@ export class SecondaryAuth<T extends Connection = Connection> {
377377
}
378378

379379
private getStateConnectionId() {
380-
return cast(globals.globalState.get(this.key), Optional(String))
380+
return cast(this.state.get(this.key), Optional(String))
381381
}
382382
}
383383

packages/core/src/shared/utilities/mementos.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,14 @@ export function partition(memento: vscode.Memento, key: string): vscode.Memento
2929
}
3030
}
3131

32-
/** Avoids sharing globalState with remote vscode instances. */
32+
/**
33+
* Resolves the appropriate memento/state for the current runtime environment.
34+
*
35+
* Why?
36+
* - In remote instances where we ssh in to them, we do not always want to share
37+
* with the local globalState. We want certain functionality to be isolated to
38+
* the remote instance.
39+
*/
3340
export function getEnvironmentSpecificMemento(): vscode.Memento {
3441
if (!vscode.env.remoteName) {
3542
// local compute: no further partitioning

packages/core/src/test/credentials/secondaryAuth.test.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { createBuilderIdProfile, createTestAuth } from './testUtil'
99
import { Connection, createSsoProfile, hasScopes, isSsoConnection } from '../../auth/connection'
1010
import assert from 'assert'
1111
import globals from '../../shared/extensionGlobals'
12+
import { waitUntil } from '../../shared/utilities/timeoutUtils'
1213

1314
describe('SecondaryAuth', function () {
1415
let auth: ReturnType<typeof createTestAuth>
@@ -100,8 +101,13 @@ describe('SecondaryAuth', function () {
100101
// delete SecondaryAuth
101102
await auth.deleteConnection(conn)
102103

104+
// currently both Auth onDidChangeConnectionState and onDidDeleteConnection trigger
105+
// and we need to wait for both of the callbacks defined through them in SecondaryAuth to complete.
106+
// We know they all completed when SecondaryAuth.onDidChangeActiveConnection has been called twice
107+
await waitUntil(async () => onDidChangeActiveConnection.callCount === 2, { interval: 10, timeout: 10000 })
108+
103109
// we fallback to the PrimaryAuth connection
104-
assert.strictEqual(onDidChangeActiveConnection.called, true)
110+
assert.strictEqual(onDidChangeActiveConnection.callCount, 2)
105111
assert.deepStrictEqual(
106112
{
107113
id: secondaryAuth.activeConnection?.id,

0 commit comments

Comments
 (0)