Skip to content

Commit eee6aba

Browse files
authored
Merge pull request #2315 from digma-ai/auth-improvements
auth improvements
2 parents eb91a15 + 2b669dc commit eee6aba

File tree

8 files changed

+166
-68
lines changed

8 files changed

+166
-68
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ tasks {
290290
"idea.log.limit" to "999999999",
291291
"idea.trace.stub.index.update" to "true",
292292
"org.digma.plugin.enable.devtools" to "true",
293+
"kotlinx.coroutines.debug" to "",
293294

294295
// "idea.ProcessCanceledException" to "disabled"
295296

ide-common/src/main/kotlin/org/digma/intellij/plugin/analytics/AnalyticsUrlProvider.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class AnalyticsUrlProvider : DisposableAdaptor, BaseUrlProvider {
3939

4040
if (state.apiUrl != myApiUrl) {
4141
Log.log(logger::trace, "api url changed to {}, replacing myApiUrl", state.apiUrl)
42+
AuthManager.getInstance().stopAutoRefresh("on api url changed")
4243
AuthManager.getInstance().logoutSynchronously()
4344
ThreadPoolProviderService.getInstance().interruptAll()
4445
val oldUrl = myApiUrl
@@ -48,6 +49,7 @@ class AnalyticsUrlProvider : DisposableAdaptor, BaseUrlProvider {
4849
fireUrlChangedEvent(oldUrl, myApiUrl)
4950
//after clients replaced do loginOrRefresh
5051
AuthManager.getInstance().loginOrRefreshAsync()
52+
AuthManager.getInstance().startAutoRefresh()
5153
doForAllProjects { project ->
5254
project.messageBus.syncPublisher(ApiClientChangedEvent.API_CLIENT_CHANGED_TOPIC).apiClientChanged(myApiUrl)
5355
}

ide-common/src/main/kotlin/org/digma/intellij/plugin/analytics/ApiErrorHandler.kt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import com.intellij.openapi.project.ProjectManager
88
import com.intellij.util.Alarm
99
import org.digma.intellij.plugin.common.DisposableAdaptor
1010
import org.digma.intellij.plugin.common.EDT
11+
import org.digma.intellij.plugin.common.ExceptionUtils
1112
import org.digma.intellij.plugin.common.ExceptionUtils.findConnectException
1213
import org.digma.intellij.plugin.common.ExceptionUtils.findFirstRealExceptionCause
1314
import org.digma.intellij.plugin.common.ExceptionUtils.findSslException
@@ -196,7 +197,7 @@ class ApiErrorHandler : DisposableAdaptor {
196197

197198

198199
//AuthManager doesn't always have a project, only on startup when calling withAuth
199-
fun handleAuthManagerError(throwable: Throwable, project: Project?) {
200+
fun handleAuthManagerCantConnectError(throwable: Throwable, project: Project?) {
200201
try {
201202
myLock.lock()
202203
handleAuthManagerErrorImpl(throwable, project)
@@ -210,6 +211,26 @@ class ApiErrorHandler : DisposableAdaptor {
210211
}
211212
}
212213

214+
fun handleAuthManagerCantRefreshError(throwable: Throwable, project: Project?) {
215+
//todo: currently only reporting
216+
Log.warnWithException(logger, throwable, "error in AuthManager {}", throwable)
217+
218+
val message = if (throwable is AuthenticationException) {
219+
throwable.message
220+
} else {
221+
ExceptionUtils.getNonEmptyMessage(throwable)
222+
}
223+
224+
doForAllProjects { p ->
225+
EDT.ensureEDT {
226+
NotificationUtil.notifyWarning(
227+
project, "<html>Error with Digma backend " + message + ".<br> "
228+
+ message + ".<br> See logs for details."
229+
)
230+
}
231+
}
232+
}
233+
213234

214235
//called from auth manager when it can't create a login handler which is a critical error.
215236
// we want to show no connection anyway to notify the user that we can't login or refresh the token. there is no way for

ide-common/src/main/kotlin/org/digma/intellij/plugin/auth/AuthManager.kt

Lines changed: 105 additions & 46 deletions
Large diffs are not rendered by default.

ide-common/src/main/kotlin/org/digma/intellij/plugin/auth/account/AbstractLoginHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ abstract class AbstractLoginHandler(protected val analyticsProvider: RestAnalyti
9292
reportPosthogEvent("refresh failed", mapOf("error" to errorMessage))
9393
}
9494

95-
false
95+
throw e
9696
}
9797
}
9898

ide-common/src/main/kotlin/org/digma/intellij/plugin/auth/account/CentralizedLoginHandler.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,10 @@ class CentralizedLoginHandler(analyticsProvider: RestAnalyticsProvider) : Abstra
9090
val errorMessage = ExceptionUtils.getNonEmptyMessage(e)
9191
reportPosthogEvent("loginOrRefresh failed", mapOf("error" to errorMessage))
9292

93-
//if got exception here it may be from refresh or login, in both cases delete the current account,
94-
//and user will be redirected to log in again
93+
//if got exception here then we probably can't refresh,logout, user will be redirected to login,
94+
// throw the exception to report it
9595
logout()
96-
97-
false
96+
throw e
9897
}
9998

10099
}

ide-common/src/main/kotlin/org/digma/intellij/plugin/auth/account/LocalLoginHandler.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,10 @@ class LocalLoginHandler(analyticsProvider: RestAnalyticsProvider) : AbstractLogi
116116
val errorMessage = ExceptionUtils.getNonEmptyMessage(e)
117117
reportPosthogEvent("loginOrRefresh failed", mapOf("error" to errorMessage))
118118

119-
//if got exception here it may be from refresh or login, in both cases delete the current account,
120-
//we'll do a silent login again
119+
//if got exception here it may be from refresh or login, in both cases delete the current account
120+
//and login again
121121
logout()
122+
login(SILENT_LOGIN_USER, SILENT_LOGIN_PASSWORD)
122123

123124
false
124125
}

ide-common/src/main/kotlin/org/digma/intellij/plugin/auth/account/LoginHandler.kt

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package org.digma.intellij.plugin.auth.account
33
import com.intellij.openapi.diagnostic.Logger
44
import com.intellij.openapi.project.Project
55
import kotlinx.coroutines.CoroutineName
6+
import kotlinx.coroutines.sync.Mutex
7+
import kotlinx.coroutines.sync.withLock
68
import org.digma.intellij.plugin.analytics.ApiErrorHandler
79
import org.digma.intellij.plugin.analytics.ReplacingClientException
810
import org.digma.intellij.plugin.analytics.RestAnalyticsProvider
@@ -22,6 +24,8 @@ interface LoginHandler {
2224

2325
private val logger: Logger = Logger.getInstance(this::class.java)
2426

27+
private val mutex = Mutex()
28+
2529
fun createLoginHandler(analyticsProvider: RestAnalyticsProvider): LoginHandler {
2630
return createLoginHandler(null, analyticsProvider)
2731
}
@@ -51,7 +55,7 @@ interface LoginHandler {
5155

5256
//if we can't create a login handler we assume there is a connection issue, it may be a real connect issue,
5357
// or any other issue were we can't get analyticsProvider.about
54-
ApiErrorHandler.getInstance().handleAuthManagerError(e, project)
58+
ApiErrorHandler.getInstance().handleAuthManagerCantConnectError(e, project)
5559

5660
Log.warnWithException(logger, e, "Exception in createLoginHandler {}, url {}", e, analyticsProvider.apiUrl)
5761
ErrorReporter.getInstance().reportError("AuthManager.createLoginHandler", e)
@@ -65,15 +69,22 @@ interface LoginHandler {
6569

6670
suspend fun login(user: String, password: String): LoginResult
6771

68-
//does login or refresh if necessary, return true if did successful login or successful refresh,
69-
// or when no need to do anything. return false if failed.
70-
//we don't really rely on the returned value, mostly for logging
71-
//todo: can be true always because its called only from onAuthenticationException
72+
/**
73+
* does login or refresh if necessary, return true if did successful login or successful refresh,or did nothing because credentials are valid.
74+
* false otherwise.
75+
* don't rely on the result for authentication purposes, its mainly for logging
76+
*/
7277
suspend fun loginOrRefresh(onAuthenticationError: Boolean = false): Boolean
7378

79+
/**
80+
* return true if refresh was successful
81+
*/
7482
suspend fun refresh(account: DigmaAccount, credentials: DigmaCredentials): Boolean
7583

7684

85+
/**
86+
* return true only if an account was really deleted
87+
*/
7788
suspend fun logout(): Boolean {
7889
return try {
7990
trace("logout called")
@@ -104,21 +115,25 @@ interface LoginHandler {
104115
suspend fun updateAccount(digmaAccount: DigmaAccount, digmaCredentials: DigmaCredentials) {
105116
trace("updating account {}", digmaAccount)
106117
//this is the only place we update the account and credentials.
107-
DigmaAccountManager.getInstance().updateAccount(digmaAccount, digmaCredentials)
108-
DigmaDefaultAccountHolder.getInstance().account = digmaAccount
109-
CredentialsHolder.digmaCredentials = digmaCredentials
118+
mutex.withLock {
119+
DigmaAccountManager.getInstance().updateAccount(digmaAccount, digmaCredentials)
120+
DigmaDefaultAccountHolder.getInstance().account = digmaAccount
121+
CredentialsHolder.digmaCredentials = digmaCredentials
122+
}
110123
}
111124

112125

113126
suspend fun deleteAccount(digmaAccount: DigmaAccount) {
114127
trace("deleting account {}", digmaAccount)
115128
//this is the only place we delete the account.
116-
try {
117-
DigmaAccountManager.getInstance().removeAccount(digmaAccount)
118-
} finally {
119-
//it's in finally because even if removeAccount failed we want to delete the account and nullify CredentialsHolder.digmaCredentials
120-
DigmaDefaultAccountHolder.getInstance().account = null
121-
CredentialsHolder.digmaCredentials = null
129+
mutex.withLock {
130+
try {
131+
DigmaAccountManager.getInstance().removeAccount(digmaAccount)
132+
} finally {
133+
//it's in finally because even if removeAccount failed we want to delete the account and nullify CredentialsHolder.digmaCredentials
134+
DigmaDefaultAccountHolder.getInstance().account = null
135+
CredentialsHolder.digmaCredentials = null
136+
}
122137
}
123138
}
124139

0 commit comments

Comments
 (0)