kirklund commented on a change in pull request #6835:
URL: https://github.com/apache/geode/pull/6835#discussion_r707765614



##########
File path: 
geode-core/src/distributedTest/java/org/apache/geode/management/internal/security/MultiUserAuthenticationDUnitTest.java
##########
@@ -16,9 +16,14 @@
 package org.apache.geode.management.internal.security;
 
 import static org.apache.geode.cache.Region.SEPARATOR;
+import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

Review comment:
       I think you meant to use:
   ```
   import static org.assertj.core.api.Assertions.assertThat;
   ```

##########
File path: 
geode-core/src/distributedTest/java/org/apache/geode/management/internal/security/MultiUserAuthenticationDUnitTest.java
##########
@@ -100,4 +113,67 @@ public void multiAuthenticatedView() throws Exception {
       cache.close();
     }
   }
+
+  @Test
+  public void multiUserCQ() throws Exception {
+    int locatorPort = locator.getPort();
+    ClientCache cache = client.withCacheSetup(f -> 
f.setPoolSubscriptionEnabled(true)
+        .setPoolMultiuserAuthentication(true)
+        .addPoolLocator("localhost", locatorPort))
+        .createCache();
+
+    // both are able to read data
+    RegionService regionService1 = client.createAuthenticatedView("data", 
"data");
+    RegionService regionService2 = client.createAuthenticatedView("dataRead", 
"dataRead");
+
+    EventsCqListner listener1 = 
createAndExecuteCQ(regionService1.getQueryService(), "cq1",
+        "select * from /region r where r.length<=2");
+    EventsCqListner listener2 = 
createAndExecuteCQ(regionService2.getQueryService(), "cq2",
+        "select * from /region r where r.length>=2");
+
+    // put 4 data in the region
+    gfsh.executeAndAssertThat("put --region=region --key=1 --value=1");
+    gfsh.executeAndAssertThat("put --region=region --key=11 --value=11");
+    gfsh.executeAndAssertThat("put --region=region --key=111 --value=111");
+
+    await().atMost(100, TimeUnit.SECONDS).untilAsserted(

Review comment:
       These `await()` calls should just use the default timeout. If this test 
runs on a slow or overloaded machine, it may fail here.

##########
File path: 
geode-core/src/main/java/org/apache/geode/cache/client/internal/AuthenticateUserOp.java
##########
@@ -123,39 +119,61 @@ private AuthenticateUserOp() {
       super(MessageType.USER_CREDENTIAL_MESSAGE, 1);
       securityProperties = securityProps;
       needsServerLocation = needsServer;
-
       getMessage().setMessageHasSecurePartFlag();
     }
 
     @Override
     protected void sendMessage(Connection cnx) throws Exception {
-      HeapDataOutputStream hdos = new 
HeapDataOutputStream(KnownVersion.CURRENT);
-      byte[] secureBytes;
-      hdos.writeLong(cnx.getConnectionID());
-      if (securityProperties != null) {
-        DistributedMember server = new 
InternalDistributedMember(cnx.getSocket().getInetAddress(),
-            cnx.getSocket().getPort(), false);
-        DistributedSystem sys = 
InternalDistributedSystem.getConnectedInstance();
-        String authInitMethod = 
sys.getProperties().getProperty(SECURITY_CLIENT_AUTH_INIT);
-
-        Properties credentials = Handshake.getCredentials(authInitMethod, 
securityProperties,
-            server, false, sys.getLogWriter(), sys.getSecurityLogWriter());
-        byte[] credentialBytes;
-        try (HeapDataOutputStream heapdos = new 
HeapDataOutputStream(KnownVersion.CURRENT)) {
-          DataSerializer.writeProperties(credentials, heapdos);
-          credentialBytes = ((ConnectionImpl) 
cnx).encryptBytes(heapdos.toByteArray());
-        }
-        getMessage().addBytesPart(credentialBytes);
+      if (securityProperties == null) {
+        securityProperties = getConnectedSystem().getSecurityProperties();
       }
-      try {
-        secureBytes = ((ConnectionImpl) cnx).encryptBytes(hdos.toByteArray());
-      } finally {
-        hdos.close();
+      byte[] credentialBytes = getCredentialBytes(cnx, securityProperties);
+      getMessage().addBytesPart(credentialBytes);
+
+      long userId = getUserId(cnx);
+      try (HeapDataOutputStream hdos = new HeapDataOutputStream(16, 
KnownVersion.CURRENT)) {
+        hdos.writeLong(cnx.getConnectionID());
+        hdos.writeLong(userId);
+        getMessage().setSecurePart(((ConnectionImpl) 
cnx).encryptBytes(hdos.toByteArray()));
       }
-      getMessage().setSecurePart(secureBytes);
       getMessage().send(false);
     }
 
+    protected long getUserId(Connection cnx) {
+      // single user mode
+      if (UserAttributes.userAttributes.get() == null) {
+        return cnx.getServer().getUserId();
+      }
+      // multi user mode
+      Long id = 
UserAttributes.userAttributes.get().getServerToId().get(cnx.getServer());
+      if (id == null) {
+        return -1L;
+      }
+      return id;
+    }
+
+    protected InternalDistributedSystem getConnectedSystem() {
+      return InternalDistributedSystem.getConnectedInstance();
+    }
+
+    protected byte[] getCredentialBytes(Connection cnx, Properties 
securityProperties)

Review comment:
       `connection` instead of `cnx`? I know the old uses abbreviations, but we 
really want to escape that trend.

##########
File path: 
geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientProxy.java
##########
@@ -345,19 +348,15 @@ protected CacheClientProxy(InternalCache cache, 
CacheClientNotifier ccn, Socket
     initializeClientAuths();
   }
 
-  private void initializeClientAuths() {
-    if (AcceptorImpl.isPostAuthzCallbackPresent()) {
-      clientUserAuths = ServerConnection.getClientUserAuths(proxyID);
-    }
+  void initializeClientAuths() {
+    clientUserAuths = ServerConnection.getClientUserAuths(proxyID);

Review comment:
       One way to make the use of `CacheClientProxy` more testable is to wrap 
the`ServerConnection.getClientUserAuths` calls in a ` 
java.util.function.Function` or custom inner-interface.
   
   You basically add a new field:
   ```
   private final Function<ClientProxyMembershipID, ClientUserAuths> 
getClientUserAuthsFunction;
   ```
   Then update the 2nd `CacheClientProxy` constructor marked with 
`@VisibleForTesting` to include one more parameter:
   ```
   MessageDispatcherFactory messageDispatcherFactory,
   Function<ClientProxyMembershipID, ClientUserAuths> 
getClientUserAuthsFunction) {
   ```
   Change the 1st constructor to pass in a method reference:
   ```
   DEFAULT_MESSAGEDISPATCHERFACTORY,
   ServerConnection::getClientUserAuths);
   ```
   And save the the parameter in the 2nd constructor to the field:
   ```
   this.getClientUserAuthsFunction = getClientUserAuthsFunction;
   ```
   And finally use it anywhere the class calls the static 
`ServerConnection.getClientUserAuths`:
   ```
   clientUserAuths = getClientUserAuths.apply(proxyID);
   ```

##########
File path: 
geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientReAuthenticateMessage.java
##########
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+package org.apache.geode.internal.cache.tier.sockets;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.geode.internal.cache.EventID;
+import org.apache.geode.internal.cache.tier.MessageType;
+import org.apache.geode.internal.serialization.DeserializationContext;
+import org.apache.geode.internal.serialization.KnownVersion;
+import org.apache.geode.internal.serialization.SerializationContext;
+
+public class ClientReAuthenticateMessage implements ClientMessage {
+
+  /**
+   * This <code>ClientMessage</code>'s <code>EventID</code>

Review comment:
       Please use the newer syntax `{@code xxx}` instead of `<code>`:
   ```
   * This {@code ClientMessage}'s {@code EventID}
   ```

##########
File path: 
geode-core/src/main/java/org/apache/geode/cache/client/internal/AuthenticateUserOp.java
##########
@@ -123,39 +119,61 @@ private AuthenticateUserOp() {
       super(MessageType.USER_CREDENTIAL_MESSAGE, 1);
       securityProperties = securityProps;
       needsServerLocation = needsServer;
-
       getMessage().setMessageHasSecurePartFlag();
     }
 
     @Override
     protected void sendMessage(Connection cnx) throws Exception {
-      HeapDataOutputStream hdos = new 
HeapDataOutputStream(KnownVersion.CURRENT);
-      byte[] secureBytes;
-      hdos.writeLong(cnx.getConnectionID());
-      if (securityProperties != null) {
-        DistributedMember server = new 
InternalDistributedMember(cnx.getSocket().getInetAddress(),
-            cnx.getSocket().getPort(), false);
-        DistributedSystem sys = 
InternalDistributedSystem.getConnectedInstance();
-        String authInitMethod = 
sys.getProperties().getProperty(SECURITY_CLIENT_AUTH_INIT);
-
-        Properties credentials = Handshake.getCredentials(authInitMethod, 
securityProperties,
-            server, false, sys.getLogWriter(), sys.getSecurityLogWriter());
-        byte[] credentialBytes;
-        try (HeapDataOutputStream heapdos = new 
HeapDataOutputStream(KnownVersion.CURRENT)) {
-          DataSerializer.writeProperties(credentials, heapdos);
-          credentialBytes = ((ConnectionImpl) 
cnx).encryptBytes(heapdos.toByteArray());
-        }
-        getMessage().addBytesPart(credentialBytes);
+      if (securityProperties == null) {
+        securityProperties = getConnectedSystem().getSecurityProperties();
       }
-      try {
-        secureBytes = ((ConnectionImpl) cnx).encryptBytes(hdos.toByteArray());
-      } finally {
-        hdos.close();
+      byte[] credentialBytes = getCredentialBytes(cnx, securityProperties);
+      getMessage().addBytesPart(credentialBytes);
+
+      long userId = getUserId(cnx);
+      try (HeapDataOutputStream hdos = new HeapDataOutputStream(16, 
KnownVersion.CURRENT)) {
+        hdos.writeLong(cnx.getConnectionID());
+        hdos.writeLong(userId);
+        getMessage().setSecurePart(((ConnectionImpl) 
cnx).encryptBytes(hdos.toByteArray()));
       }
-      getMessage().setSecurePart(secureBytes);
       getMessage().send(false);
     }
 
+    protected long getUserId(Connection cnx) {

Review comment:
       Can we name the parameter `connection` instead of `cnx`?

##########
File path: 
geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientReAuthenticateMessage.java
##########
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+package org.apache.geode.internal.cache.tier.sockets;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.geode.internal.cache.EventID;
+import org.apache.geode.internal.cache.tier.MessageType;
+import org.apache.geode.internal.serialization.DeserializationContext;
+import org.apache.geode.internal.serialization.KnownVersion;
+import org.apache.geode.internal.serialization.SerializationContext;
+
+public class ClientReAuthenticateMessage implements ClientMessage {
+
+  /**
+   * This <code>ClientMessage</code>'s <code>EventID</code>
+   */
+  private final EventID eventId;
+
+  public ClientReAuthenticateMessage() {
+    eventId = new EventID();
+  }
+
+  public ClientReAuthenticateMessage(EventID eventId) {
+    this.eventId = eventId;
+  }

Review comment:
       You should really use constructor chaining here:
   ```
   public ClientReAuthenticateMessage() {
     this(new EventID());
   }
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to