Skip to content

Commit ebcee53

Browse files
authored
Add the type of credentials to validate and setCredentials (#2128)
1 parent 1180f70 commit ebcee53

File tree

11 files changed

+75
-26
lines changed

11 files changed

+75
-26
lines changed

core/src/software/aws/toolkits/core/credentials/ToolkitCredentialsProvider.kt

+15-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ package software.aws.toolkits.core.credentials
55

66
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider
77

8+
enum class CredentialType {
9+
StaticProfile,
10+
StaticSessionProfile,
11+
CredentialProcessProfile,
12+
AssumeRoleProfile,
13+
AssumeMfaRoleProfile,
14+
SsoProfile
15+
}
16+
817
/**
918
* Represents a possible credential provider that can be used within the toolkit.
1019
*
@@ -33,13 +42,18 @@ interface CredentialIdentifier {
3342
*/
3443
val factoryId: String
3544

45+
/**
46+
* The type of credential
47+
*/
48+
val credentialType: CredentialType?
49+
3650
/**
3751
* Some ID types (e.g. Profile) have a concept of a default region, this is optional.
3852
*/
3953
val defaultRegionId: String? get() = null
4054
}
4155

42-
abstract class CredentialIdentifierBase : CredentialIdentifier {
56+
abstract class CredentialIdentifierBase(override val credentialType: CredentialType?) : CredentialIdentifier {
4357
final override fun equals(other: Any?): Boolean {
4458
if (this === other) return true
4559
if (javaClass != other?.javaClass) return false

core/tst/software/aws/toolkits/core/credentials/Mocks.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ fun aCredentialsIdentifier(
1717
displayName: String = aString(),
1818
factoryId: String = aString(),
1919
defaultRegionId: String? = null
20-
) = object : CredentialIdentifierBase() {
20+
) = object : CredentialIdentifierBase(CredentialType.StaticProfile) {
2121
override val id: String = id
2222
override val displayName: String = displayName
2323
override val factoryId: String = factoryId

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ coroutinesVersion=1.3.3
1616
ideaPluginVersion=0.4.20
1717
ktlintVersion=0.38.1
1818
jacksonVersion=2.9.8
19-
telemetryVersion=0.0.59
19+
telemetryVersion=0.0.70
2020

2121
assertjVersion=3.15.0
2222
junitVersion=4.12

jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/AwsConnectionManager.kt

+5-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,11 @@ abstract class AwsConnectionManager(private val project: Project) : SimpleModifi
172172
LOGGER.warn(e) { message("credentials.profile.validation_error", credentialsIdentifier.displayName) }
173173
} finally {
174174
incModificationCount()
175-
AwsTelemetry.validateCredentials(project, success = isValidConnectionSettings())
175+
AwsTelemetry.validateCredentials(
176+
project,
177+
success = isValidConnectionSettings(),
178+
credentialType = credentialsIdentifier.credentialType.toTelemetryType()
179+
)
176180
validationJob = null
177181
}
178182
}

jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/ChangeConnectionSettingsMenu.kt

+3
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ internal class ChangeCredentialsAction(private val credentialsProvider: Credenti
184184
override fun setSelected(e: AnActionEvent, state: Boolean) {
185185
if (state) {
186186
getAccountSetting(e).changeCredentialProvider(credentialsProvider)
187+
188+
// Set credentials is not considered passive, so only send it when they are actively changed
189+
AwsTelemetry.setCredentials(e.project, credentialsProvider.credentialType.toTelemetryType())
187190
}
188191
}
189192
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package software.aws.toolkits.jetbrains.core.credentials
5+
6+
import software.aws.toolkits.core.credentials.CredentialType
7+
import software.aws.toolkits.telemetry.CredentialType as TelemetryCredentialType
8+
9+
fun CredentialType?.toTelemetryType(): TelemetryCredentialType = when (this) {
10+
CredentialType.StaticProfile -> TelemetryCredentialType.StaticProfile
11+
CredentialType.StaticSessionProfile -> TelemetryCredentialType.StaticSessionProfile
12+
CredentialType.CredentialProcessProfile -> TelemetryCredentialType.CredentialProcessProfile
13+
CredentialType.AssumeRoleProfile -> TelemetryCredentialType.AssumeRoleProfile
14+
CredentialType.AssumeMfaRoleProfile -> TelemetryCredentialType.AssumeMfaRoleProfile
15+
CredentialType.SsoProfile -> TelemetryCredentialType.SsoProfile
16+
null -> TelemetryCredentialType.Other
17+
}

jetbrains-core/src/software/aws/toolkits/jetbrains/core/credentials/profiles/ProfileCredentialProviderFactory.kt

+27-8
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import software.aws.toolkits.core.ToolkitClientManager
2222
import software.aws.toolkits.core.credentials.CredentialIdentifier
2323
import software.aws.toolkits.core.credentials.CredentialIdentifierBase
2424
import software.aws.toolkits.core.credentials.CredentialProviderFactory
25+
import software.aws.toolkits.core.credentials.CredentialType
2526
import software.aws.toolkits.core.credentials.CredentialsChangeEvent
2627
import software.aws.toolkits.core.credentials.CredentialsChangeListener
2728
import software.aws.toolkits.core.credentials.sso.SSO_ACCOUNT
@@ -51,22 +52,24 @@ const val DEFAULT_PROFILE_ID = "profile:default"
5152

5253
private const val PROFILE_FACTORY_ID = "ProfileCredentialProviderFactory"
5354

54-
private open class ProfileCredentialsIdentifier(val profileName: String, override val defaultRegionId: String?) : CredentialIdentifierBase() {
55+
private open class ProfileCredentialsIdentifier(val profileName: String, override val defaultRegionId: String?, credentialType: CredentialType?) :
56+
CredentialIdentifierBase(credentialType) {
5557
override val id = "profile:$profileName"
5658
override val displayName = message("credentials.profile.name", profileName)
5759
override val factoryId = PROFILE_FACTORY_ID
5860
override val shortName: String = profileName
5961
}
6062

61-
private class ProfileCredentialsIdentifierMfa(profileName: String, defaultRegionId: String?) :
62-
ProfileCredentialsIdentifier(profileName, defaultRegionId), MfaRequiredInteractiveCredentials
63+
private class ProfileCredentialsIdentifierMfa(profileName: String, defaultRegionId: String?, credentialType: CredentialType?) :
64+
ProfileCredentialsIdentifier(profileName, defaultRegionId, credentialType), MfaRequiredInteractiveCredentials
6365

6466
private class ProfileCredentialsIdentifierSso(
6567
profileName: String,
6668
defaultRegionId: String?,
6769
override val ssoCache: SsoCache,
68-
override val ssoUrl: String
69-
) : ProfileCredentialsIdentifier(profileName, defaultRegionId),
70+
override val ssoUrl: String,
71+
credentialType: CredentialType?
72+
) : ProfileCredentialsIdentifier(profileName, defaultRegionId, credentialType),
7073
SsoRequiredInteractiveCredentials
7174

7275
class ProfileCredentialProviderFactory : CredentialProviderFactory {
@@ -317,16 +320,18 @@ class ProfileCredentialProviderFactory : CredentialProviderFactory {
317320
private fun Profile.asId(profiles: Map<String, Profile>): ProfileCredentialsIdentifier {
318321
val name = this.name()
319322
val defaultRegion = this.properties()[ProfileProperty.REGION]
323+
val requestedProfileType = this.toCredentialType()
320324

321325
return when {
322-
this.requiresMfa(profiles) -> ProfileCredentialsIdentifierMfa(name, defaultRegion)
326+
this.requiresMfa(profiles) -> ProfileCredentialsIdentifierMfa(name, defaultRegion, requestedProfileType)
323327
this.requiresSso(profiles) -> ProfileCredentialsIdentifierSso(
324328
name,
325329
defaultRegion,
326330
diskCache,
327-
this.requiredProperty(SSO_URL)
331+
this.requiredProperty(SSO_URL),
332+
requestedProfileType
328333
)
329-
else -> ProfileCredentialsIdentifier(name, defaultRegion)
334+
else -> ProfileCredentialsIdentifier(name, defaultRegion, requestedProfileType)
330335
}
331336
}
332337

@@ -337,6 +342,20 @@ class ProfileCredentialProviderFactory : CredentialProviderFactory {
337342
.any { it.propertyExists(SSO_URL) }
338343
}
339344

345+
private fun Profile.toCredentialType(): CredentialType? = when {
346+
this.propertyExists(SSO_URL) -> CredentialType.SsoProfile
347+
this.propertyExists(ProfileProperty.ROLE_ARN) -> {
348+
if (this.propertyExists(ProfileProperty.MFA_SERIAL))
349+
CredentialType.AssumeMfaRoleProfile
350+
else
351+
CredentialType.AssumeRoleProfile
352+
}
353+
this.propertyExists(ProfileProperty.AWS_SESSION_TOKEN) -> CredentialType.StaticSessionProfile
354+
this.propertyExists(ProfileProperty.AWS_ACCESS_KEY_ID) -> CredentialType.StaticProfile
355+
this.propertyExists(ProfileProperty.CREDENTIAL_PROCESS) -> CredentialType.CredentialProcessProfile
356+
else -> null
357+
}
358+
340359
private class ProfileHolder {
341360
private val profiles = mutableMapOf<String, Profile>()
342361

jetbrains-core/src/software/aws/toolkits/jetbrains/services/cloudformation/stack/Stack.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class StackWindowManager(private val project: Project) {
4242
fun openStack(stackName: String, stackId: String) {
4343
assert(SwingUtilities.isEventDispatchThread())
4444
toolWindow.find(stackId)?.run { show() } ?: StackUI(project, stackName, stackId, toolWindow).start()
45-
CloudformationTelemetry.open(project)
45+
CloudformationTelemetry.open(project, success = true)
4646
}
4747

4848
companion object {

jetbrains-core/tst/software/aws/toolkits/jetbrains/core/credentials/CredentialManagerTest.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ class CredentialManagerTest {
277277
override val factoryId: String,
278278
override val defaultRegionId: String,
279279
val credentialsEchoField: String? = null
280-
) : CredentialIdentifierBase() {
280+
) : CredentialIdentifierBase(null) {
281281
override val displayName: String = "$factoryId:$id"
282282
}
283283
}

jetbrains-core/tst/software/aws/toolkits/jetbrains/core/credentials/MockCredentialsManager.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class MockCredentialsManager : CredentialManager() {
7070
}
7171

7272
class MockCredentialIdentifier(override val displayName: String, val credentials: AwsCredentialsProvider, override val defaultRegionId: String?) :
73-
CredentialIdentifierBase() {
73+
CredentialIdentifierBase(null) {
7474
override val id: String = displayName
7575
override val factoryId: String = "mockCredentialProviderFactory"
7676
}

jetbrains-core/tst/software/aws/toolkits/jetbrains/ui/ResourceSelectorTest.kt

+3-11
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ import com.nhaarman.mockitokotlin2.mock
99
import org.assertj.core.api.Assertions.assertThat
1010
import org.junit.Rule
1111
import org.junit.Test
12-
import software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider
13-
import software.aws.toolkits.core.credentials.CredentialIdentifierBase
14-
import software.aws.toolkits.core.credentials.ToolkitCredentialsProvider
12+
import software.aws.toolkits.core.credentials.aCredentialsIdentifier
13+
import software.aws.toolkits.core.credentials.aToolkitCredentialsProvider
1514
import software.aws.toolkits.core.region.AwsRegion
1615
import software.aws.toolkits.core.utils.test.retryableAssert
1716
import software.aws.toolkits.jetbrains.core.MockResourceCacheRule
@@ -238,13 +237,6 @@ class ResourceSelectorTest {
238237
}
239238

240239
private companion object {
241-
fun mockCred(id: String) = ToolkitCredentialsProvider(
242-
object : CredentialIdentifierBase() {
243-
override val id: String = id
244-
override val displayName: String = id
245-
override val factoryId: String = "mockFactory"
246-
},
247-
AnonymousCredentialsProvider.create()
248-
)
240+
fun mockCred(id: String) = aToolkitCredentialsProvider(aCredentialsIdentifier(id))
249241
}
250242
}

0 commit comments

Comments
 (0)