-
Notifications
You must be signed in to change notification settings - Fork 274
feat(amazonq): Implement aws/credentials/token messages #5410
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
352f368
6500b33
892577f
8e3949f
fb9a2c5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| // Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| package software.aws.toolkits.jetbrains.services.amazonq.lsp.auth | ||
|
|
||
| import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage | ||
| import java.util.concurrent.CompletableFuture | ||
|
|
||
| interface AuthCredentialsService { | ||
| fun updateTokenCredentials(accessToken: String, encrypted: Boolean): CompletableFuture<ResponseMessage> | ||
| fun deleteTokenCredentials(): CompletableFuture<Unit> | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| // Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| package software.aws.toolkits.jetbrains.services.amazonq.lsp.auth | ||
|
|
||
| import com.intellij.openapi.project.Project | ||
| import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage | ||
| import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService | ||
| import software.aws.toolkits.jetbrains.services.amazonq.lsp.encryption.JwtEncryptionManager | ||
| import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.credentials.BearerCredentials | ||
| import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.credentials.UpdateCredentialsPayload | ||
| import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.credentials.UpdateCredentialsPayloadData | ||
| import java.util.concurrent.CompletableFuture | ||
|
|
||
| class DefaultAuthCredentialsService( | ||
| private val project: Project, | ||
| private val encryptionManager: JwtEncryptionManager, | ||
|
Check warning on line 17 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/auth/DefaultAuthCredentialsService.kt
|
||
| ) : AuthCredentialsService { | ||
|
|
||
| override fun updateTokenCredentials(accessToken: String, encrypted: Boolean): CompletableFuture<ResponseMessage> { | ||
| val token = if (encrypted) { | ||
| encryptionManager.decrypt(accessToken) | ||
|
Check warning on line 22 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/auth/DefaultAuthCredentialsService.kt
|
||
| } else { | ||
| accessToken | ||
|
Check warning on line 24 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/auth/DefaultAuthCredentialsService.kt
|
||
| } | ||
|
|
||
| val payload = createUpdateCredentialsPayload(token) | ||
|
Check warning on line 27 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/auth/DefaultAuthCredentialsService.kt
|
||
|
|
||
| return AmazonQLspService.executeIfRunning(project) { server -> | ||
| server.updateTokenCredentials(payload) | ||
| } ?: (CompletableFuture.failedFuture(IllegalStateException("LSP Server not running"))) | ||
|
Check warning on line 31 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/auth/DefaultAuthCredentialsService.kt
|
||
| } | ||
|
|
||
| override fun deleteTokenCredentials(): CompletableFuture<Unit> = | ||
| CompletableFuture<Unit>().also { completableFuture -> | ||
|
Check warning on line 35 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/auth/DefaultAuthCredentialsService.kt
|
||
| AmazonQLspService.executeIfRunning(project) { server -> | ||
| server.deleteTokenCredentials() | ||
| completableFuture.complete(null) | ||
| } ?: completableFuture.completeExceptionally(IllegalStateException("LSP Server not running")) | ||
| } | ||
|
Check warning on line 40 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/auth/DefaultAuthCredentialsService.kt
|
||
|
|
||
| private fun createUpdateCredentialsPayload(token: String): UpdateCredentialsPayload = | ||
| UpdateCredentialsPayload( | ||
| data = encryptionManager.encrypt( | ||
| UpdateCredentialsPayloadData( | ||
| BearerCredentials(token) | ||
|
Check warning on line 46 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/auth/DefaultAuthCredentialsService.kt
|
||
| ) | ||
| ), | ||
| encrypted = true | ||
| ) | ||
|
Check warning on line 50 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/auth/DefaultAuthCredentialsService.kt
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| // Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| package software.aws.toolkits.jetbrains.services.amazonq.lsp.auth | ||
|
|
||
| import com.intellij.openapi.components.serviceIfCreated | ||
| import com.intellij.openapi.project.Project | ||
| import io.mockk.every | ||
| import io.mockk.mockk | ||
| import io.mockk.verify | ||
| import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage | ||
| import org.junit.Before | ||
| import org.junit.Test | ||
| import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLanguageServer | ||
| import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService | ||
| import software.aws.toolkits.jetbrains.services.amazonq.lsp.encryption.JwtEncryptionManager | ||
| import java.util.concurrent.CompletableFuture | ||
|
|
||
| class DefaultAuthCredentialsServiceTest { | ||
| private lateinit var project: Project | ||
| private lateinit var mockLanguageServer: AmazonQLanguageServer | ||
| private lateinit var mockEncryptionManager: JwtEncryptionManager | ||
| private lateinit var sut: DefaultAuthCredentialsService | ||
|
|
||
| @Before | ||
| fun setUp() { | ||
| project = mockk<Project>() | ||
| mockLanguageServer = mockk<AmazonQLanguageServer>() | ||
| mockEncryptionManager = mockk<JwtEncryptionManager>() | ||
| every { mockEncryptionManager.encrypt(any()) } returns "mock-encrypted-data" | ||
|
|
||
| // Mock the service methods on Project | ||
| val mockLspService = mockk<AmazonQLspService>() | ||
| every { project.getService(AmazonQLspService::class.java) } returns mockLspService | ||
| every { project.serviceIfCreated<AmazonQLspService>() } returns mockLspService | ||
|
|
||
| // Mock the LSP service's executeSync method as a suspend function | ||
| every { | ||
| mockLspService.executeSync<CompletableFuture<ResponseMessage>>(any()) | ||
| } coAnswers { | ||
| val func = firstArg<suspend (AmazonQLanguageServer) -> CompletableFuture<ResponseMessage>>() | ||
| func.invoke(mockLanguageServer) | ||
| } | ||
|
|
||
| sut = DefaultAuthCredentialsService(project, this.mockEncryptionManager) | ||
| } | ||
|
|
||
| @Test | ||
| fun `test updateTokenCredentials unencrypted success`() { | ||
| val token = "unencryptedToken" | ||
| val isEncrypted = false | ||
|
|
||
| every { | ||
| mockLanguageServer.updateTokenCredentials(any()) | ||
| } returns CompletableFuture.completedFuture(ResponseMessage()) | ||
|
|
||
| sut.updateTokenCredentials(token, isEncrypted) | ||
|
|
||
| verify(exactly = 0) { | ||
| mockEncryptionManager.decrypt(any()) | ||
| } | ||
| verify(exactly = 1) { | ||
| mockLanguageServer.updateTokenCredentials(any()) | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| fun `test updateTokenCredentials encrypted success`() { | ||
| val encryptedToken = "encryptedToken" | ||
| val decryptedToken = "decryptedToken" | ||
| val isEncrypted = true | ||
|
|
||
| every { mockEncryptionManager.decrypt(encryptedToken) } returns decryptedToken | ||
| every { mockEncryptionManager.encrypt(any()) } returns "mock-encrypted-data" | ||
| every { | ||
| mockLanguageServer.updateTokenCredentials(any()) | ||
| } returns CompletableFuture.completedFuture(ResponseMessage()) | ||
|
|
||
| sut.updateTokenCredentials(encryptedToken, isEncrypted) | ||
|
|
||
| verify(exactly = 1) { mockEncryptionManager.decrypt(encryptedToken) } | ||
| verify(exactly = 1) { mockLanguageServer.updateTokenCredentials(any()) } | ||
| } | ||
|
|
||
| @Test | ||
| fun `test deleteTokenCredentials success`() { | ||
| every { mockLanguageServer.deleteTokenCredentials() } returns CompletableFuture.completedFuture(Unit) | ||
|
|
||
| sut.deleteTokenCredentials() | ||
|
|
||
| verify(exactly = 1) { mockLanguageServer.deleteTokenCredentials() } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
im assuming hooking these up will be a followup?