GoogleCloudPlatform / cloud-code-intellij

Plugin to support the Google Cloud Platform in IntelliJ IDEA - Docs and Issues Repository
Apache License 2.0
320 stars 59 forks source link

If a CDB session has been created, and the user has their rights to the project revoked, we throw an error #229

Closed patflynn closed 8 years ago

patflynn commented 9 years ago

We should handle this gracefully and inform the user they no longer have access to the project.

elharo commented 8 years ago

I think this happens in CloudDebugGlobalPoller.queryServerForBreakpoints

elharo commented 8 years ago

could also happen in CloudDebugProcessStateController.deleteBreakpoint, setBreakpointAsync and ProjectRepositoryValidator.checkSyncStashState

It is probably this last one that happens on app startup, but this can happen anywhere/anytime we call the server.

elharo commented 8 years ago

You can reproduce the problem by going to your accounts page for user@google.com and revoking the permissions for IntelliJ, then trying to use the CloudDebugger.

IntelliJ reports this as an internal error.

at org.jetbrains.ide.PooledThreadExecutor$1$1.run(PooledThreadExecutor.java:55)

[ 162577] ERROR - ea.elysium.GoogleUserModelItem - Exception loading projects for Elliotte Rusty Harold com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized { "code" : 401, "errors" : [ { "domain" : "global", "location" : "Authorization", "locationType" : "header", "message" : "Invalid Credentials", "reason" : "authError", "debugInfo" : "com.google.api.server.core.Fault: ImmutableErrorDefinition{base=INVALID_CREDENTIALS, category=USER_ERROR, cause=com.google.api.server.core.Fault: ImmutableErrorDefinition{base=INVALID_CREDENTIALS, category=USER_ERROR, cause=null, debugInfo=null, domain=global, extendedHelp=null, httpHeaders={}, httpStatus=unauthorized, internalReason=Reason{arguments={}, cause=null, code=null, createdByBackend=false, debugMessage=null, errorProtoCode=null, errorProtoDomain=null, filteredMessage=null, location=null, message=null, unnamedArguments=[]}, location=headers.Authorization, message=Invalid Credentials, reason=authError, rpcCode=401} Invalid Credentials, debugInfo=null, domain=global, extendedHelp=null, httpHeaders={WWW-Authenticate=[Bearer realm=\"https://accounts.google.com/\", error=invalid_token]}, httpStatus=unauthorized, internalReason=Reason{arguments={}, cause=null, code=null, createdByBackend=false, debugMessage=null, errorProtoCode=null, errorProtoDomain=null, filteredMessage=null, location=null, message=null, unnamedArguments=[]}, location=headers.Authorization, message=Invalid Credentials, reason=authError, rpcCode=401} Invalid Credentials\n\tat com.google.api.server.auth.AuthenticatorInterceptor.addChallengeHeader(AuthenticatorInterceptor.java:268)\n\tat com.google.api.server.auth.AuthenticatorInterceptor.processErrorResponse(AuthenticatorInterceptor.java:235)\n\tat com.google.api.server.auth.GaiaMintInterceptor.processErrorResponse(GaiaMintInterceptor.java:744)\n\tat com.google.api.server.core.intercept.AroundInterceptorWrapper.processErrorResponse(AroundInterceptorWrapper.java:28)\n\tat com.google.api.server.stats.StatsBootstrap$InterceptorStatsRecorder.processErrorResponse(StatsBootstrap.java:314)\n\tat com.google.api.server.core.intercept.Interceptions$AroundInterception.handleErrorResponse(Interceptions.java:202)\n\tat com.google.api.server.core.intercept.Interceptions$AroundInterception.invoke(Interceptions.java:151)\n\tat com.google.api.server.core.protocol.http.rest.RestServlet.service(RestServlet.java:123)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:717)\n\tat com.google.api.server.core.protocol.http.ApiServlet.service(ApiServlet.java:51)\n\tat com.google.gse.FilteredServlet$ChainEnd.doFilter(FilteredServlet.java:212)\n\tat com.google.api.server.core.EventIdFilter.doFilter(EventIdFilter.java:49)\n\tat com.google.gse.FilteredServlet$Chain.doFilter(FilteredServlet.java:189)\n\tat com.google.loadbalancer.gslb.backend.ubb.UBBFilter.doFilter(UBBFilter.java:73)\n\tat com.google.gse.FilteredServlet$Chain.doFilter(FilteredServlet.java:189)\n\tat com.google.servlet.testing.ResponseInjectionFilter.doFilter(ResponseInjectionFilter.java:135)\n\tat com.google.gse.FilteredServlet$Chain.doFilter(FilteredServlet.java:189)\n\tat com.google.gse.FilteredServlet.service(FilteredServlet.java:158)\n\tat com.google.gse.internal.HttpConnectionImpl.runServletFromWithinSpan(HttpConnectionImpl.java:947)\n\tat com.google.gse.internal.HttpConnectionImpl.access$000(HttpConnectionImpl.java:75)\n\tat com.google.gse.internal.HttpConnectionImpl$1.runServletFromWithinSpan(HttpConnectionImpl.java:820)\n\tat com.google.gse.GSETraceHelper$TraceableServletRunnable$2.run(GSETraceHelper.java:467)\n\tat com.google.tracing.LocalTraceSpanRunnable.run(LocalTraceSpanRunnable.java:56)\n\tat com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpanBuilder.java:642)\n\tat com.google.gse.GSETraceHelper$TraceableServletRunnable.continueGfeTrace(GSETraceHelper.java:416)\n\tat com.google.gse.GSETraceHelper$TraceableServletRunnable.runWithTracingEnabled(GSETraceHelper.java:371)\n\tat com.google.gse.GSETraceHelper$TraceableServletRunnable.run(GSETraceHelper.java:337)\n\tat com.google.gse.internal.HttpConnectionImpl.runServlet(HttpConnectionImpl.java:822)\n\tat com.google.gse.internal.HttpConnectionImpl.run(HttpConnectionImpl.java:776)\n\tat com.google.gse.internal.DispatchQueueImpl$WorkerThread.run(DispatchQueueImpl.java:387)\nCaused by: com.google.api.server.core.Fault: ImmutableErrorDefinition{base=INVALID_CREDENTIALS, category=USER_ERROR, cause=null, debugInfo=null, domain=global, extendedHelp=null, httpHeaders={}, httpStatus=unauthorized, internalReason=Reason{arguments={}, cause=null, code=null, createdByBackend=false, debugMessage=null, errorProtoCode=null, errorProtoDomain=null, filteredMessage=null, location=null, message=null, unnamedArguments=[]}, location=headers.Authorization, message=Invalid Credentials, reason=authError, rpcCode=401} Invalid Credentials\n\tat com.google.api.server.auth.DefaultAuthenticationProcessor.toFault(DefaultAuthenticationProcessor.java:186)\n\tat com.google.api.server.auth.DefaultAuthenticationProcessor.handleResponse(DefaultAuthenticationProcessor.java:142)\n\tat com.google.api.server.auth.OAuth2AuthenticationProcessor.handleResponse(OAuth2AuthenticationProcessor.java:104)\n\tat com.google.api.server.auth.DefaultAuthenticationProcessor.process(DefaultAuthenticationProcessor.java:86)\n\tat com.google.api.server.auth.OAuth2AuthenticationProcessor.process(OAuth2AuthenticationProcessor.java:158)\n\tat com.google.api.server.auth.GaiaMintApiAuthenticator.authenticate(GaiaMintApiAuthenticator.java:216)\n\tat com.google.api.server.auth.GaiaMintInterceptor.doAuthenticateSingleRequest(GaiaMintInterceptor.java:856)\n\tat com.google.api.server.auth.GaiaMintInterceptor.doAuthenticate(GaiaMintInterceptor.java:667)\n\tat com.google.api.server.auth.AuthenticatorInterceptor.authenticate(AuthenticatorInterceptor.java:374)\n\tat com.google.api.server.auth.GaiaMintInterceptor.authenticate(GaiaMintInterceptor.java:642)\n\tat com.google.api.server.auth.AuthenticatorInterceptor.processRequest(AuthenticatorInterceptor.java:195)\n\tat com.google.api.server.auth.GaiaMintInterceptor.processRequest(GaiaMintInterceptor.java:494)\n\tat com.google.api.server.core.intercept.AroundInterceptorWrapper.processRequest(AroundInterceptorWrapper.java:20)\n\tat com.google.api.server.stats.StatsBootstrap$InterceptorStatsRecorder.processRequest(StatsBootstrap.java:280)\n\tat com.google.api.server.core.intercept.Interceptions$AroundInterception.processRequest(Interceptions.java:159)\n\tat com.google.api.server.core.intercept.Interceptions$AroundInterception.invoke(Interceptions.java:135)\n\t... 23 more\n" } ], "message" : "Invalid Credentials" } at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145) at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113) at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321) at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1056) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469) at com.google.gct.idea.elysium.GoogleUserModelItem.loadUserProjects(GoogleUserModelItem.java:132) at com.google.gct.idea.elysium.GoogleUserModelItem.access$100(GoogleUserModelItem.java:43) at com.google.gct.idea.elysium.GoogleUserModelItem$1.run(GoogleUserModelItem.java:97) at com.intellij.openapi.application.impl.ApplicationImpl$8.run(ApplicationImpl.java:365) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) at java.lang.Thread.run(Thread.java:662) at org.jetbrains.ide.PooledThreadExecutor$1$1.run(PooledThreadExecutor.java:55)

