Uploaded image for project: 'Dev - Nexus Repo'
  1. Dev - Nexus Repo
  2. NEXUS-20631

deleting Browse view nodes can fail if the requesting user signs out or the session expires

    XMLWordPrintable

    Details

    • Notability:
      3

      Description

      1. Signin and delete a Browse tree view node with a large number of assets under it.
      2. After clicking the button to delete the node, immediately end your UI session by signing out. ( or allow automatic UI session timeout if the UI session timeout is reached).

      The background thread used to delete all assets under the deleted node will fail and stop processing if it finds the HTTP session is ended and subsequently the cached user object gone.

      In one example, this looks to be caused by the Audit feature ( AssetAuditor), but may be caused by any code that has to look up the user object in this async thread ( like when trying to answer the question does this user have permission to delete this asset ).

      Example :

      The delete is requested:
      
      127.0.0.1 - username [25/Jul/2019:10:06:13 +0200] "POST /service/extdirect HTTP/1.0" 200 144 114972 142 "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0"
      
      ...
      
      Exactly 30 minutes later ( UI session timeout), the UI times out the user:
      
      127.0.0.1 - username [25/Jul/2019:10:36:03 +0200] "DELETE /service/rapture/session HTTP/1.0" 204 - 0 1 "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0"
      2019-07-25 10:36:03,978+0200 INFO  [qtp521434659-7187204] username org.sonatype.nexus.rapture.internal.security.SessionServlet - Deleting session for user: username
      
      ...
      
      The background thread performing the delete ERRORs and stops:
      
      2019-07-25 10:36:05,121+0200 ERROR [delete-path-8-thread-1]  username com.google.common.eventbus.EventBus.nexus - Could not dispatch event AssetCreatedEvent{metadata=AttachedEntityMetadata{schema=asset, document=asset#109:1889060{bucket:#79:2,format:maven2,last_updated:Thu Jul 25 10:36:05 CEST 2019,attributes:[5],component:null,name:org/example/Tm1Manager/maven-metadata.xml,size:59373,content_type:application/xml,created_by:system,created_by_ip:system,blob_ref:default@1103665D-3EAED1F0-05892A40-0BCD894E-864F7AE8:f57036cf-81b5-4d2c-91b7-687c9f6c3baf,last_downloaded:null,blob_created:Thu Jul 25 10:36:05 CEST 2019,blob_updated:Thu Jul 25 10:36:05 CEST 2019} v1}, remoteNodeId=null} to subscriber org.sonatype.nexus.repository.storage.internal.AssetAuditor@a882cdb method [public void org.sonatype.nexus.repository.storage.internal.AssetAuditor.on(org.sonatype.nexus.repository.storage.AssetEvent)]
      org.apache.shiro.session.UnknownSessionException: There is no session with id [72d5f6a1-0123-492b-a1bf-e7c472987cd9]
       at org.apache.shiro.session.mgt.eis.AbstractSessionDAO.readSession(AbstractSessionDAO.java:170)
       at org.apache.shiro.session.mgt.eis.CachingSessionDAO.readSession(CachingSessionDAO.java:261)
       at org.apache.shiro.session.mgt.DefaultSessionManager.retrieveSessionFromDataSource(DefaultSessionManager.java:236)
       at org.apache.shiro.session.mgt.DefaultSessionManager.retrieveSession(DefaultSessionManager.java:222)
       at org.apache.shiro.session.mgt.AbstractValidatingSessionManager.doGetSession(AbstractValidatingSessionManager.java:118)
       at org.apache.shiro.session.mgt.AbstractNativeSessionManager.lookupSession(AbstractNativeSessionManager.java:148)
       at org.apache.shiro.session.mgt.AbstractNativeSessionManager.lookupRequiredSession(AbstractNativeSessionManager.java:152)
       at org.apache.shiro.session.mgt.AbstractNativeSessionManager.getAttribute(AbstractNativeSessionManager.java:249)
       at org.apache.shiro.session.mgt.DelegatingSession.getAttribute(DelegatingSession.java:141)
       at org.apache.shiro.session.ProxiedSession.getAttribute(ProxiedSession.java:121)
       at org.apache.shiro.subject.support.DelegatingSubject.getRunAsPrincipalsStack(DelegatingSubject.java:469)
       at org.apache.shiro.subject.support.DelegatingSubject.getPrincipals(DelegatingSubject.java:153)
       at org.apache.shiro.subject.support.DelegatingSubject.getPrincipal(DelegatingSubject.java:149)
       at org.sonatype.nexus.security.UserIdHelper.get(UserIdHelper.java:55)
       at org.sonatype.nexus.security.UserIdHelper.get(UserIdHelper.java:47)
       at org.sonatype.nexus.audit.internal.InitiatorProviderImpl.get(InitiatorProviderImpl.java:57)
       at org.sonatype.nexus.audit.internal.AuditRecorderImpl.record(AuditRecorderImpl.java:86)
       at org.sonatype.nexus.audit.AuditorSupport.record(AuditorSupport.java:122)
       at org.sonatype.nexus.repository.storage.internal.AssetAuditor.on(AssetAuditor.java:67)
       at sun.reflect.GeneratedMethodAccessor136.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       at java.lang.reflect.Method.invoke(Method.java:498)
       at com.google.common.eventbus.Subscriber.invokeSubscriberMethod(Subscriber.java:87)
       at com.google.common.eventbus.Subscriber$1.run(Subscriber.java:72)
       at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:398)
       at com.google.common.eventbus.Subscriber.dispatchEvent(Subscriber.java:67)
       at com.google.common.eventbus.Dispatcher$ImmediateDispatcher.dispatch(Dispatcher.java:186)
       at com.google.common.eventbus.EventBus.post(EventBus.java:212)
       at org.sonatype.nexus.internal.event.EventManagerImpl.post(EventManagerImpl.java:127)
       at org.sonatype.nexus.orient.entity.EntityHook.postEvents(EntityHook.java:316)
       at org.sonatype.nexus.orient.entity.EntityHook.flushEvents(EntityHook.java:289)
       at org.sonatype.nexus.orient.entity.EntityHook.onAfterTxCommit(EntityHook.java:174)
       at com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx.commit(ODatabaseDocumentTx.java:2949)
       at com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx.commit(ODatabaseDocumentTx.java:2870)
       at org.sonatype.nexus.repository.storage.StorageTxImpl.commit(StorageTxImpl.java:183)
       at sun.reflect.GeneratedMethodAccessor111.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       at java.lang.reflect.Method.invoke(Method.java:498)
       at org.sonatype.nexus.common.stateguard.SimpleMethodInvocation.proceed(SimpleMethodInvocation.java:53)
       at org.sonatype.nexus.common.stateguard.MethodInvocationAction.run(MethodInvocationAction.java:39)
       at org.sonatype.nexus.common.stateguard.StateGuard$TransitionImpl.run(StateGuard.java:193)
       at org.sonatype.nexus.common.stateguard.TransitionsInterceptor.invoke(TransitionsInterceptor.java:56)
       at org.sonatype.nexus.common.stateguard.StateGuardAspect$1.invoke(StateGuardAspect.java:66)
       at com.sun.proxy.$Proxy214.commit(Unknown Source)
       at org.sonatype.nexus.transaction.BatchTransaction.commit(BatchTransaction.java:38)
       at org.sonatype.nexus.transaction.TransactionalWrapper.proceedWithTransaction(TransactionalWrapper.java:67)
       at org.sonatype.nexus.transaction.Operations.transactional(Operations.java:200)
       at org.sonatype.nexus.transaction.Operations.call(Operations.java:146)
       at org.sonatype.nexus.repository.maven.internal.hosted.metadata.MetadataUpdater.update(MetadataUpdater.java:89)
       at org.sonatype.nexus.repository.maven.internal.hosted.metadata.MetadataUpdater.processMetadata(MetadataUpdater.java:72)
       at org.sonatype.nexus.repository.maven.internal.hosted.metadata.MetadataRebuilder$Worker.rebuildMetadataInner(MetadataRebuilder.java:494)
       at org.sonatype.nexus.repository.maven.internal.hosted.metadata.MetadataRebuilder$Worker.rebuildMetadata(MetadataRebuilder.java:402)
       at org.sonatype.nexus.repository.maven.internal.hosted.metadata.MetadataRebuilder.rebuild(MetadataRebuilder.java:124)
       at org.sonatype.nexus.repository.maven.internal.hosted.metadata.MetadataRebuilder.deleteAndRebuild(MetadataRebuilder.java:255)
       at org.sonatype.nexus.repository.maven.internal.hosted.MavenHostedFacetImpl.deleteMetadata(MavenHostedFacetImpl.java:130)
       at org.sonatype.nexus.repository.maven.internal.hosted.MavenHostedComponentMaintenanceFacet.deleteComponent(MavenHostedComponentMaintenanceFacet.java:55)
       at org.sonatype.nexus.repository.storage.DefaultComponentMaintenanceImpl.deleteComponent(DefaultComponentMaintenanceImpl.java:49)
       at org.sonatype.nexus.repository.maintenance.internal.DeleteFolderServiceImpl.deleteComponent(DeleteFolderServiceImpl.java:133)
       at org.sonatype.nexus.repository.maintenance.internal.DeleteFolderServiceImpl.deleteFolder(DeleteFolderServiceImpl.java:122)
       at org.sonatype.nexus.repository.maintenance.internal.MaintenanceServiceImpl.lambda$0(MaintenanceServiceImpl.java:112)
       at org.sonatype.nexus.thread.internal.MDCAwareRunnable.run(MDCAwareRunnable.java:40)
       at org.apache.shiro.subject.support.SubjectRunnable.doRun(SubjectRunnable.java:120)
       at org.apache.shiro.subject.support.SubjectRunnable.run(SubjectRunnable.java:108)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
       at java.util.concurrent.FutureTask.run(FutureTask.java:266)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
       at java.lang.Thread.run(Thread.java:748)
      

      Expected

      Async threads like this should not rely on a presence of an HTTP user session, after the work has begun. Any user specific details needed to fulfill the original request and subsequent auditing should be passed along in such a way that the original requested action does not fail for lack of user session.

      Mitigation

      If such a scenario occurs, then a user needs to reselect the node that was not completely deleted, and ask to delete it again, until the operation eventually completes.

      Otherwise, the UI session timeout may need to be increased - which generally may not be a wise permanent solution for security reasons.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              Unassigned Unassigned
              Reporter:
              plynch Peter Lynch
              Last Updated By:
              Joe Tom Joe Tom
              Team:
              NXRM - Tron
              Votes:
              2 Vote for this issue
              Watchers:
              3 Start watching this issue

                Dates

                Created:
                Updated:

                  tigCommentSecurity.panel-title