You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@linkis.apache.org by al...@apache.org on 2022/09/14 14:29:10 UTC

[incubator-linkis] branch dev-1.3.1 updated: Add a tool class to determine whether the os user exists (#3349)

This is an automated email from the ASF dual-hosted git repository.

alexkun pushed a commit to branch dev-1.3.1
in repository https://gitbox.apache.org/repos/asf/incubator-linkis.git


The following commit(s) were added to refs/heads/dev-1.3.1 by this push:
     new d022d1488 Add a tool class to determine whether the os user exists (#3349)
d022d1488 is described below

commit d022d14886cab586b01a7510733f09c3bee0a802
Author: peacewong <wp...@gmail.com>
AuthorDate: Wed Sep 14 22:29:04 2022 +0800

    Add a tool class to determine whether the os user exists (#3349)
    
    * Add a tool class to determine whether the os user exists
    
    * Modify the judgment condition
---
 .../linkis/storage/fs/impl/LocalFileSystem.java    |   3 +
 .../linkis-storage-script-dev-server/pom.xml       |   6 ++
 .../filesystem/conf/WorkSpaceConfiguration.java    |   7 ++
 .../exception/WorkspaceExceptionManager.java       |   1 +
 .../filesystem/restful/api/FsRestfulApi.java       |  32 +++---
 .../linkis/filesystem/utils/UserGroupInfo.scala    | 117 +++++++++++++++++++++
 6 files changed, 150 insertions(+), 16 deletions(-)

diff --git a/linkis-commons/linkis-storage/src/main/java/org/apache/linkis/storage/fs/impl/LocalFileSystem.java b/linkis-commons/linkis-storage/src/main/java/org/apache/linkis/storage/fs/impl/LocalFileSystem.java
index 12b89a1e3..82975d541 100644
--- a/linkis-commons/linkis-storage/src/main/java/org/apache/linkis/storage/fs/impl/LocalFileSystem.java
+++ b/linkis-commons/linkis-storage/src/main/java/org/apache/linkis/storage/fs/impl/LocalFileSystem.java
@@ -285,6 +285,9 @@ public class LocalFileSystem extends FileSystem {
     } else {
       this.properties = new HashMap<String, String>();
     }
+    if (FsPath.WINDOWS) {
+      group = StorageConfiguration.STORAGE_USER_GROUP().getValue(properties);
+    }
     if (StringUtils.isEmpty(group)) {
       String groupInfo;
       try {
diff --git a/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/pom.xml b/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/pom.xml
index b09d432da..eb06769a0 100644
--- a/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/pom.xml
+++ b/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/pom.xml
@@ -70,6 +70,12 @@
       <version>${project.version}</version>
     </dependency>
 
+    <dependency>
+      <groupId>com.github.oshi</groupId>
+      <artifactId>oshi-core</artifactId>
+      <version>6.2.1</version>
+    </dependency>
+
   </dependencies>
 
   <build>
diff --git a/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/src/main/java/org/apache/linkis/filesystem/conf/WorkSpaceConfiguration.java b/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/src/main/java/org/apache/linkis/filesystem/conf/WorkSpaceConfiguration.java
index 603eb49de..c7a3ff981 100644
--- a/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/src/main/java/org/apache/linkis/filesystem/conf/WorkSpaceConfiguration.java
+++ b/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/src/main/java/org/apache/linkis/filesystem/conf/WorkSpaceConfiguration.java
@@ -57,6 +57,13 @@ public class WorkSpaceConfiguration {
   public static final CommonVars<Boolean> FILESYSTEM_PATH_AUTO_CREATE =
       CommonVars$.MODULE$.apply("linkis.workspace.filesystem.auto.create", false);
 
+  public static final CommonVars<Long> LOCAL_FILESYSTEM_USER_REFRESH_INTERVAL =
+      CommonVars$.MODULE$.apply(
+          "linkis.filesystem.local.usermap.refresh.interval.mills", 30 * 60 * 1000L);
+
+  public static final CommonVars<Boolean> ENABLE_USER_GROUP =
+      CommonVars$.MODULE$.apply("linkis.os.user.group.enabled", true);
+
   public static final ExecutorService executorService =
       new ThreadPoolExecutor(
           FILESYSTEM_FS_THREAD_NUM.getValue(),
diff --git a/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/src/main/java/org/apache/linkis/filesystem/exception/WorkspaceExceptionManager.java b/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/src/main/java/org/apache/linkis/filesystem/exception/WorkspaceExceptionManager.java
index fc6d36387..2bbcbfc69 100644
--- a/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/src/main/java/org/apache/linkis/filesystem/exception/WorkspaceExceptionManager.java
+++ b/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/src/main/java/org/apache/linkis/filesystem/exception/WorkspaceExceptionManager.java
@@ -65,6 +65,7 @@ public class WorkspaceExceptionManager {
           put("80028", "the path exist special char");
           put("80029", "empty dir!");
           put("80030", "Failed to create user path");
+          put("80031", "The user was not initialized(用户未初始化)");
         }
       };
 
diff --git a/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/src/main/java/org/apache/linkis/filesystem/restful/api/FsRestfulApi.java b/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/src/main/java/org/apache/linkis/filesystem/restful/api/FsRestfulApi.java
index 9d53fbd5f..4e7286214 100644
--- a/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/src/main/java/org/apache/linkis/filesystem/restful/api/FsRestfulApi.java
+++ b/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/src/main/java/org/apache/linkis/filesystem/restful/api/FsRestfulApi.java
@@ -17,6 +17,15 @@
 
 package org.apache.linkis.filesystem.restful.api;
 
+import com.fasterxml.jackson.databind.JsonNode;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.math3.util.Pair;
+import org.apache.http.Consts;
 import org.apache.linkis.common.io.FsPath;
 import org.apache.linkis.common.io.FsWriter;
 import org.apache.linkis.filesystem.conf.WorkSpaceConfiguration;
@@ -26,6 +35,7 @@ import org.apache.linkis.filesystem.exception.WorkSpaceException;
 import org.apache.linkis.filesystem.exception.WorkspaceExceptionManager;
 import org.apache.linkis.filesystem.service.FsService;
 import org.apache.linkis.filesystem.util.WorkspaceUtil;
+import org.apache.linkis.filesystem.utils.UserGroupUtils;
 import org.apache.linkis.filesystem.validator.PathValidator$;
 import org.apache.linkis.server.Message;
 import org.apache.linkis.server.utils.ModuleUserUtils;
@@ -39,11 +49,8 @@ import org.apache.linkis.storage.script.*;
 import org.apache.linkis.storage.source.FileSource;
 import org.apache.linkis.storage.source.FileSource$;
 import org.apache.linkis.storage.utils.StorageUtils;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.math3.util.Pair;
-import org.apache.http.Consts;
-
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.*;
@@ -52,16 +59,6 @@ import org.springframework.web.multipart.MultipartFile;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiImplicitParams;
-import io.swagger.annotations.ApiOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import java.io.*;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
@@ -139,7 +136,10 @@ public class FsRestfulApi {
         FsPath fsPath = new FsPath(path);
         FileSystem fileSystem = fsService.getFileSystem(userName, fsPath);
         if (!fileSystem.exists(fsPath)) {
-
+            if (!FsPath.WINDOWS && ! UserGroupUtils.isUserExist(userName)) {
+                LOGGER.warn("User {} not exist in linkis node.", userName);
+                throw WorkspaceExceptionManager.createException(80031);
+            }
             if (FILESYSTEM_PATH_AUTO_CREATE.getValue()) {
                 try {
                     fileSystem.mkdirs(fsPath);
diff --git a/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/src/main/scala/org/apache/linkis/filesystem/utils/UserGroupInfo.scala b/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/src/main/scala/org/apache/linkis/filesystem/utils/UserGroupInfo.scala
new file mode 100644
index 000000000..754fe08f4
--- /dev/null
+++ b/linkis-public-enhancements/linkis-script-dev/linkis-storage-script-dev-server/src/main/scala/org/apache/linkis/filesystem/utils/UserGroupInfo.scala
@@ -0,0 +1,117 @@
+/*
+ * 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.linkis.filesystem.utils
+
+import org.apache.linkis.common.utils.{Logging, Utils}
+import org.apache.linkis.filesystem.conf.WorkSpaceConfiguration
+
+import java.util
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.locks.ReentrantReadWriteLock
+
+import scala.collection.mutable.ArrayBuffer
+
+import com.sun.jna.Platform
+import oshi.util.{ExecutingCommand, FileUtil}
+
+/**
+ * TODO If other modules need to be used later, the tool class should be moved to the linkis-storage
+ * module
+ */
+
+class UserGroupInfo extends Logging {
+
+  private val userList = new ArrayBuffer[String]()
+
+  private val USERLOCKER = new ReentrantReadWriteLock()
+
+  private def init(): Unit = {
+    Utils.tryAndError(refreshUserMap())
+    val runnable = new Runnable {
+      override def run(): Unit = {
+        Utils.tryAndError(refreshUserMap())
+      }
+    }
+    Utils.defaultScheduler.scheduleWithFixedDelay(
+      runnable,
+      100000L,
+      WorkSpaceConfiguration.LOCAL_FILESYSTEM_USER_REFRESH_INTERVAL.getValue,
+      TimeUnit.MILLISECONDS
+    )
+
+  }
+
+  init()
+
+  private def refreshUserMap(): Unit = {
+    val tmpUsers = new ArrayBuffer[String]()
+    var passwd: util.List[String] = null
+    if (Platform.isAIX) passwd = FileUtil.readFile("/etc/passwd")
+    else passwd = ExecutingCommand.runNative("getent passwd")
+    val iterator = passwd.iterator
+    while (iterator.hasNext) {
+      val entry = iterator.next.asInstanceOf[String]
+      val split = entry.split(":")
+      if (split.length > 2) {
+        val userName = split(0)
+        tmpUsers.append(userName)
+      }
+    }
+    tmpUsers.sorted
+    logger.info("user refresh user count {}", tmpUsers.length)
+    if (logger.isDebugEnabled()) {
+      logger.debug("Refresh users:{}", tmpUsers.mkString(","))
+    }
+    if (tmpUsers.isEmpty) {
+      logger.warn("Refresh user map is empty")
+      return
+    }
+    USERLOCKER.writeLock().lock()
+    Utils.tryFinally {
+      userList.clear()
+      userList ++ tmpUsers
+    } {
+      USERLOCKER.writeLock().unlock()
+    }
+
+  }
+
+  def isUserExist(username: String): Boolean = {
+    USERLOCKER.readLock().lock()
+    Utils.tryFinally {
+      userList.exists(_.equals(username))
+    } {
+      USERLOCKER.readLock().unlock()
+    }
+  }
+
+}
+
+object UserGroupUtils {
+
+  private lazy val userGroupInfo = new UserGroupInfo()
+
+  def isUserExist(username: String): Boolean = {
+    if (WorkSpaceConfiguration.ENABLE_USER_GROUP.getValue) {
+      userGroupInfo.isUserExist(username)
+    } else {
+      true
+    }
+  }
+
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@linkis.apache.org
For additional commands, e-mail: commits-help@linkis.apache.org