convergencelabs / convergence-project

The project used for Convergence Project Management and Issue Reporting
https://convergence.io
42 stars 5 forks source link

Deleting a user from the Admin interface produces a 500 error #261

Closed toebes closed 2 years ago

toebes commented 2 years ago

Versions Please fill in all that apply:

Describe the Bug Deleting a user generates a 500 error which is not reported on the Admin console

Step To Reproduce

  1. Create a user associated with a model
  2. Delete the model so that the user is no longer listed in any permissions
  3. Go into the admin console and select the Users for the domain
  4. Click on the delete icon for the user
  5. Answer yes to the "Are you sure delete this user?" (notice the grammar error on the question)

If you are monitoring the network, you can see that it makes a call:

  Request URL: https://cosso.oit.ncsu.edu/rest/domains/convergence/scienceolympiad/users/_<user>_
  Request Method: DELETE
  Status Code: 500 Internal Server Error
  Remote Address: 54.90.19.158:443
  Referrer Policy: strict-origin-when-cross-origin

The response headers are:

HTTP/1.1 500 Internal Server Error
Server: nginx/1.17.6
Date: Mon, 13 Dec 2021 02:22:46 GMT
Content-Type: application/json
Content-Length: 58
Connection: keep-alive
Access-Control-Allow-Origin: <server>
Access-Control-Allow-Credentials: true

Expected Behavior The delete should succeed or if there is some error, it should be reported to the Admin Console

mmacfadden commented 2 years ago

The following stack trace is produced:

