Skip to content

Commit 45044da

Browse files
samgst-amazonrli
authored andcommitted
Update telemetry: emit auth scopes in user state (aws#4944)
* add authScopes to emitUserState telemetry * add authScopes to emitUserState telemetry * Replace userState function with direct TelemetryService record function to capture authScopes * add value parameter * fix whitespace * Update plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/gettingstarted/GettingStartedAuthUtils.kt Co-authored-by: Richard Li <[email protected]> * Check current explorerConnection for scopes only * Add function to grab scopes from each activeConnection used that is connected/expired. * remove TelemetryOverride definition and use common's telemetry function instead * remove unused imports * Change the way explorer connection scope is checked * remove check for CodeWhispererConnection: merged into qConnection & qScopes * add common logic to one function * Update telemetryOverride.json missed { --------- Co-authored-by: Richard Li <[email protected]>
1 parent 6a3d599 commit 45044da

File tree

4 files changed

+105
-62
lines changed

4 files changed

+105
-62
lines changed

plugins/core/jetbrains-community/resources/telemetryOverride.json

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -755,25 +755,6 @@
755755
],
756756
"passive": true
757757
},
758-
{
759-
"name": "auth_userState",
760-
"description": "The state of the user's authentication.",
761-
"metadata": [
762-
{
763-
"type": "source",
764-
"required": true
765-
},
766-
{
767-
"type": "authStatus",
768-
"required": true
769-
},
770-
{
771-
"type": "authEnabledConnections",
772-
"required": true
773-
}
774-
],
775-
"passive": true
776-
},
777758
{
778759
"name": "webview_amazonqSignInOpened",
779760
"description": "Called when a Amazon Q sign in webview is opened.",

plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/gettingstarted/GettingStartedAuthUtils.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection
1616
import software.aws.toolkits.jetbrains.core.credentials.reauthConnectionIfNeeded
1717
import software.aws.toolkits.jetbrains.core.credentials.sono.Q_SCOPES
1818
import software.aws.toolkits.jetbrains.core.gettingstarted.editor.SourceOfEntry
19+
import software.aws.toolkits.jetbrains.core.gettingstarted.editor.getAuthScopes
1920
import software.aws.toolkits.jetbrains.core.gettingstarted.editor.getAuthStatus
2021
import software.aws.toolkits.jetbrains.core.gettingstarted.editor.getConnectionCount
2122
import software.aws.toolkits.jetbrains.core.gettingstarted.editor.getEnabledConnections
@@ -238,10 +239,10 @@ fun reauthenticateWithQ(project: Project) {
238239
fun emitUserState(project: Project) {
239240
AuthTelemetry.userState(
240241
project,
241-
source = getStartupState().toString(),
242242
authEnabledConnections = getEnabledConnections(project),
243+
authScopes = getAuthScopes(project),
243244
authStatus = getAuthStatus(project),
244-
passive = true
245+
source = getStartupState().toString()
245246
)
246247
}
247248

plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/gettingstarted/editor/GettingStartedPanelUtils.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package software.aws.toolkits.jetbrains.core.gettingstarted.editor
66
import com.intellij.openapi.project.Project
77
import com.intellij.ui.dsl.builder.Panel
88
import software.aws.toolkits.core.credentials.CredentialIdentifier
9+
import software.aws.toolkits.core.credentials.CredentialType
910
import software.aws.toolkits.jetbrains.core.credentials.AwsBearerTokenConnection
1011
import software.aws.toolkits.jetbrains.core.credentials.AwsConnectionManager
1112
import software.aws.toolkits.jetbrains.core.credentials.ConnectionState
@@ -115,6 +116,20 @@ fun checkIamConnectionValidity(project: Project): ActiveConnection {
115116
}
116117
}
117118

119+
fun checkIamProfileByCredentialType(project: Project): ActiveConnection {
120+
val currConn = AwsConnectionManager.getInstance(project).selectedCredentialIdentifier ?: return ActiveConnection.NotConnected
121+
val invalidConnection = AwsConnectionManager.getInstance(project).connectionState.let { it.isTerminal && it !is ConnectionState.ValidConnection }
122+
val connectionType = when (currConn.credentialType) {
123+
CredentialType.SsoProfile -> ActiveConnectionType.IAM_IDC
124+
else -> ActiveConnectionType.IAM
125+
}
126+
return if (invalidConnection) {
127+
ActiveConnection.ExpiredIam(connectionType = connectionType, activeConnectionIam = currConn)
128+
} else {
129+
ActiveConnection.ValidIam(connectionType = connectionType, activeConnectionIam = currConn)
130+
}
131+
}
132+
118133
/**
119134
* Finds the first valid [ActiveConnection] and returns it.
120135
*
@@ -146,6 +161,7 @@ fun checkConnectionValidity(project: Project): ActiveConnection {
146161
return result
147162
}
148163

164+
@Deprecated("Does not work for current config file setup. Old versions still utilize this logic.")
149165
fun isCredentialSso(providerId: String): ActiveConnectionType {
150166
val profileName = providerId.split("-").first()
151167
val ssoSessionIds = CredentialManager.getInstance().getSsoSessionIdentifiers().map {

plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/gettingstarted/editor/GettingStartedTelemetryUtils.kt

Lines changed: 86 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import software.aws.toolkits.core.utils.tryOrNull
1010
import software.aws.toolkits.jetbrains.core.credentials.CredentialManager
1111
import software.aws.toolkits.jetbrains.core.credentials.ToolkitAuthManager
1212
import software.aws.toolkits.jetbrains.core.credentials.profiles.ProfileCredentialsIdentifierSso
13+
import software.aws.toolkits.jetbrains.core.credentials.sono.IDENTITY_CENTER_ROLE_ACCESS_SCOPE
1314
import software.aws.toolkits.jetbrains.settings.AwsSettings
1415
import software.aws.toolkits.telemetry.AuthStatus
1516
import software.aws.toolkits.telemetry.StartUpState
@@ -22,54 +23,66 @@ fun getConnectionCount(): Long {
2223

2324
fun getEnabledConnectionsForTelemetry(project: Project?): Set<AuthFormId> {
2425
project ?: return emptySet()
25-
val enabledConnections = mutableSetOf<AuthFormId>()
26-
27-
val explorerConnection = checkIamConnectionValidity(project)
28-
if (explorerConnection !is ActiveConnection.NotConnected) {
29-
if (explorerConnection.connectionType == ActiveConnectionType.IAM_IDC) {
30-
enabledConnections.add(AuthFormId.IDENTITYCENTER_EXPLORER)
31-
} else {
32-
enabledConnections.add(
33-
AuthFormId.IAMCREDENTIALS_EXPLORER
34-
)
35-
}
36-
}
37-
val codeCatalystConnection = checkBearerConnectionValidity(project, BearerTokenFeatureSet.CODECATALYST)
38-
if (codeCatalystConnection !is ActiveConnection.NotConnected) {
39-
if (codeCatalystConnection.connectionType == ActiveConnectionType.IAM_IDC) {
40-
enabledConnections.add(AuthFormId.IDENTITYCENTER_CODECATALYST)
41-
} else {
42-
enabledConnections.add(AuthFormId.BUILDERID_CODECATALYST)
43-
}
44-
}
26+
val enabledConnections = mutableSetOf<Any>()
4527

46-
val codeWhispererConnection = checkBearerConnectionValidity(project, BearerTokenFeatureSet.CODEWHISPERER)
47-
if (codeWhispererConnection !is ActiveConnection.NotConnected) {
48-
if (codeWhispererConnection.connectionType == ActiveConnectionType.IAM_IDC) {
49-
enabledConnections.add(AuthFormId.IDENTITYCENTER_CODEWHISPERER)
50-
} else {
51-
enabledConnections.add(
52-
AuthFormId.BUILDERID_CODEWHISPERER
53-
)
54-
}
55-
}
28+
addConnectionInfoToSet(
29+
checkIamConnectionValidity(project),
30+
enabledConnections,
31+
AuthFormId.IDENTITYCENTER_EXPLORER,
32+
AuthFormId.IAMCREDENTIALS_EXPLORER
33+
)
5634

57-
val qConnection = checkBearerConnectionValidity(project, BearerTokenFeatureSet.Q)
58-
if (qConnection !is ActiveConnection.NotConnected) {
59-
if (qConnection.connectionType == ActiveConnectionType.IAM_IDC) {
60-
enabledConnections.add(AuthFormId.IDENTITYCENTER_Q)
61-
} else {
62-
enabledConnections.add(
63-
AuthFormId.BUILDERID_Q
64-
)
65-
}
66-
}
67-
return enabledConnections
35+
addConnectionInfoToSet(
36+
checkBearerConnectionValidity(project, BearerTokenFeatureSet.CODECATALYST),
37+
enabledConnections,
38+
AuthFormId.IDENTITYCENTER_CODECATALYST,
39+
AuthFormId.BUILDERID_CODECATALYST
40+
)
41+
42+
addConnectionInfoToSet(
43+
checkBearerConnectionValidity(project, BearerTokenFeatureSet.CODEWHISPERER),
44+
enabledConnections,
45+
AuthFormId.IDENTITYCENTER_CODEWHISPERER,
46+
AuthFormId.BUILDERID_CODEWHISPERER
47+
)
48+
49+
addConnectionInfoToSet(
50+
checkBearerConnectionValidity(project, BearerTokenFeatureSet.Q),
51+
enabledConnections,
52+
AuthFormId.IDENTITYCENTER_Q,
53+
AuthFormId.BUILDERID_Q
54+
)
55+
return enabledConnections.mapTo(mutableSetOf()) { it as AuthFormId }
6856
}
6957

7058
fun getEnabledConnections(project: Project?): String =
7159
getEnabledConnectionsForTelemetry(project).joinToString(",")
7260

61+
fun getAuthScopesForTelemetry(project: Project?): Set<String> {
62+
project ?: return emptySet()
63+
val scopes = mutableSetOf<Any>()
64+
65+
val explorerConnection = checkIamProfileByCredentialType(project)
66+
if (explorerConnection !is ActiveConnection.NotConnected && explorerConnection.connectionType == ActiveConnectionType.IAM_IDC) {
67+
scopes.add(IDENTITY_CENTER_ROLE_ACCESS_SCOPE)
68+
}
69+
70+
addConnectionInfoToSet(
71+
checkBearerConnectionValidity(project, BearerTokenFeatureSet.CODECATALYST),
72+
dataSet = scopes
73+
)
74+
75+
addConnectionInfoToSet(
76+
checkBearerConnectionValidity(project, BearerTokenFeatureSet.Q),
77+
dataSet = scopes
78+
)
79+
80+
return scopes.mapTo(mutableSetOf()) { it as String }
81+
}
82+
83+
fun getAuthScopes(project: Project?): String =
84+
getAuthScopesForTelemetry(project).joinToString(",")
85+
7386
fun getStartupState(): StartUpState {
7487
val hasStartedToolkitBefore = tryOrNull {
7588
getPersistentStateComponentStorageLocation(AwsSettings::class.java)?.exists()
@@ -87,6 +100,38 @@ fun getAuthStatus(project: Project) = when (checkConnectionValidity(project)) {
87100
else -> AuthStatus.NotConnected
88101
}
89102

103+
fun addConnectionInfoToSet(
104+
activeConnection: ActiveConnection,
105+
dataSet: MutableSet<Any>,
106+
idcConnection: AuthFormId? = null,
107+
defaultConnection: AuthFormId? = null,
108+
) {
109+
if (activeConnection is ActiveConnection.NotConnected) {
110+
return
111+
}
112+
113+
// add enabled connections
114+
when (activeConnection.connectionType) {
115+
ActiveConnectionType.IAM_IDC -> {
116+
idcConnection ?.let {
117+
dataSet.add(idcConnection)
118+
return
119+
}
120+
} else -> {
121+
defaultConnection?.let {
122+
dataSet.add(defaultConnection)
123+
return
124+
}
125+
}
126+
}
127+
128+
// add scopes
129+
val connectionScopes = activeConnection.activeConnectionBearer?.scopes
130+
if (!connectionScopes.isNullOrEmpty()) {
131+
dataSet.addAll(connectionScopes)
132+
}
133+
}
134+
90135
enum class AuthFormId {
91136
IAMCREDENTIALS_EXPLORER,
92137
IDENTITYCENTER_EXPLORER,

0 commit comments

Comments
 (0)