elharo commented 8 years ago

On launch:

[ 5724] WARN - gle.gct.login.GoogleLoginUtils - Error retrieving user information. com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request { "error" : "invalid_grant", "error_description" : "Token has been revoked." } at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105) at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:287) at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:307) at com.google.api.client.auth.oauth2.Credential.executeRefreshToken(Credential.java:570) at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:362) at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:489) at com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:217) at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:859) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469) at com.google.gct.login.GoogleLoginUtils$2.run(GoogleLoginUtils.java:97) at com.intellij.openapi.application.impl.ApplicationImpl$8.run(ApplicationImpl.java:365) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) at java.lang.Thread.run(Thread.java:662) at org.jetbrains.ide.PooledThreadExecutor$1$1.run(PooledThreadExecutor.java:55) [ 17796] ERROR - ea.elysium.GoogleUserModelItem - Exception loading projects for null com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request { "error" : "invalid_grant", "error_description" : "Token has been revoked." }

elharo commented 8 years ago

I'm reassigning to @patflynn to clarify what "handle gracefully" means here. Pop up a dialog telling the user they're logged out? Close the cloud debugger? Disable the cloud debugger somehow? All oif the above?

patflynn commented 8 years ago

It's an edge case, but at least I'd like a clear error when trying to launch the session that explains why it failed.

For an active session this is similar to the logout scenario. We should handle them similarly I think

patflynn commented 8 years ago

@elharo did we make any changes to handle logout?