remKeysIt = remKeys.iterator();
+ while (remKeysIt.hasNext()) {
+ userDataProp.remove(remKeysIt.next());
+ }
+
+ saveUserData();
+ }
+
+ /**
+ * Get user password. Returns the encrypted value.
+ *
+ *
+ * If the password value is not null
+ * password = new password
+ * else
+ * if user does exist
+ * password = old password
+ * else
+ * password = ""
+ *
+ */
+ private String getPassword(User usr) {
+ String name = usr.getName();
+ String password = usr.getPassword();
+
+ if (password != null) {
+ password = passwordEncryptor.encrypt(password);
+ } else {
+ String blankPassword = passwordEncryptor.encrypt("");
+
+ if (doesExist(name)) {
+ String key = PREFIX + name + '.' + ATTR_PASSWORD;
+ password = userDataProp.getProperty(key, blankPassword);
+ } else {
+ password = blankPassword;
+ }
+ }
+ return password;
+ }
+
+ /**
+ * Get all user names.
+ */
+ public synchronized String[] getAllUserNames() {
+ lazyInit();
+
+ // get all user names
+ String suffix = '.' + ATTR_HOME;
+ ArrayList ulst = new ArrayList();
+ Enumeration> allKeys = userDataProp.propertyNames();
+ int prefixlen = PREFIX.length();
+ int suffixlen = suffix.length();
+ while (allKeys.hasMoreElements()) {
+ String key = (String) allKeys.nextElement();
+ if (key.endsWith(suffix)) {
+ String name = key.substring(prefixlen);
+ int endIndex = name.length() - suffixlen;
+ name = name.substring(0, endIndex);
+ ulst.add(name);
+ }
+ }
+
+ Collections.sort(ulst);
+ return ulst.toArray(new String[0]);
+ }
+
+ private ArrayList parseGroups(String groupsLine) {
+ String groupsArray[] = groupsLine.split(",");
+ return new ArrayList(Arrays.asList(groupsArray));
+ }
+
+ public static synchronized boolean getUserRenamePush(String userName) {
+ return userDataProp.getBoolean(PREFIX + userName + ".rename.push", false);
+ }
+
+ /**
+ * Load user data.
+ */
+ public synchronized User getUserByName(String userName) {
+ lazyInit();
+
+ if (!doesExist(userName)) {
+ return null;
+ }
+
+ String baseKey = PREFIX + userName + '.';
+ HdfsUser user = new HdfsUser();
+ user.setName(userName);
+ user.setEnabled(userDataProp.getBoolean(baseKey + ATTR_ENABLE, true));
+ user.setHomeDirectory(userDataProp
+ .getProperty(baseKey + ATTR_HOME, "/"));
+
+// user.setGroups(parseGroups(userDataProp
+// .getProperty(baseKey + "groups")));
+
+ List authorities = new ArrayList();
+
+ if (userDataProp.getBoolean(baseKey + ATTR_WRITE_PERM, false)) {
+ authorities.add(new WritePermission());
+ }
+
+ int maxLogin = userDataProp.getInteger(baseKey + ATTR_MAX_LOGIN_NUMBER,
+ 0);
+ int maxLoginPerIP = userDataProp.getInteger(baseKey
+ + ATTR_MAX_LOGIN_PER_IP, 0);
+
+ authorities.add(new ConcurrentLoginPermission(maxLogin, maxLoginPerIP));
+
+ int uploadRate = userDataProp.getInteger(
+ baseKey + ATTR_MAX_UPLOAD_RATE, 0);
+ int downloadRate = userDataProp.getInteger(baseKey
+ + ATTR_MAX_DOWNLOAD_RATE, 0);
+
+ authorities.add(new TransferRatePermission(downloadRate, uploadRate));
+
+ user.setAuthorities(authorities);
+
+ user.setMaxIdleTime(userDataProp.getInteger(baseKey
+ + ATTR_MAX_IDLE_TIME, 0));
+
+ return user;
+ }
+
+ /**
+ * User existance check
+ */
+ public synchronized boolean doesExist(String name) {
+ lazyInit();
+
+ String key = PREFIX + name + '.' + ATTR_HOME;
+ return userDataProp.containsKey(key);
+ }
+
+ /**
+ * User authenticate method
+ */
+ public synchronized User authenticate(Authentication authentication)
+ throws AuthenticationFailedException {
+ lazyInit();
+
+ if (authentication instanceof UsernamePasswordAuthentication) {
+ UsernamePasswordAuthentication upauth = (UsernamePasswordAuthentication) authentication;
+
+ String user = upauth.getUsername();
+ String password = upauth.getPassword();
+
+ if (user == null) {
+ throw new AuthenticationFailedException("Authentication failed");
+ }
+
+ if (password == null) {
+ password = "";
+ }
+
+ String storedPassword = userDataProp.getProperty(PREFIX + user + '.'
+ + ATTR_PASSWORD);
+
+ if (storedPassword == null) {
+ // user does not exist
+ throw new AuthenticationFailedException("Authentication failed");
+ }
+
+ if (passwordEncryptor.matches(password, storedPassword)) {
+ return getUserByName(user);
+ } else {
+ throw new AuthenticationFailedException("Authentication failed");
+ }
+
+ } else if (authentication instanceof AnonymousAuthentication) {
+ if (doesExist("anonymous")) {
+ return getUserByName("anonymous");
+ } else {
+ throw new AuthenticationFailedException("Authentication failed");
+ }
+ } else {
+ throw new IllegalArgumentException(
+ "Authentication not supported by this user manager");
+ }
+ }
+
+ /**
+ * Close the user manager - remove existing entries.
+ */
+ public synchronized void dispose() {
+ if (userDataProp != null) {
+ userDataProp.clear();
+ userDataProp = null;
+ }
+ }
+}
diff --git a/other/java/hdfs-over-ftp/src/main/resources/application.yml b/other/java/hdfs-over-ftp/src/main/resources/application.yml
new file mode 100644
index 000000000..128bab1f9
--- /dev/null
+++ b/other/java/hdfs-over-ftp/src/main/resources/application.yml
@@ -0,0 +1,15 @@
+server:
+ port: 8080
+
+ftp:
+ port: 2222
+ passive-address: localhost
+ passive-ports: 30000-30999
+
+hdfs:
+ uri: seaweedfs://localhost:8888
+
+seaweedFs:
+ enable: true
+ access: direct # direct/filerProxy/publicUrl
+ replication: "000"
\ No newline at end of file
diff --git a/other/java/hdfs-over-ftp/src/main/resources/assembly.xml b/other/java/hdfs-over-ftp/src/main/resources/assembly.xml
new file mode 100644
index 000000000..84fef56f8
--- /dev/null
+++ b/other/java/hdfs-over-ftp/src/main/resources/assembly.xml
@@ -0,0 +1,39 @@
+
+
+
+ package
+
+
+ tar.gz
+
+ false
+
+
+
+ src/main/resources
+ /
+
+ application.yml
+ logback-spring.xml
+ users.properties
+ kafka-producer.properties
+
+
+
+ ${project.build.directory}
+ /
+
+ *.jar
+
+
+
+
+
+ false
+ lib
+ runtime
+ false
+
+
+
diff --git a/other/java/hdfs-over-ftp/src/main/resources/logback-spring.xml b/other/java/hdfs-over-ftp/src/main/resources/logback-spring.xml
new file mode 100644
index 000000000..96b4c1d71
--- /dev/null
+++ b/other/java/hdfs-over-ftp/src/main/resources/logback-spring.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
+
+
+
+
+
+
+ ${LOG_HOME}/fileLog.log
+
+ ${LOG_HOME}/fileLog.log.%d.%i
+
+ 100 MB
+
+
+
+
+ %d %p (%file:%line\)- %m%n
+
+ UTF-8
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/other/java/hdfs-over-ftp/users.properties b/other/java/hdfs-over-ftp/users.properties
new file mode 100644
index 000000000..aeeab8e35
--- /dev/null
+++ b/other/java/hdfs-over-ftp/users.properties
@@ -0,0 +1,12 @@
+#Generated file - don't edit (please)
+#Thu Mar 11 19:11:12 CST 2021
+ftpserver.user.test.idletime=0
+ftpserver.user.test.maxloginperip=0
+ftpserver.user.test.userpassword=44664D4D827C740293D2AA244FB60445
+ftpserver.user.test.enableflag=true
+ftpserver.user.test.maxloginnumber=0
+ftpserver.user.test.rename.push=true
+ftpserver.user.test.homedirectory=/buckets/test/
+ftpserver.user.test.downloadrate=0
+ftpserver.user.test.writepermission=true
+ftpserver.user.test.uploadrate=0