madrob commented on code in PR #857:
URL: https://github.com/apache/solr/pull/857#discussion_r906356207


##########
solr/solr-ref-guide/modules/deployment-guide/pages/zookeeper-access-control.adoc:
##########
@@ -56,9 +56,37 @@ ACLs describe who is allowed to read, update, delete, 
create, etc.
 Each piece of information (znode/content) in ZooKeeper has its own set of 
ACLs, and inheritance or sharing is not possible.
 The default behavior in Solr is to add one ACL on all the content it creates - 
one ACL that gives anyone the permission to do anything (in ZooKeeper terms 
this is called "the open-unsafe ACL").
 
+
+
+== Solr to Zookeeper ACLs Workflow
+
+* Solr to Zookeeper credentials and ACLs are controlled trough 3 interfaces: 
{solr-javadocs}solrj/org/apache/solr/common/cloud/ZkCredentialsInjector.html[`ZkCredentialsInjector`],
  
{solr-javadocs}solrj/org/apache/solr/common/cloud/ZkCredentialsProvider.html[`ZkCredentialsProvider`]
 and 
{solr-javadocs}solrj/org/apache/solr/common/cloud/ZkACLProvider.html[`ZkACLProvider`].

Review Comment:
   ```suggestion
   * Solr to Zookeeper credentials and ACLs are controlled through 3 
interfaces: 
{solr-javadocs}solrj/org/apache/solr/common/cloud/ZkCredentialsInjector.html[`ZkCredentialsInjector`],
  
{solr-javadocs}solrj/org/apache/solr/common/cloud/ZkCredentialsProvider.html[`ZkCredentialsProvider`]
 and 
{solr-javadocs}solrj/org/apache/solr/common/cloud/ZkACLProvider.html[`ZkACLProvider`].
   ```



##########
solr/solr-ref-guide/modules/deployment-guide/pages/zookeeper-access-control.adoc:
##########
@@ -56,9 +56,37 @@ ACLs describe who is allowed to read, update, delete, 
create, etc.
 Each piece of information (znode/content) in ZooKeeper has its own set of 
ACLs, and inheritance or sharing is not possible.
 The default behavior in Solr is to add one ACL on all the content it creates - 
one ACL that gives anyone the permission to do anything (in ZooKeeper terms 
this is called "the open-unsafe ACL").
 
+
+
+== Solr to Zookeeper ACLs Workflow
+
+* Solr to Zookeeper credentials and ACLs are controlled trough 3 interfaces: 
{solr-javadocs}solrj/org/apache/solr/common/cloud/ZkCredentialsInjector.html[`ZkCredentialsInjector`],
  
{solr-javadocs}solrj/org/apache/solr/common/cloud/ZkCredentialsProvider.html[`ZkCredentialsProvider`]
 and 
{solr-javadocs}solrj/org/apache/solr/common/cloud/ZkACLProvider.html[`ZkACLProvider`].
+
+* The workflow is as follow: Credentials source →   `ZkCredentialsInjector` →  
`ZkCredentialsProvider/ZkACLProvider` → Zookeeper.
+
+`ZkCredentialsInjector` gets the credentials from an external source which in 
turn get injected into `ZkCredentialsProvider`

Review Comment:
   We could say "source" because I guess every source is external given how we 
define it.



