diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBAuthIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBAuthIT.java index 441dd1fdb5c94..5ec674b2a37f9 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBAuthIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBAuthIT.java @@ -20,9 +20,7 @@ package org.apache.iotdb.db.it.auth; import org.apache.iotdb.commons.auth.entity.PrivilegeType; -import org.apache.iotdb.commons.conf.CommonDescriptor; import org.apache.iotdb.commons.schema.column.ColumnHeaderConstant; -import org.apache.iotdb.commons.utils.AuthUtils; import org.apache.iotdb.db.it.utils.TestUtils; import org.apache.iotdb.it.env.EnvFactory; import org.apache.iotdb.it.framework.IoTDBTestRunner; @@ -51,8 +49,6 @@ import java.util.Set; import java.util.concurrent.Callable; -import static org.apache.iotdb.commons.auth.entity.User.INTERNAL_USER_END_ID; -import static org.apache.iotdb.db.audit.DNAuditLogger.PREFIX_PASSWORD_HISTORY; import static org.apache.iotdb.db.it.utils.TestUtils.createUser; import static org.apache.iotdb.db.it.utils.TestUtils.executeNonQuery; import static org.apache.iotdb.db.it.utils.TestUtils.resultSetEqualTest; @@ -1521,107 +1517,6 @@ public void testStrongPassword() throws SQLException { } } - @Test - public void testPasswordHistory() { - try (Connection connection = EnvFactory.getEnv().getConnection(); - Statement statement = connection.createStatement()) { - testPasswordHistoryEncrypted(statement); - testPasswordHistoryCreateAndDrop(statement); - testPasswordHistoryAlter(statement); - } catch (SQLException e) { - e.printStackTrace(); - fail(e.getMessage()); - } - } - - public void testPasswordHistoryEncrypted(Statement statement) throws SQLException { - ResultSet resultSet = - statement.executeQuery("SELECT password,oldPassword from root.__audit.password_history._0"); - assertTrue(resultSet.next()); - assertEquals( - AuthUtils.encryptPassword(CommonDescriptor.getInstance().getConfig().getAdminPassword()), - resultSet.getString("root.__audit.password_history._0.password")); - assertEquals( - AuthUtils.encryptPassword(CommonDescriptor.getInstance().getConfig().getAdminPassword()), - resultSet.getString("root.__audit.password_history._0.oldPassword")); - } - - public void testPasswordHistoryCreateAndDrop(Statement statement) throws SQLException { - statement.execute("create user userA 'abcdef123456'"); - - long expectedUserAId = INTERNAL_USER_END_ID + 1; - try (ResultSet resultSet = - statement.executeQuery( - String.format( - "select last password from %s.`_" + expectedUserAId + "`", - PREFIX_PASSWORD_HISTORY))) { - if (!resultSet.next()) { - fail("Password history not found"); - } - assertEquals(AuthUtils.encryptPassword("abcdef123456"), resultSet.getString("Value")); - } - - try (ResultSet resultSet = - statement.executeQuery( - String.format( - "select last oldPassword from %s.`_" + expectedUserAId + "`", - PREFIX_PASSWORD_HISTORY))) { - if (!resultSet.next()) { - fail("Password history not found"); - } - assertEquals(AuthUtils.encryptPassword("abcdef123456"), resultSet.getString("Value")); - } - - statement.execute("drop user userA"); - - try (ResultSet resultSet = - statement.executeQuery( - String.format( - "select last password from %s.`_" + expectedUserAId + "`", - PREFIX_PASSWORD_HISTORY))) { - assertFalse(resultSet.next()); - } - - try (ResultSet resultSet = - statement.executeQuery( - String.format( - "select last oldPassword from %s.`_" + expectedUserAId + "`", - PREFIX_PASSWORD_HISTORY))) { - assertFalse(resultSet.next()); - } - } - - public void testPasswordHistoryAlter(Statement statement) throws SQLException { - statement.execute("create user userA 'abcdef123456'"); - statement.execute("alter user userA set password 'abcdef654321'"); - - long expectedUserAId = INTERNAL_USER_END_ID + 2; - try (ResultSet resultSet = - statement.executeQuery( - String.format( - "select last password from %s.`_" + expectedUserAId + "`", - PREFIX_PASSWORD_HISTORY))) { - if (!resultSet.next()) { - fail("Password history not found"); - } - assertEquals(AuthUtils.encryptPassword("abcdef654321"), resultSet.getString("Value")); - } - - try (ResultSet resultSet = - statement.executeQuery( - String.format( - "select oldPassword from %s.`_" + expectedUserAId + "` order by time desc limit 1", - PREFIX_PASSWORD_HISTORY))) { - if (!resultSet.next()) { - fail("Password history not found"); - } - assertEquals( - AuthUtils.encryptPassword("abcdef123456"), - resultSet.getString( - String.format("%s._" + expectedUserAId + ".oldPassword", PREFIX_PASSWORD_HISTORY))); - } - } - @Test public void testChangeBackPassword() { try (Connection connection = EnvFactory.getEnv().getConnection(); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/audit/DNAuditLogger.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/audit/DNAuditLogger.java index 3a07ac9aa69b7..c838ff8ef3f7e 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/audit/DNAuditLogger.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/audit/DNAuditLogger.java @@ -32,7 +32,6 @@ import java.util.function.Supplier; public class DNAuditLogger extends AbstractAuditLogger { - public static final String PREFIX_PASSWORD_HISTORY = "root.__audit.password_history"; private Coordinator coordinator; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/thrift/IoTDBDataNodeReceiver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/thrift/IoTDBDataNodeReceiver.java index 254928e91910d..c4664f552de7c 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/thrift/IoTDBDataNodeReceiver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/thrift/IoTDBDataNodeReceiver.java @@ -105,7 +105,6 @@ import org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType; import org.apache.iotdb.db.tools.schema.SRStatementGenerator; import org.apache.iotdb.db.tools.schema.SchemaRegionSnapshotParser; -import org.apache.iotdb.db.utils.DataNodeAuthUtils; import org.apache.iotdb.pipe.api.exception.PipeException; import org.apache.iotdb.rpc.RpcUtils; import org.apache.iotdb.rpc.TSStatusCode; @@ -955,14 +954,6 @@ protected TSStatus login() { return RpcUtils.getStatus(openSessionResp.getCode(), openSessionResp.getMessage()); } - long userId = AuthorityChecker.getUserId(username).orElse(-1L); - Long timeToExpire = DataNodeAuthUtils.checkPasswordExpiration(userId, password, false); - if (timeToExpire != null && timeToExpire <= System.currentTimeMillis()) { - return RpcUtils.getStatus( - TSStatusCode.ILLEGAL_PASSWORD.getStatusCode(), - "Password has expired, please use \"ALTER USER\" to change to a new one"); - } - return AuthorityChecker.checkUser(username, password); } 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 ac7cc236d9f6d..cf0705dbb5341 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 @@ -24,14 +24,12 @@ import org.apache.iotdb.commons.audit.AuditLogFields; import org.apache.iotdb.commons.audit.AuditLogOperation; import org.apache.iotdb.commons.audit.UserEntity; -import org.apache.iotdb.commons.conf.CommonDescriptor; import org.apache.iotdb.commons.conf.IoTDBConstant; import org.apache.iotdb.commons.service.JMXService; import org.apache.iotdb.commons.service.ServiceType; import org.apache.iotdb.commons.service.metric.MetricService; import org.apache.iotdb.commons.service.metric.enums.Metric; import org.apache.iotdb.commons.service.metric.enums.Tag; -import org.apache.iotdb.commons.utils.AuthUtils; import org.apache.iotdb.commons.utils.CommonDateTimeUtils; import org.apache.iotdb.db.audit.DNAuditLogger; import org.apache.iotdb.db.auth.AuthorityChecker; @@ -42,7 +40,6 @@ import org.apache.iotdb.db.queryengine.common.SessionInfo; import org.apache.iotdb.db.queryengine.plan.execution.config.session.PreparedStatementMemoryManager; import org.apache.iotdb.db.storageengine.dataregion.read.control.QueryResourceManager; -import org.apache.iotdb.db.utils.DataNodeAuthUtils; import org.apache.iotdb.metrics.utils.MetricLevel; import org.apache.iotdb.metrics.utils.MetricType; import org.apache.iotdb.rpc.RpcUtils; @@ -55,10 +52,7 @@ 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.Comparator; import java.util.List; import java.util.Map; @@ -148,16 +142,6 @@ public BasicOpenSessionResp login( final long userId = AuthorityChecker.getUserId(username).orElse(-1L); - Long timeToExpire = - DataNodeAuthUtils.checkPasswordExpiration(userId, password, useEncryptedPassword); - if (timeToExpire != null && timeToExpire <= System.currentTimeMillis()) { - openSessionResp - .sessionId(-1) - .setCode(TSStatusCode.ILLEGAL_PASSWORD.getStatusCode()) - .setMessage("Password has expired, please use \"ALTER USER\" to change to a new one"); - return openSessionResp; - } - boolean enableLoginLock = userId != -1; LoginLockManager loginLockManager = LoginLockManager.getInstance(); if (enableLoginLock && loginLockManager.checkLock(userId, session.getClientAddress())) { @@ -182,42 +166,6 @@ public BasicOpenSessionResp login( session.setSqlDialect(sqlDialect); supplySession(session, userId, username, ZoneId.of(zoneId), clientVersion); String logInMessage = "Login successfully"; - if (timeToExpire != null && timeToExpire != Long.MAX_VALUE) { - 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", - username); - long currentTime = CommonDateTimeUtils.currentTime(); - TSStatus tsStatus = - DataNodeAuthUtils.recordPasswordHistory( - userId, password, AuthUtils.encryptPassword(password), currentTime); - if (tsStatus.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { - openSessionResp - .sessionId(-1) - .setCode(tsStatus.getCode()) - .setMessage(tsStatus.getMessage()); - return openSessionResp; - } - timeToExpire = - CommonDateTimeUtils.convertIoTDBTimeToMillis(currentTime) - + CommonDescriptor.getInstance().getConfig().getPasswordExpirationDays() - * 1000 - * 86400; - if (timeToExpire > System.currentTimeMillis()) { - 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 .sessionId(session.getId()) .setCode(TSStatusCode.SUCCESS_STATUS.getStatusCode()) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java index 9a622a751c33c..320c904ac20ee 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java @@ -249,7 +249,6 @@ import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowConfigurationStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.StartRepairDataStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.StopRepairDataStatement; -import org.apache.iotdb.db.utils.DataNodeAuthUtils; import org.apache.iotdb.pipe.api.customizer.parameter.PipeParameters; import org.apache.iotdb.rpc.TSStatusCode; @@ -1497,7 +1496,6 @@ private void visitUpdateUser(RelationalAuthorStatement node) { throw new SemanticException("User " + node.getUserName() + " not found"); } node.setOldPassword(user.getPassword()); - DataNodeAuthUtils.verifyPasswordReuse(node.getAssociatedUserId(), node.getPassword()); } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TreeConfigTaskVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TreeConfigTaskVisitor.java index 1ea10ef37e840..362982f645ccf 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TreeConfigTaskVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TreeConfigTaskVisitor.java @@ -227,7 +227,6 @@ import org.apache.iotdb.db.queryengine.plan.statement.sys.quota.SetThrottleQuotaStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.quota.ShowSpaceQuotaStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.quota.ShowThrottleQuotaStatement; -import org.apache.iotdb.db.utils.DataNodeAuthUtils; import org.apache.iotdb.rpc.TSStatusCode; import org.apache.tsfile.exception.NotImplementedException; @@ -346,8 +345,6 @@ private void visitUpdateUser(AuthorStatement statement) { throw new SemanticException("User " + statement.getUserName() + " not found"); } statement.setPassWord(user.getPassword()); - DataNodeAuthUtils.verifyPasswordReuse( - statement.getAssociatedUsedId(), statement.getNewPassword()); } private void visitRenameUser(AuthorStatement statement) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/RelationalAuthorStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/RelationalAuthorStatement.java index 8fbf1339e4126..8509b21987d24 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/RelationalAuthorStatement.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/RelationalAuthorStatement.java @@ -22,14 +22,10 @@ import org.apache.iotdb.commons.auth.entity.PrivilegeType; import org.apache.iotdb.commons.schema.table.Audit; import org.apache.iotdb.commons.schema.table.InformationSchema; -import org.apache.iotdb.commons.utils.AuthUtils; -import org.apache.iotdb.commons.utils.CommonDateTimeUtils; import org.apache.iotdb.db.auth.AuthorityChecker; import org.apache.iotdb.db.queryengine.plan.analyze.QueryType; import org.apache.iotdb.db.queryengine.plan.relational.type.AuthorRType; -import org.apache.iotdb.db.utils.DataNodeAuthUtils; import org.apache.iotdb.rpc.RpcUtils; -import org.apache.iotdb.rpc.StatementExecutionException; import com.google.common.collect.ImmutableList; import org.apache.tsfile.utils.RamUsageEstimator; @@ -300,53 +296,6 @@ public String toString() { * @return null if the post-process succeeds, a status otherwise. */ public TSStatus onSuccess() { - if (authorType == AuthorRType.CREATE_USER) { - return onCreateUserSuccess(); - } else if (authorType == AuthorRType.UPDATE_USER) { - return onUpdateUserSuccess(); - } else if (authorType == AuthorRType.DROP_USER) { - return onDropUserSuccess(); - } - return null; - } - - private TSStatus onCreateUserSuccess() { - associatedUserId = AuthorityChecker.getUserId(userName).orElse(-1L); - // the old password is expected to be encrypted during updates, so we also encrypt it here to - // keep consistency - TSStatus tsStatus = - DataNodeAuthUtils.recordPasswordHistory( - associatedUserId, - password, - AuthUtils.encryptPassword(password), - CommonDateTimeUtils.currentTime()); - try { - RpcUtils.verifySuccess(tsStatus); - } catch (StatementExecutionException e) { - return new TSStatus(e.getStatusCode()).setMessage(e.getMessage()); - } - return null; - } - - private TSStatus onUpdateUserSuccess() { - TSStatus tsStatus = - DataNodeAuthUtils.recordPasswordHistory( - associatedUserId, password, oldPassword, CommonDateTimeUtils.currentTime()); - try { - RpcUtils.verifySuccess(tsStatus); - } catch (StatementExecutionException e) { - return new TSStatus(e.getStatusCode()).setMessage(e.getMessage()); - } - return null; - } - - private TSStatus onDropUserSuccess() { - TSStatus tsStatus = DataNodeAuthUtils.deletePasswordHistory(associatedUserId); - try { - RpcUtils.verifySuccess(tsStatus); - } catch (StatementExecutionException e) { - return new TSStatus(e.getStatusCode()).setMessage(e.getMessage()); - } return null; } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/sys/AuthorStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/sys/AuthorStatement.java index faf0db5391f79..ecc10a8ae7a52 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/sys/AuthorStatement.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/sys/AuthorStatement.java @@ -22,8 +22,6 @@ import org.apache.iotdb.common.rpc.thrift.TSStatus; import org.apache.iotdb.commons.path.PartialPath; import org.apache.iotdb.commons.schema.table.Audit; -import org.apache.iotdb.commons.utils.AuthUtils; -import org.apache.iotdb.commons.utils.CommonDateTimeUtils; import org.apache.iotdb.db.auth.AuthorityChecker; import org.apache.iotdb.db.queryengine.plan.analyze.QueryType; import org.apache.iotdb.db.queryengine.plan.statement.AuthorType; @@ -31,9 +29,7 @@ import org.apache.iotdb.db.queryengine.plan.statement.Statement; import org.apache.iotdb.db.queryengine.plan.statement.StatementType; import org.apache.iotdb.db.queryengine.plan.statement.StatementVisitor; -import org.apache.iotdb.db.utils.DataNodeAuthUtils; import org.apache.iotdb.rpc.RpcUtils; -import org.apache.iotdb.rpc.StatementExecutionException; import java.util.Collections; import java.util.List; @@ -265,53 +261,6 @@ public List getPaths() { * @return null if the post-process succeeds, a status otherwise. */ public TSStatus onSuccess() { - if (authorType == AuthorType.CREATE_USER) { - return onCreateUserSuccess(); - } else if (authorType == AuthorType.UPDATE_USER) { - return onUpdateUserSuccess(); - } else if (authorType == AuthorType.DROP_USER) { - return onDropUserSuccess(); - } - return null; - } - - private TSStatus onCreateUserSuccess() { - associatedUsedId = AuthorityChecker.getUserId(userName).orElse(-1L); - // the old password is expected to be encrypted during updates, so we also encrypt it here to - // keep consistency - TSStatus tsStatus = - DataNodeAuthUtils.recordPasswordHistory( - associatedUsedId, - password, - AuthUtils.encryptPassword(password), - CommonDateTimeUtils.currentTime()); - try { - RpcUtils.verifySuccess(tsStatus); - } catch (StatementExecutionException e) { - return new TSStatus(e.getStatusCode()).setMessage(e.getMessage()); - } - return null; - } - - private TSStatus onUpdateUserSuccess() { - TSStatus tsStatus = - DataNodeAuthUtils.recordPasswordHistory( - associatedUsedId, newPassword, password, CommonDateTimeUtils.currentTime()); - try { - RpcUtils.verifySuccess(tsStatus); - } catch (StatementExecutionException e) { - return new TSStatus(e.getStatusCode()).setMessage(e.getMessage()); - } - return null; - } - - private TSStatus onDropUserSuccess() { - TSStatus tsStatus = DataNodeAuthUtils.deletePasswordHistory(associatedUsedId); - try { - RpcUtils.verifySuccess(tsStatus); - } catch (StatementExecutionException e) { - return new TSStatus(e.getStatusCode()).setMessage(e.getMessage()); - } return null; } 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 deleted file mode 100644 index 6ee378282adb2..0000000000000 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/DataNodeAuthUtils.java +++ /dev/null @@ -1,370 +0,0 @@ -/* - * 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.iotdb.db.utils; - -import org.apache.iotdb.common.rpc.thrift.TSStatus; -import org.apache.iotdb.commons.audit.UserEntity; -import org.apache.iotdb.commons.conf.CommonDescriptor; -import org.apache.iotdb.commons.exception.IllegalPathException; -import org.apache.iotdb.commons.exception.IoTDBException; -import org.apache.iotdb.commons.exception.IoTDBRuntimeException; -import org.apache.iotdb.commons.path.PartialPath; -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.audit.DNAuditLogger; -import org.apache.iotdb.db.auth.AuthorityChecker; -import org.apache.iotdb.db.conf.IoTDBDescriptor; -import org.apache.iotdb.db.exception.sql.SemanticException; -import org.apache.iotdb.db.protocol.session.SessionManager; -import org.apache.iotdb.db.queryengine.common.SessionInfo; -import org.apache.iotdb.db.queryengine.plan.Coordinator; -import org.apache.iotdb.db.queryengine.plan.analyze.ClusterPartitionFetcher; -import org.apache.iotdb.db.queryengine.plan.analyze.schema.ClusterSchemaFetcher; -import org.apache.iotdb.db.queryengine.plan.execution.ExecutionResult; -import org.apache.iotdb.db.queryengine.plan.execution.IQueryExecution; -import org.apache.iotdb.db.queryengine.plan.parser.StatementGenerator; -import org.apache.iotdb.db.queryengine.plan.statement.Statement; -import org.apache.iotdb.db.queryengine.plan.statement.crud.InsertRowStatement; -import org.apache.iotdb.db.queryengine.plan.statement.metadata.DeleteTimeSeriesStatement; -import org.apache.iotdb.rpc.TSStatusCode; -import org.apache.iotdb.service.rpc.thrift.TSLastDataQueryReq; - -import org.apache.tsfile.enums.TSDataType; -import org.apache.tsfile.read.common.block.TsBlock; -import org.apache.tsfile.utils.Binary; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.charset.StandardCharsets; -import java.time.ZoneId; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.Optional; - -public class DataNodeAuthUtils { - - private DataNodeAuthUtils() {} - - private static final Logger LOGGER = LoggerFactory.getLogger(DataNodeAuthUtils.class); - - /** - * @return the timestamp when the password of the user is lastly changed from the given one to a - * new one, or -1 if the password has not been changed. - */ - public static long getPasswordChangeTimeMillis(long userId, String password) { - - long queryId = -1; - try { - Statement statement = - StatementGenerator.createStatement( - "SELECT password from " - + DNAuditLogger.PREFIX_PASSWORD_HISTORY - + ".`_" - + userId - + "` where oldPassword='" - + AuthUtils.encryptPassword(password) - + "' order by time desc limit 1", - ZoneId.systemDefault()); - - SessionInfo sessionInfo = - new SessionInfo( - 0, - new UserEntity( - AuthorityChecker.INTERNAL_AUDIT_USER_ID, - AuthorityChecker.INTERNAL_AUDIT_USER, - IoTDBDescriptor.getInstance().getConfig().getInternalAddress()), - ZoneId.systemDefault()); - - queryId = SessionManager.getInstance().requestQueryId(); - ExecutionResult result = - Coordinator.getInstance() - .executeForTreeModel( - statement, - queryId, - sessionInfo, - "", - ClusterPartitionFetcher.getInstance(), - ClusterSchemaFetcher.getInstance()); - if (result.status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { - LOGGER.warn("Fail to get password change time: {}", result.status); - return -1; - } - - IQueryExecution queryExecution = Coordinator.getInstance().getQueryExecution(queryId); - TsBlock lastTsBlock; - Optional batchResult = queryExecution.getBatchResult(); - lastTsBlock = batchResult.orElse(null); - if (lastTsBlock != null) { - if (lastTsBlock.getPositionCount() <= 0) { - // no password history, may have upgraded from an older version - return -1; - } - long timeByIndex = lastTsBlock.getTimeByIndex(lastTsBlock.getPositionCount() - 1); - return CommonDateTimeUtils.convertIoTDBTimeToMillis(timeByIndex); - } - } catch (IoTDBException e) { - LOGGER.warn("Cannot generate query for checking password reuse interval", e); - } finally { - if (queryId != -1) { - Coordinator.getInstance().cleanupQueryExecution(queryId); - } - } - return -1; - } - - public static void verifyPasswordReuse(long userId, String password) { - long passwordReuseIntervalDays = - CommonDescriptor.getInstance().getConfig().getPasswordReuseIntervalDays(); - if (password == null || passwordReuseIntervalDays <= 0) { - return; - } - - long passwordChangeTime = DataNodeAuthUtils.getPasswordChangeTimeMillis(userId, password); - long currentTimeMillis = System.currentTimeMillis(); - long elapsedTime = currentTimeMillis - passwordChangeTime; - long reuseIntervalMillis = - passwordReuseIntervalDays * 1000 * 86400 > 0 - ? passwordReuseIntervalDays * 1000 * 86400 - : Long.MAX_VALUE; - if (elapsedTime <= reuseIntervalMillis) { - throw new SemanticException( - String.format( - "The password has been used recently, and it cannot be reused before %s", - new Date(passwordChangeTime + reuseIntervalMillis))); - } - LOGGER.info( - "It has been {}ms, since the password was changed {} -> {}", - elapsedTime, - passwordChangeTime, - currentTimeMillis); - } - - public static TSStatus recordPasswordHistory( - long userId, String password, String oldEncryptedPassword, long timeToRecord) { - InsertRowStatement insertRowStatement = new InsertRowStatement(); - try { - insertRowStatement.setDevicePath( - new PartialPath(DNAuditLogger.PREFIX_PASSWORD_HISTORY + ".`_" + userId + "`")); - insertRowStatement.setTime(timeToRecord); - insertRowStatement.setMeasurements(new String[] {"password", "oldPassword"}); - insertRowStatement.setValues( - new Object[] { - new Binary(AuthUtils.encryptPassword(password), StandardCharsets.UTF_8), - oldEncryptedPassword == null - ? null - : new Binary(oldEncryptedPassword, StandardCharsets.UTF_8) - }); - insertRowStatement.setDataTypes(new TSDataType[] {TSDataType.STRING, TSDataType.STRING}); - } catch (IllegalPathException ignored) { - return new TSStatus(TSStatusCode.INTERNAL_SERVER_ERROR.getStatusCode()) - .setMessage( - "Cannot create password history for " + userId + " because the path will be illegal"); - } - - long queryId = -1; - try { - SessionInfo sessionInfo = - new SessionInfo( - 0, - new UserEntity( - AuthorityChecker.INTERNAL_AUDIT_USER_ID, - AuthorityChecker.INTERNAL_AUDIT_USER, - IoTDBDescriptor.getInstance().getConfig().getInternalAddress()), - ZoneId.systemDefault()); - - queryId = SessionManager.getInstance().requestQueryId(); - ExecutionResult result = - Coordinator.getInstance() - .executeForTreeModel( - insertRowStatement, - queryId, - sessionInfo, - "", - ClusterPartitionFetcher.getInstance(), - ClusterSchemaFetcher.getInstance()); - return result.status; - } catch (Exception e) { - if (CommonDescriptor.getInstance().getConfig().isMayBypassPasswordCheckInException()) { - return StatusUtils.OK; - } - LOGGER.error("Cannot create password history for {}", userId, e); - return new TSStatus(TSStatusCode.INTERNAL_SERVER_ERROR.getStatusCode()) - .setMessage("The server is not ready for login, please check the server log for details"); - } finally { - if (queryId != -1) { - Coordinator.getInstance().cleanupQueryExecution(queryId); - } - } - } - - public static TSStatus deletePasswordHistory(long userId) { - DeleteTimeSeriesStatement deleteTimeSeriesStatement = new DeleteTimeSeriesStatement(); - deleteTimeSeriesStatement.setMayDeleteAudit(true); - try { - PartialPath devicePath = - new PartialPath(DNAuditLogger.PREFIX_PASSWORD_HISTORY + ".`_" + userId + "`"); - deleteTimeSeriesStatement.setPathPatternList( - Arrays.asList( - devicePath.concatAsMeasurementPath("password"), - devicePath.concatAsMeasurementPath("oldPassword"))); - } catch (IllegalPathException ignored) { - return new TSStatus(TSStatusCode.INTERNAL_SERVER_ERROR.getStatusCode()) - .setMessage( - "Cannot delete password history for " + userId + " because the path will be illegal"); - } - - long queryId = -1; - try { - SessionInfo sessionInfo = - new SessionInfo( - 0, - new UserEntity( - AuthorityChecker.INTERNAL_AUDIT_USER_ID, - AuthorityChecker.INTERNAL_AUDIT_USER, - IoTDBDescriptor.getInstance().getConfig().getInternalAddress()), - ZoneId.systemDefault()); - - queryId = SessionManager.getInstance().requestQueryId(); - ExecutionResult result = - Coordinator.getInstance() - .executeForTreeModel( - deleteTimeSeriesStatement, - queryId, - sessionInfo, - "", - ClusterPartitionFetcher.getInstance(), - ClusterSchemaFetcher.getInstance()); - return result.status; - } catch (Exception e) { - if (CommonDescriptor.getInstance().getConfig().isMayBypassPasswordCheckInException()) { - return StatusUtils.OK; - } - LOGGER.error("Cannot delete password history for {}", userId, e); - return new TSStatus(TSStatusCode.INTERNAL_SERVER_ERROR.getStatusCode()) - .setMessage( - "The server is not ready for this operation, please check the server log for details"); - } finally { - if (queryId != -1) { - Coordinator.getInstance().cleanupQueryExecution(queryId); - } - } - } - - /** - * Check if the password for the give user has expired. - * - * @return the timestamp when the password will expire. Long.MAX if the password never expires. - * Null if the password history cannot be found. - */ - public static Long checkPasswordExpiration( - final long userId, final String password, final boolean useEncryptedPassword) { - if (userId == -1) { - return null; - } - - // check password expiration - long passwordExpirationDays = - CommonDescriptor.getInstance().getConfig().getPasswordExpirationDays(); - boolean mayBypassPasswordCheckInException = - CommonDescriptor.getInstance().getConfig().isMayBypassPasswordCheckInException(); - - TSLastDataQueryReq lastDataQueryReq = new TSLastDataQueryReq(); - lastDataQueryReq.setSessionId(0); - lastDataQueryReq.setPaths( - Collections.singletonList( - DNAuditLogger.PREFIX_PASSWORD_HISTORY + ".`_" + userId + "`.password")); - - long queryId = -1; - try { - Statement statement = StatementGenerator.createStatement(lastDataQueryReq); - SessionInfo sessionInfo = - new SessionInfo( - 0, - new UserEntity( - AuthorityChecker.INTERNAL_AUDIT_USER_ID, - AuthorityChecker.INTERNAL_AUDIT_USER, - IoTDBDescriptor.getInstance().getConfig().getInternalAddress()), - ZoneId.systemDefault()); - - queryId = SessionManager.getInstance().requestQueryId(); - ExecutionResult result = - Coordinator.getInstance() - .executeForTreeModel( - statement, - queryId, - sessionInfo, - "", - ClusterPartitionFetcher.getInstance(), - ClusterSchemaFetcher.getInstance()); - if (result.status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { - LOGGER.warn("Fail to check password expiration: {}", result.status); - throw new IoTDBRuntimeException( - "Cannot query password history because: " - + result - + ", please log in later or disable password expiration.", - result.status.getCode()); - } - - IQueryExecution queryExecution = Coordinator.getInstance().getQueryExecution(queryId); - Optional batchResult = queryExecution.getBatchResult(); - if (batchResult.isPresent()) { - TsBlock tsBlock = batchResult.get(); - if (tsBlock.getPositionCount() <= 0) { - // no password history, may have upgraded from an older version - return null; - } - long lastPasswordTime = - CommonDateTimeUtils.convertIoTDBTimeToMillis(tsBlock.getTimeByIndex(0)); - // columns of last query: [timeseriesName, value, dataType] - String oldPassword = tsBlock.getColumn(1).getBinary(0).toString(); - if (oldPassword.equals( - useEncryptedPassword ? password : AuthUtils.encryptPassword(password))) { - if (lastPasswordTime + passwordExpirationDays * 1000 * 86400 <= lastPasswordTime) { - // overflow or passwordExpirationDays <= 0 - return Long.MAX_VALUE; - } else { - return lastPasswordTime + passwordExpirationDays * 1000 * 86400; - } - } else { - // 1. the password is incorrect, later logIn will fail - // 2. the password history does not record correctly, use the current time to create one - return null; - } - } else { - return null; - } - } 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()); - } - } finally { - if (queryId != -1) { - Coordinator.getInstance().cleanupQueryExecution(queryId); - } - } - } -} 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 ff4a47b6f84ab..4f1e83bab812b 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 @@ -459,9 +459,6 @@ public class CommonConfig { private String userEncryptTokenHint = "not set yet"; private boolean enforceStrongPassword = false; - private long passwordExpirationDays = -1; - // an old password cannot be reused within the given interval if >= 0. - private long passwordReuseIntervalDays = -1; private boolean mayBypassPasswordCheckInException = true; /** whether to enable the audit log * */ @@ -2726,22 +2723,6 @@ public void setEnforceStrongPassword(boolean enforceStrongPassword) { this.enforceStrongPassword = enforceStrongPassword; } - public long getPasswordExpirationDays() { - return passwordExpirationDays; - } - - public void setPasswordExpirationDays(long passwordExpirationDays) { - this.passwordExpirationDays = passwordExpirationDays; - } - - public long getPasswordReuseIntervalDays() { - return passwordReuseIntervalDays; - } - - public void setPasswordReuseIntervalDays(long passwordReuseIntervalDays) { - this.passwordReuseIntervalDays = passwordReuseIntervalDays; - } - public boolean isMayBypassPasswordCheckInException() { return mayBypassPasswordCheckInException; }