This is an automated email from the ASF dual-hosted git repository. jiangtian pushed a commit to branch may_pass_pw_check in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 79c0f42315079a58945db905d36ab1f805b2430c Author: Tian Jiang <[email protected]> AuthorDate: Sun Aug 17 14:51:29 2025 +0800 Increase availability when checking password & do not log until close to expiration --- .../org/apache/iotdb/jdbc/IoTDBConnection.java | 20 +++++++++-- .../iotdb/db/protocol/session/SessionManager.java | 39 ++++++++++++++++------ .../apache/iotdb/db/utils/DataNodeAuthUtils.java | 6 +++- .../apache/iotdb/commons/conf/CommonConfig.java | 9 +++++ 4 files changed, 61 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..9d82e2b978a 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,11 @@ public class SessionManager implements SessionManagerMBean { // check password expiration long passwordExpirationDays = CommonDescriptor.getInstance().getConfig().getPasswordExpirationDays(); + boolean mayBypassPasswordCheckInException = + CommonDescriptor.getInstance().getConfig().isMayBypassPasswordCheckInException(); + if (mayBypassPasswordCheckInException && passwordExpirationDays < 0) { + return Long.MAX_VALUE; + } TSLastDataQueryReq lastDataQueryReq = new TSLastDataQueryReq(); lastDataQueryReq.setSessionId(0); @@ -199,12 +205,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 +249,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 +273,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; + } }