##########
solr/solrj/src/java/org/apache/solr/common/cloud/acl/DigestZkACLProvider.java:
##########
@@ -0,0 +1,102 @@
+/*
+ * 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.solr.common.cloud.acl;
+
+import static 
org.apache.zookeeper.server.auth.DigestAuthenticationProvider.generateDigest;
+
+import java.lang.invoke.MethodHandles;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.solr.common.StringUtils;
+import org.apache.solr.common.cloud.SecurityAwareZkACLProvider;
+import org.apache.solr.common.cloud.acl.ZkCredentialsInjector.ZkCredential;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Id;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A class that expects a {@link ZkCredentialsInjector} to create Zookeeper 
ACLs using digest scheme
+ */
+public class DigestZkACLProvider extends SecurityAwareZkACLProvider {
+
+  private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+  public DigestZkACLProvider() {
+    this(new DefaultZkCredentialsInjector());
+  }
+
+  public DigestZkACLProvider(ZkCredentialsInjector zkCredentialsInjector) {
+    this.zkCredentialsInjector = zkCredentialsInjector;
+  }
+
+  /**
+   * @return Set of ACLs to return for non-security related znodes
+   */
+  @Override
+  protected List<ACL> createNonSecurityACLsToAdd() {
+    return createACLsToAdd(true);
+  }
+
+  /**
+   * Provider ACL Credential
+   *
+   * @return Set of ACLs to return security-related znodes
+   */
+  @Override
+  protected List<ACL> createSecurityACLsToAdd() {
+    return createACLsToAdd(false);
+  }
+
+  protected List<ACL> createACLsToAdd(boolean includeReadOnly) {
+    try {
+      List<ACL> result = new ArrayList<>();
+      List<ZkCredential> zkCredentials = 
zkCredentialsInjector.getZkCredentials();
+      log.debug("createACLsToAdd using ZkCredentials: {}", zkCredentials);
+      for (ZkCredential zkCredential : zkCredentials) {
+        if (StringUtils.isEmpty(zkCredential.getUsername())
+            || StringUtils.isEmpty(zkCredential.getPassword())) {
+          continue;
+        }
+        Id id = createACLId(zkCredential.getUsername(), 
zkCredential.getPassword());
+        int perms;
+        if (zkCredential.isAll()) {
+          // Not to have to provide too much credentials and ACL information 
to the process it is
+          // assumed that you want "ALL"-acls
+          // added to the user you are using to connect to ZK
+          perms = ZooDefs.Perms.ALL;
+        } else if (includeReadOnly && zkCredential.isReadonly()) {
+          // Besides, that support for adding additional "READONLY"-acls for 
another user
+          perms = ZooDefs.Perms.READ;
+        } else continue;
+        result.add(new ACL(perms, id));
+      }
+      if (result.isEmpty()) {
+        result = ZooDefs.Ids.OPEN_ACL_UNSAFE;
+      }
+      return result;
+    } catch (NoSuchAlgorithmException e) {
+      throw new RuntimeException("JVM mis-configured: missing SHA-1 
algorithm", e);
+    }
+  }
+
+  protected Id createACLId(String username, String password) throws 
NoSuchAlgorithmException {
+    return new Id("digest", generateDigest(username + ":" + password));

Review Comment:
   probably makes sense to try/catch here and rethrow as InternalError. 
Zookeeper already tries to recheck this for us, so if we're erroring here then 
it means somebody is hotswapping security providers and all bets are off.



##########
solr/solr-ref-guide/modules/deployment-guide/pages/zookeeper-access-control.adoc:
##########
@@ -56,9 +56,37 @@ ACLs describe who is allowed to read, update, delete, 
create, etc.
 Each piece of information (znode/content) in ZooKeeper has its own set of 
ACLs, and inheritance or sharing is not possible.
 The default behavior in Solr is to add one ACL on all the content it creates - 
one ACL that gives anyone the permission to do anything (in ZooKeeper terms 
this is called "the open-unsafe ACL").
 
+
+
+== Solr to Zookeeper ACLs Workflow
+
+* Solr to Zookeeper credentials and ACLs are controlled trough 3 interfaces: 
{solr-javadocs}solrj/org/apache/solr/common/cloud/ZkCredentialsInjector.html[`ZkCredentialsInjector`],
  
{solr-javadocs}solrj/org/apache/solr/common/cloud/ZkCredentialsProvider.html[`ZkCredentialsProvider`]
 and 
{solr-javadocs}solrj/org/apache/solr/common/cloud/ZkACLProvider.html[`ZkACLProvider`].
+
+* The workflow is as follow: Credentials source →   `ZkCredentialsInjector` →  
`ZkCredentialsProvider/ZkACLProvider` → Zookeeper.
+
+`ZkCredentialsInjector` gets the credentials from an external source which in 
turn get injected into `ZkCredentialsProvider`
+and `ZkACLProvider`. The "external source" here can be System Properties, a 
file, a Secret Manager, or any other local or remote source.
+
+* Those credentials are then passed to Solr trough System Properties using the 
following properties names:

Review Comment:
   This seems strange, even if I use a file for example, credentials still end 
up in system properties?



##########
solr/solr-ref-guide/modules/deployment-guide/pages/zookeeper-access-control.adoc:
##########
@@ -69,64 +97,361 @@ Solr nodes, clients, and tools (e.g., ZkCLI) always use a 
java class called {sol
 The implementation of the solution described here is all about changing 
`SolrZkClient`.
 If you use `SolrZkClient` in your application, the descriptions below will be 
true for your application too.
 
-=== Controlling Credentials
 
-You control which credentials provider will be used by configuring the 
`zkCredentialsProvider` property in the `<solrcloud>` section of 
xref:configuration-guide:configuring-solr-xml.adoc[`solr.xml`] to the name of a 
class (on the classpath) implementing the 
{solr-javadocs}/solrj/org/apache/solr/common/cloud/ZkCredentialsProvider.html[`ZkCredentialsProvider`]
 interface.
+* Controlling credentials and ACLs is done in 3 steps: Set a 
`ZkCredentialsInjector` that reads the credentials from
+some source and then inject them into a `ZkCredentialsProvider` that Solr uses 
to connect to Zookeeper. ZkACLProvider
+uses the same credentials to set the ACLs.
+
+
+We will describe these 3 steps in details before giving some ready to use 
examples.
+
+
+. Set the `ZkCredentialsInjector`.
+. Set the `ZkCredentialsProvider`.
+. Set the `ZkACLProvider`.
+
+
+=== Set a Credentials Injector
+
+* A credentials injector gets the credentials from an external source and 
injects them into Solr.
+
+
+** You control which credentials will be injected by configuring 
`zkCredentialsInjector` property in the `<solrcloud>` section of 
xref:configuration-guide:configuring-solr-xml.adoc[`solr.xml`] to the name of a 
class (on the classpath) implementing the 
{solr-javadocs}solrj/org/apache/solr/common/cloud/ZkCredentialsInjector.html[`ZkCredentialsInjector`]
 interface. +
+`server/solr/solr.xml` file in the Solr distribution defines 
the`zkCredentialsInjector`such that it will take on the value

Review Comment:
   ```suggestion
   `server/solr/solr.xml` file in the Solr distribution defines the 
`zkCredentialsInjector` such that it will take on the value
   ```



##########
solr/solrj/src/java/org/apache/solr/common/cloud/acl/DigestZkACLProvider.java:
##########
@@ -0,0 +1,102 @@
+/*
+ * 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.solr.common.cloud.acl;
+
+import static 
org.apache.zookeeper.server.auth.DigestAuthenticationProvider.generateDigest;
+
+import java.lang.invoke.MethodHandles;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.solr.common.StringUtils;
+import org.apache.solr.common.cloud.SecurityAwareZkACLProvider;
+import org.apache.solr.common.cloud.acl.ZkCredentialsInjector.ZkCredential;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Id;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A class that expects a {@link ZkCredentialsInjector} to create Zookeeper 
ACLs using digest scheme
+ */
+public class DigestZkACLProvider extends SecurityAwareZkACLProvider {
+
+  private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+  public DigestZkACLProvider() {

Review Comment:
   This constructor appears unused but I think we need it for reflective 
instantiation? Please add a comment noting this.



##########
solr/core/src/java/org/apache/solr/cloud/ZkController.java:
##########
@@ -59,6 +59,7 @@
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Supplier;
+import org.apache.commons.lang3.StringUtils;

Review Comment:
   ```suggestion
   import org.apache.solr.common.StringUtils;
   ```



##########
solr/solrj/src/java/org/apache/solr/common/cloud/VMParamsAllAndReadonlyDigestZkACLProvider.java:
##########
@@ -16,134 +16,82 @@
  */
 package org.apache.solr.common.cloud;
 
-import static 
org.apache.solr.common.cloud.VMParamsSingleSetCredentialsDigestZkCredentialsProvider.DEFAULT_DIGEST_FILE_VM_PARAM_NAME;
-import static 
org.apache.solr.common.cloud.VMParamsSingleSetCredentialsDigestZkCredentialsProvider.readCredentialsFile;
-
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
 import java.util.List;
-import java.util.Properties;
-import org.apache.solr.common.StringUtils;
-import org.apache.zookeeper.ZooDefs;
 import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Id;
-import org.apache.zookeeper.server.auth.DigestAuthenticationProvider;
 
-public class VMParamsAllAndReadonlyDigestZkACLProvider extends 
SecurityAwareZkACLProvider {
+/**
+ * Deprecated in favor of a combination of {@link DigestZkACLProvider} and 
{@link
+ * VMParamsZkCredentialsInjector}.
+ *
+ * <pre>
+ * Current implementation delegates to {@link DigestZkACLProvider} with an 
injected {@link VMParamsZkCredentialsInjector}
+ * </pre>
+ */
+@Deprecated

Review Comment:
   We typically include a `since` annotation on our deprecations. I guess this 
would be `since=10.0`?



##########
solr/solrj/src/java/org/apache/solr/common/cloud/acl/DigestZkCredentialsProvider.java:
##########
@@ -0,0 +1,67 @@
+/*
+ * 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.solr.common.cloud.acl;
+
+import java.lang.invoke.MethodHandles;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.apache.solr.common.StringUtils;
+import org.apache.solr.common.cloud.DefaultZkCredentialsProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A class that expects a {@link ZkCredentialsInjector} to create Zookeeper 
credentials using digest
+ * scheme
+ */
+public class DigestZkCredentialsProvider extends DefaultZkCredentialsProvider {
+
+  private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+  public DigestZkCredentialsProvider() {
+    this(new DefaultZkCredentialsInjector());
+  }
+
+  public DigestZkCredentialsProvider(ZkCredentialsInjector 
zkCredentialsInjector) {
+    this.zkCredentialsInjector = zkCredentialsInjector;
+  }
+
+  @Override
+  protected Collection<ZkCredentials> createCredentials() {
+    List<ZkCredentials> result = new ArrayList<>(1);
+    List<ZkCredentialsInjector.ZkCredential> zkCredentials =
+        zkCredentialsInjector.getZkCredentials();
+    log.debug("createCredentials using zkCredentials: {}", zkCredentials);

Review Comment:
   Is this safe? Will it log a password?



##########
solr/solrj/src/java/org/apache/solr/common/cloud/ZkACLProvider.java:
##########
@@ -17,9 +17,14 @@
 package org.apache.solr.common.cloud;
 
 import java.util.List;
+import org.apache.solr.common.cloud.acl.ZkCredentialsInjector;
 import org.apache.zookeeper.data.ACL;
 
 public interface ZkACLProvider {
 
   List<ACL> getACLsToAdd(String zNodePath);
+
+  default void setZkCredentialsInjector(ZkCredentialsInjector 
zkCredentialsInjector) {

Review Comment:
   javadoc please



##########
solr/solr-ref-guide/modules/deployment-guide/pages/zookeeper-access-control.adoc:
##########
@@ -56,9 +56,37 @@ ACLs describe who is allowed to read, update, delete, 
create, etc.
 Each piece of information (znode/content) in ZooKeeper has its own set of 
ACLs, and inheritance or sharing is not possible.
 The default behavior in Solr is to add one ACL on all the content it creates - 
one ACL that gives anyone the permission to do anything (in ZooKeeper terms 
this is called "the open-unsafe ACL").
 
+
+
+== Solr to Zookeeper ACLs Workflow
+
+* Solr to Zookeeper credentials and ACLs are controlled trough 3 interfaces: 
{solr-javadocs}solrj/org/apache/solr/common/cloud/ZkCredentialsInjector.html[`ZkCredentialsInjector`],
  
{solr-javadocs}solrj/org/apache/solr/common/cloud/ZkCredentialsProvider.html[`ZkCredentialsProvider`]
 and 
{solr-javadocs}solrj/org/apache/solr/common/cloud/ZkACLProvider.html[`ZkACLProvider`].
+
+* The workflow is as follow: Credentials source →   `ZkCredentialsInjector` →  
`ZkCredentialsProvider/ZkACLProvider` → Zookeeper.

Review Comment:
   Should this be "data flow" instead of workflow? I'm not sure what the right 
word would be but workflow doesn't feel right.



-- 
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: issues-unsubscr...@solr.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscr...@solr.apache.org
For additional commands, e-mail: issues-h...@solr.apache.org

Reply via email to