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

jiangtian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new b206294d0c8 Increase availability when checking password & do not log 
until close to expiration (#16146)
b206294d0c8 is described below

commit b206294d0c8f839994d0bca9ea52c0fecc671a0e
Author: Jiang Tian <[email protected]>
AuthorDate: Tue Aug 12 17:42:33 2025 +0800

    Increase availability when checking password & do not log until close to 
expiration (#16146)
    
    * Increase availability when checking password & do not log until close to 
expiration
    
    * fix
---
 .../org/apache/iotdb/jdbc/IoTDBConnection.java     | 20 ++++++++++--
 .../iotdb/db/protocol/session/SessionManager.java  | 36 ++++++++++++++++------
 .../apache/iotdb/db/utils/DataNodeAuthUtils.java   |  6 +++-
 .../apache/iotdb/commons/conf/CommonConfig.java    |  9 ++++++
 4 files changed, 58 insertions(+), 13 deletions(-)

diff --git 
a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java 
b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
index e92bccba09f..89c5823f658 100644
--- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
+++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
@@ -59,7 +59,9 @@ import java.sql.SQLXML;
 import java.sql.Savepoint;
 import java.sql.Statement;
 import java.sql.Struct;
+import java.time.LocalDateTime;
 import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
@@ -574,7 +576,7 @@ public class IoTDBConnection implements Connection {
       this.timeFactor = RpcUtils.getTimeFactor(openResp);
       if (protocolVersion.getValue() != 
openResp.getServerProtocolVersion().getValue()) {
         logger.warn(
-            "Protocol differ, Client version is {}}, but Server version is {}",
+            "Protocol differ, Client version is {}, but Server version is {}",
             protocolVersion.getValue(),
             openResp.getServerProtocolVersion().getValue());
         if (openResp.getServerProtocolVersion().getValue() == 0) { // less 
than 0.10
@@ -584,7 +586,21 @@ public class IoTDBConnection implements Connection {
                   protocolVersion.getValue(), 
openResp.getServerProtocolVersion().getValue()));
         }
       }
-      logger.info(openResp.getStatus().getMessage());
+      String expirationInformer = "Your password will expire at ";
+      String message = openResp.getStatus().getMessage();
+      int expirationIndex = message.indexOf(expirationInformer);
+      if (expirationIndex != -1) {
+        String expirationDateStr = message.substring(expirationIndex + 
expirationInformer.length());
+        DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd 
HH:mm:ss");
+        LocalDateTime expirationDate = 
LocalDateTime.from(dateFormat.parse(expirationDateStr));
+        LocalDateTime now = LocalDateTime.now();
+        if (now.isAfter(expirationDate.minusDays(3))) {
+          logger.warn(
+              "{}{}, please change it in time via 'ALTER USER' statement",
+              expirationInformer,
+              expirationDateStr);
+        }
+      }
     } catch (TException e) {
       transport.close();
       if (e.getMessage().contains("Required field 'client_protocol' was not 
present!")) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/session/SessionManager.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/session/SessionManager.java
index 166bfce08e1..69008d34b75 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/session/SessionManager.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/session/SessionManager.java
@@ -22,7 +22,6 @@ package org.apache.iotdb.db.protocol.session;
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.commons.conf.CommonDescriptor;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
-import org.apache.iotdb.commons.exception.IoTDBException;
 import org.apache.iotdb.commons.exception.IoTDBRuntimeException;
 import org.apache.iotdb.commons.pipe.config.constant.SystemConstant;
 import org.apache.iotdb.commons.service.JMXService;
@@ -63,10 +62,12 @@ import org.apache.tsfile.read.common.block.TsBlock;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.time.Instant;
+import java.time.LocalDateTime;
 import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.Date;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
@@ -143,6 +144,8 @@ public class SessionManager implements SessionManagerMBean {
     // check password expiration
     long passwordExpirationDays =
         CommonDescriptor.getInstance().getConfig().getPasswordExpirationDays();
+    boolean mayBypassPasswordCheckInException =
+        
CommonDescriptor.getInstance().getConfig().isMayBypassPasswordCheckInException();
 
     TSLastDataQueryReq lastDataQueryReq = new TSLastDataQueryReq();
     lastDataQueryReq.setSessionId(0);
@@ -199,12 +202,15 @@ public class SessionManager implements 
SessionManagerMBean {
       } else {
         return null;
       }
-    } catch (IoTDBException e) {
-      throw new IoTDBRuntimeException(
-          "Cannot query password history because: "
-              + e.getMessage()
-              + ", please log in later or disable password expiration.",
-          TSStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
+    } catch (Throwable e) {
+      LOGGER.error("Fail to check password expiration", e);
+      if (mayBypassPasswordCheckInException) {
+        return Long.MAX_VALUE;
+      } else {
+        throw new IoTDBRuntimeException(
+            "Internal server error " + ", please log in later or disable 
password expiration.",
+            TSStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
+      }
     }
   }
 
@@ -240,7 +246,12 @@ public class SessionManager implements SessionManagerMBean 
{
         supplySession(session, username, ZoneId.of(zoneId), clientVersion);
         String logInMessage = "Login successfully";
         if (timeToExpire != null && timeToExpire != Long.MAX_VALUE) {
-          logInMessage += ". Your password will expire at " + new 
Date(timeToExpire);
+          DateTimeFormatter dateFormat = 
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+          logInMessage +=
+              ". Your password will expire at "
+                  + dateFormat.format(
+                      LocalDateTime.ofInstant(
+                          Instant.ofEpochMilli(timeToExpire), 
ZoneId.systemDefault()));
         } else if (timeToExpire == null) {
           LOGGER.info(
               "No password history for user {}, using the current time to 
create a new one",
@@ -259,7 +270,12 @@ public class SessionManager implements SessionManagerMBean 
{
                       * 1000
                       * 86400;
           if (timeToExpire > System.currentTimeMillis()) {
-            logInMessage += ". Your password will expire at " + new 
Date(timeToExpire);
+            DateTimeFormatter dateFormat = 
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+            logInMessage +=
+                ". Your password will expire at "
+                    + dateFormat.format(
+                        LocalDateTime.ofInstant(
+                            Instant.ofEpochMilli(timeToExpire), 
ZoneId.systemDefault()));
           }
         }
         openSessionResp
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/DataNodeAuthUtils.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/DataNodeAuthUtils.java
index 94bf1db83b9..3526c2619ff 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/DataNodeAuthUtils.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/DataNodeAuthUtils.java
@@ -27,6 +27,7 @@ import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.pipe.config.constant.SystemConstant;
 import org.apache.iotdb.commons.utils.AuthUtils;
 import org.apache.iotdb.commons.utils.CommonDateTimeUtils;
+import org.apache.iotdb.commons.utils.StatusUtils;
 import org.apache.iotdb.db.auth.AuthorityChecker;
 import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.protocol.session.SessionManager;
@@ -106,7 +107,7 @@ public class DataNodeAuthUtils {
         return CommonDateTimeUtils.convertIoTDBTimeToMillis(timeByIndex);
       }
     } catch (IoTDBException e) {
-      LOGGER.warn("Cannot generate query for checking password expiration", e);
+      LOGGER.warn("Cannot generate query for checking password reuse 
interval", e);
     }
     return -1;
   }
@@ -175,6 +176,9 @@ public class DataNodeAuthUtils {
                   ClusterSchemaFetcher.getInstance());
       return result.status;
     } catch (Exception e) {
+      if 
(CommonDescriptor.getInstance().getConfig().isMayBypassPasswordCheckInException())
 {
+        return StatusUtils.OK;
+      }
       LOGGER.error("Cannot create password history for {} because {}", 
username, e.getMessage());
       return new TSStatus(TSStatusCode.INTERNAL_SERVER_ERROR.getStatusCode())
           .setMessage("The server is not ready for login, please check the 
server log for details");
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
index a780830642a..70381b14c82 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
@@ -417,6 +417,7 @@ public class CommonConfig {
   private long passwordExpirationDays = -1;
   // an old password cannot be reused within the given interval if >= 0.
   private long passwordReuseIntervalDays = -1;
+  private boolean mayBypassPasswordCheckInException = true;
 
   CommonConfig() {
     // Empty constructor
@@ -2426,4 +2427,12 @@ public class CommonConfig {
   public void setPasswordReuseIntervalDays(long passwordReuseIntervalDays) {
     this.passwordReuseIntervalDays = passwordReuseIntervalDays;
   }
+
+  public boolean isMayBypassPasswordCheckInException() {
+    return mayBypassPasswordCheckInException;
+  }
+
+  public void setMayBypassPasswordCheckInException(boolean 
mayBypassPasswordCheckInException) {
+    this.mayBypassPasswordCheckInException = mayBypassPasswordCheckInException;
+  }
 }

Reply via email to