server_1         | 20:27:04 ERROR DomainUserStoreActor$$anonfun$onDeleteUser$2 - Unexpected error deleting user
server_1         | com.orientechnologies.orient.core.exception.OStorageException: Error on executing command:
server_1         | let users = SELECT FROM User WHERE userType = :userType AND username = :username;
server_1         | let user = $users[0];
server_1         | UPDATE PermissionTarget REMOVE permissions = permissions[grantee = $user] WHERE permissions CONTAINS(grantee = $user);
server_1         | DELETE FROM permission WHERE grantee = $user
server_1         |
server_1         |      DB name="8565213004482691108"
server_1         |      at com.orientechnologies.orient.client.remote.OStorageRemote.baseNetworkOperation(OStorageRemote.java:366) ~[com.orientechnologies.orientdb-client-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.client.remote.OStorageRemote.networkOperationRetryTimeout(OStorageRemote.java:228) ~[com.orientechnologies.orientdb-client-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.client.remote.OStorageRemote.networkOperationNoRetry(OStorageRemote.java:261) ~[com.orientechnologies.orientdb-client-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.client.remote.OStorageRemote.execute(OStorageRemote.java:1000) ~[com.orientechnologies.orientdb-client-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.core.db.document.ODatabaseDocumentRemote.execute(ODatabaseDocumentRemote.java:445) ~[com.orientechnologies.orientdb-client-3.0.37.jar:3.0.37]
server_1         |      at com.convergencelabs.convergence.server.backend.datastore.OrientDBUtil$.$anonfun$execute$1(OrientDBUtil.scala:76) ~[com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at com.convergencelabs.convergence.server.util.TryWithResource.com$convergencelabs$convergence$server$util$TryWithResource$$tryWithResource(TryWithResource.scala:33) ~[com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at com.convergencelabs.convergence.server.util.TryWithResource$.apply(TryWithResource.scala:78) ~[com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at com.convergencelabs.convergence.server.backend.datastore.OrientDBUtil$.execute(OrientDBUtil.scala:76) ~[com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at com.convergencelabs.convergence.server.backend.datastore.domain.permissions.PermissionsStore.$anonfun$removeAllPermissionsForUser$1(PermissionsStore.scala:379) ~[com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at com.convergencelabs.convergence.server.backend.db.PooledDatabaseProvider.$anonfun$withDatabase$3(PooledDatabaseProvider.scala:58) ~[com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at com.convergencelabs.convergence.server.util.TryWithResource.tryWithResolvedResource(TryWithResource.scala:50) ~[com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at com.convergencelabs.convergence.server.util.TryWithResource.com$convergencelabs$convergence$server$util$TryWithResource$$tryWithResource(TryWithResource.scala:36) ~[com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at com.convergencelabs.convergence.server.util.TryWithResource$.apply(TryWithResource.scala:78) ~[com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at com.convergencelabs.convergence.server.backend.db.PooledDatabaseProvider.$anonfun$withDatabase$1(PooledDatabaseProvider.scala:56) ~[com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at scala.util.Success.flatMap(Try.scala:258) ~[org.scala-lang.scala-library-2.13.7.jar:?]
server_1         |      at com.convergencelabs.convergence.server.backend.db.PooledDatabaseProvider.withDatabase(PooledDatabaseProvider.scala:55) ~[com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at com.convergencelabs.convergence.server.backend.datastore.AbstractDatabasePersistence.withDb(AbstractDatabasePersistence.scala:32) ~[com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at com.convergencelabs.convergence.server.backend.datastore.domain.permissions.PermissionsStore.removeAllPermissionsForUser(PermissionsStore.scala:370) ~[com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at com.convergencelabs.convergence.server.backend.datastore.domain.user.DomainUserDeletionOrchestrator.deleteNormalDomainUser(DomainUserDeletionOrchestrator.scala:43) ~[com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at com.convergencelabs.convergence.server.backend.services.domain.user.DomainUserStoreActor.onDeleteUser(DomainUserStoreActor.scala:148) [com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at com.convergencelabs.convergence.server.backend.services.domain.user.DomainUserStoreActor.onMessage(DomainUserStoreActor.scala:41) [com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at com.convergencelabs.convergence.server.backend.services.domain.user.DomainUserStoreActor.onMessage(DomainUserStoreActor.scala:27) [com.convergencelabs.convergence-server-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
server_1         |      at akka.actor.typed.scaladsl.AbstractBehavior.receive(AbstractBehavior.scala:84) [com.typesafe.akka.akka-actor-typed_2.13-2.6.15.jar:2.6.15]
server_1         |      at akka.actor.typed.Behavior$.interpret(Behavior.scala:274) [com.typesafe.akka.akka-actor-typed_2.13-2.6.15.jar:2.6.15]
server_1         |      at akka.actor.typed.Behavior$.interpretMessage(Behavior.scala:230) [com.typesafe.akka.akka-actor-typed_2.13-2.6.15.jar:2.6.15]
server_1         |      at akka.actor.typed.internal.adapter.ActorAdapter.handleMessage(ActorAdapter.scala:131) [com.typesafe.akka.akka-actor-typed_2.13-2.6.15.jar:2.6.15]
server_1         |      at akka.actor.typed.internal.adapter.ActorAdapter.aroundReceive(ActorAdapter.scala:107) [com.typesafe.akka.akka-actor-typed_2.13-2.6.15.jar:2.6.15]
server_1         |      at akka.actor.ActorCell.receiveMessage(ActorCell.scala:580) [com.typesafe.akka.akka-actor_2.13-2.6.15.jar:2.6.15]
server_1         |      at akka.actor.ActorCell.invoke(ActorCell.scala:548) [com.typesafe.akka.akka-actor_2.13-2.6.15.jar:2.6.15]
server_1         |      at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:270) [com.typesafe.akka.akka-actor_2.13-2.6.15.jar:2.6.15]
server_1         |      at akka.dispatch.Mailbox.run(Mailbox.scala:231) [com.typesafe.akka.akka-actor_2.13-2.6.15.jar:2.6.15]
server_1         |      at akka.dispatch.Mailbox.exec(Mailbox.scala:243) [com.typesafe.akka.akka-actor_2.13-2.6.15.jar:2.6.15]
server_1         |      at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) [?:?]
server_1         |      at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020) [?:?]
server_1         |      at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656) [?:?]
server_1         |      at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594) [?:?]
server_1         |      at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183) [?:?]
server_1         | Caused by: java.lang.RuntimeException: com.orientechnologies.orient.core.exception.ODatabaseException: Error on deserialization of Serializable
server_1         |      DB name="8565213004482691108"
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerNetworkV37.deserializeValue(ORecordSerializerNetworkV37.java:326) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerNetworkV37.readEmbeddedMap(ORecordSerializerNetworkV37.java:459) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerNetworkV37.deserializeValue(ORecordSerializerNetworkV37.java:302) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerNetworkV37.deserialize(ORecordSerializerNetworkV37.java:122) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerNetworkV37.fromStream(ORecordSerializerNetworkV37.java:860) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.client.remote.message.OQueryRequest.getParams(OQueryRequest.java:148) ~[com.orientechnologies.orientdb-client-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.client.remote.message.OQueryRequest.getNamedParameters(OQueryRequest.java:163) ~[com.orientechnologies.orientdb-client-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.server.OConnectionBinaryExecutor.executeQuery(OConnectionBinaryExecutor.java:1192) ~[com.orientechnologies.orientdb-server-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.client.remote.message.OQueryRequest.execute(OQueryRequest.java:136) ~[com.orientechnologies.orientdb-client-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.sessionRequest(ONetworkProtocolBinary.java:317) ~[com.orientechnologies.orientdb-server-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.execute(ONetworkProtocolBinary.java:212) ~[com.orientechnologies.orientdb-server-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.common.thread.OSoftThread.run(OSoftThread.java:69) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         | Caused by: com.orientechnologies.orient.core.exception.ODatabaseException: Error on deserialization of Serializable
server_1         |      DB name="8565213004482691108"
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.OSerializableWrapper.fromStream(OSerializableWrapper.java:48) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerNetworkV37.deserializeValue(ORecordSerializerNetworkV37.java:320) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerNetworkV37.readEmbeddedMap(ORecordSerializerNetworkV37.java:459) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerNetworkV37.deserializeValue(ORecordSerializerNetworkV37.java:302) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerNetworkV37.deserialize(ORecordSerializerNetworkV37.java:122) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerNetworkV37.fromStream(ORecordSerializerNetworkV37.java:860) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.client.remote.message.OQueryRequest.getParams(OQueryRequest.java:148) ~[com.orientechnologies.orientdb-client-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.client.remote.message.OQueryRequest.getNamedParameters(OQueryRequest.java:163) ~[com.orientechnologies.orientdb-client-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.server.OConnectionBinaryExecutor.executeQuery(OConnectionBinaryExecutor.java:1192) ~[com.orientechnologies.orientdb-server-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.client.remote.message.OQueryRequest.execute(OQueryRequest.java:136) ~[com.orientechnologies.orientdb-client-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.sessionRequest(ONetworkProtocolBinary.java:317) ~[com.orientechnologies.orientdb-server-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.execute(ONetworkProtocolBinary.java:212) ~[com.orientechnologies.orientdb-server-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.common.thread.OSoftThread.run(OSoftThread.java:69) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         | Caused by: java.lang.ClassNotFoundException: scala.Enumeration$Val
server_1         |      at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[?:?]
server_1         |      at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[?:?]
server_1         |      at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352) ~[?:?]
server_1         |      at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[?:?]
server_1         |      at java.lang.Class.forName0(Native Method) ~[?:?]
server_1         |      at java.lang.Class.forName(Class.java:348) ~[?:?]
server_1         |      at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:720) ~[?:?]
server_1         |      at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1925) ~[?:?]
server_1         |      at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1808) ~[?:?]
server_1         |      at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2099) ~[?:?]
server_1         |      at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1625) ~[?:?]
server_1         |      at java.io.ObjectInputStream.readObject(ObjectInputStream.java:465) ~[?:?]
server_1         |      at java.io.ObjectInputStream.readObject(ObjectInputStream.java:423) ~[?:?]
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.OSerializableWrapper.fromStream(OSerializableWrapper.java:45) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerNetworkV37.deserializeValue(ORecordSerializerNetworkV37.java:320) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerNetworkV37.readEmbeddedMap(ORecordSerializerNetworkV37.java:459) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerNetworkV37.deserializeValue(ORecordSerializerNetworkV37.java:302) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerNetworkV37.deserialize(ORecordSerializerNetworkV37.java:122) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerNetworkV37.fromStream(ORecordSerializerNetworkV37.java:860) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.client.remote.message.OQueryRequest.getParams(OQueryRequest.java:148) ~[com.orientechnologies.orientdb-client-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.client.remote.message.OQueryRequest.getNamedParameters(OQueryRequest.java:163) ~[com.orientechnologies.orientdb-client-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.server.OConnectionBinaryExecutor.executeQuery(OConnectionBinaryExecutor.java:1192) ~[com.orientechnologies.orientdb-server-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.client.remote.message.OQueryRequest.execute(OQueryRequest.java:136) ~[com.orientechnologies.orientdb-client-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.sessionRequest(ONetworkProtocolBinary.java:317) ~[com.orientechnologies.orientdb-server-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.execute(ONetworkProtocolBinary.java:212) ~[com.orientechnologies.orientdb-server-3.0.37.jar:3.0.37]
server_1         |      at com.orientechnologies.common.thread.OSoftThread.run(OSoftThread.java:69) ~[com.orientechnologies.orientdb-core-3.0.37.jar:3.0.37]
mmacfadden commented 2 years ago

This is cause because we are not serializing the user type to a string and trying to send a Scala enum over to the database which can't deserialize the value.

achamas-playco commented 2 years ago

For anyone else looking to solve this problem, the fix for this was for the 1.0.0-rc13 release for the server project.

Unfortunately it doesn't seem that this server version is included with the latest omnibus container, or the docker-compose project but it is available on docker hub, which is good.

The solution is to avoid using the omnibus container (eg. convergencelabs/convergence-omnibus) for development or deployment and instead use the convergence-docker-compose repo directly. It essentially spins up the same parts, you just need to clone the project and docker-compose it locally.

Leave the CONVERGENCE_DOCKER_TAG version in the .env file as is (it was on 1.0.0-rc.12) and instead explicitly set the server version in the docker-compose.yml file to use 1.0.0-rc13.

  ##
  ## The main Convergence Server. In this compose file this single node boots all
  ## server roles.
  ##
  server:
    image: ${CONVERGENCE_DOCKER_REPO}/convergence-server:1.0.0-rc.13
    ...

The rest of the docker services use rc12, which is why you don't want to change the .env file.

Then start everything up with docker-compose up and you'll get the latest server with the fix, which solves this problem!

Great project btw thanks!

mmacfadden commented 2 years ago

We will get the omnibus container posted up shortly.