li4wang commented on code in PR #1966:
URL: https://github.com/apache/zookeeper/pull/1966#discussion_r1054858542


##########
zookeeper-server/src/main/java/org/apache/zookeeper/server/admin/Commands.java:
##########
@@ -92,24 +112,97 @@ public static void registerCommand(Command command) {
      *
      * @param cmdName
      * @param zkServer
-     * @param kwargs String-valued keyword arguments to the command
+     * @param kwargs String-valued keyword arguments to the command from HTTP 
GET request
      *        (may be null if command requires no additional arguments)
+     * @param inputStream inputStream from HTTP POST request
+     *        (null if it's HTTP GET request)
+     * @param authInfo auth info for auth check
+     *        (null if command requires no auth check)
+     * @param request HTTP request
      * @return Map representing response to command containing at minimum:
      *    - "command" key containing the command's primary name
      *    - "error" key containing a String error message or null if no error
      */
     public static CommandResponse runCommand(
-        String cmdName,
-        ZooKeeperServer zkServer,
-        Map<String, String> kwargs) {
+            String cmdName,
+            ZooKeeperServer zkServer,
+            Map<String, String> kwargs,
+            InputStream inputStream,
+            String authInfo,
+            HttpServletRequest request) {
         Command command = getCommand(cmdName);
         if (command == null) {
-            return new CommandResponse(cmdName, "Unknown command: " + cmdName);
+            // set the status code to 200 to keep the current behavior of 
existing commands
+            LOG.warn("Unknown command: {}", cmdName);
+            return new CommandResponse(cmdName, "Unknown command: " + cmdName, 
HttpServletResponse.SC_OK);
         }
         if (command.isServerRequired() && (zkServer == null || 
!zkServer.isRunning())) {
-            return new CommandResponse(cmdName, "This ZooKeeper instance is 
not currently serving requests");
+            // set the status code to 200 to keep the current behavior of 
existing commands
+            LOG.warn("This ZooKeeper instance is not currently serving 
requests for command: {}", cmdName);
+            return new CommandResponse(cmdName, "This ZooKeeper instance is 
not currently serving requests", HttpServletResponse.SC_OK);
         }
-        return command.run(zkServer, kwargs);
+
+        final AuthRequest authRequest = command.getAuthRequest();
+        if (authRequest != null) {
+            if (authInfo == null) {
+                LOG.warn("Auth info is missing for command: {}", cmdName);
+                return new CommandResponse(cmdName, "Auth info is missing for 
the command", HttpServletResponse.SC_UNAUTHORIZED);
+            }
+            try {
+                final List<Id> ids = handleAuthentication(request, authInfo);
+                handleAuthorization(zkServer, ids, 
authRequest.getPermission(), authRequest.getPath());
+            } catch (final KeeperException.AuthFailedException e) {
+                return new CommandResponse(cmdName, "Not authenticated", 
HttpServletResponse.SC_UNAUTHORIZED);
+            } catch (final KeeperException.NoAuthException e) {
+                return new CommandResponse(cmdName, "Not authorized", 
HttpServletResponse.SC_FORBIDDEN);
+            } catch (final Exception e) {
+                LOG.warn("Error occurred during auth for command: {}", 
cmdName, e);
+                return new CommandResponse(cmdName, "Error occurred during 
auth", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            }
+        }
+        return command.run(zkServer, kwargs, inputStream);
+    }
+
+    private static List<Id> handleAuthentication(final HttpServletRequest 
request, final String authInfo) throws KeeperException.AuthFailedException {
+        final String[] authData = authInfo.split(AUTH_INFO_SEPARATOR);
+        // for IP and x509, auth info only contains the schema and Auth Id 
will be extracted from HTTP request
+        if (authData.length != 1 && authData.length != 2) {
+            LOG.warn("Invalid auth info: {}", authInfo);
+            throw new KeeperException.AuthFailedException();
+        }
+
+        final String schema = authData[0];
+        final ServerAuthenticationProvider authProvider = 
ProviderRegistry.getServerProvider(schema);
+        if (authProvider != null) {
+            try {
+                final byte[] auth = authData.length == 2 ? 
authData[1].getBytes(StandardCharsets.UTF_8) : null;
+                final List<Id> ids = 
authProvider.handleAuthentication(request, auth);
+                if (ids.isEmpty()) {
+                    LOG.warn("Auth Id list is empty: {}", authInfo);

Review Comment:
   fixed



-- 
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: notifications-unsubscr...@zookeeper.apache.org

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

Reply via email to