You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by pr...@apache.org on 2026/08/25 08:34:30 UTC
(ranger) 01/01: RANGER-5756: Make J10056 skip automatic reactivation of disabled external users (#1176)
This is an automated email from the ASF dual-hosted git repository.
pradeepagrawal8184 pushed a commit to branch RANGER-5756_210
in repository https://gitbox.apache.org/repos/asf/ranger.git
commit dfe6e2845c52ddc2e3ad14a2303b34b75c1727ef
Author: PradeeP AgrawaL <pr...@apache.org>
AuthorDate: Tue Aug 25 13:12:56 2026 +0530
RANGER-5756: Make J10056 skip automatic reactivation of disabled external users (#1176)
---
.../PatchForExternalUserStatusUpdate_J10056.java | 133 +++++++++----------
...estPatchForExternalUserStatusUpdate_J10056.java | 143 +++++++++++++++++++++
2 files changed, 202 insertions(+), 74 deletions(-)
diff --git a/security-admin/src/main/java/org/apache/ranger/patch/PatchForExternalUserStatusUpdate_J10056.java b/security-admin/src/main/java/org/apache/ranger/patch/PatchForExternalUserStatusUpdate_J10056.java
index f4a122b38..dcd167fdc 100644
--- a/security-admin/src/main/java/org/apache/ranger/patch/PatchForExternalUserStatusUpdate_J10056.java
+++ b/security-admin/src/main/java/org/apache/ranger/patch/PatchForExternalUserStatusUpdate_J10056.java
@@ -17,8 +17,6 @@
package org.apache.ranger.patch;
-import java.util.List;
-
import org.apache.commons.collections.CollectionUtils;
import org.apache.ranger.common.RangerCommonEnums;
import org.apache.ranger.db.RangerDaoManager;
@@ -28,81 +26,68 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
-import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.TransactionDefinition;
-import org.springframework.transaction.TransactionStatus;
-import org.springframework.transaction.support.TransactionCallback;
-import org.springframework.transaction.support.TransactionTemplate;
+
+import java.util.List;
@Component
public class PatchForExternalUserStatusUpdate_J10056 extends BaseLoader {
+ private static final Logger logger = LoggerFactory.getLogger(PatchForExternalUserStatusUpdate_J10056.class);
+
+ @Autowired
+ private RangerDaoManager daoManager;
+
+ public static void main(String[] args) {
+ try {
+ PatchForExternalUserStatusUpdate_J10056 loader = (PatchForExternalUserStatusUpdate_J10056) CLIUtil.getBean(PatchForExternalUserStatusUpdate_J10056.class);
+
+ loader.init();
+
+ while (loader.isMoreToProcess()) {
+ loader.load();
+ }
+
+ logger.info("Load complete. Exiting!!!");
+
+ System.exit(0);
+ } catch (Exception e) {
+ logger.error("Error loading", e);
+
+ System.exit(1);
+ }
+ }
+
+ @Override
+ public void init() throws Exception {
+ // Do Nothing
+ }
+
+ @Override
+ public void printStats() {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void execLoad() {
+ updateExternalUserStatus();
+ }
+
+ private void updateExternalUserStatus() {
+ XXPortalUserDao dao = this.daoManager.getXXPortalUser();
+ List<XXPortalUser> xXPortalUsers = dao.findByUserSourceAndStatus(RangerCommonEnums.USER_EXTERNAL, RangerCommonEnums.ACT_STATUS_DISABLED);
+
+ if (CollectionUtils.isEmpty(xXPortalUsers)) {
+ return;
+ }
+
+ // Do not bulk-reactivate external disabled users. Disabled is a valid administrative state (see XUserREST.modifyUserActiveStatus),
+ // and this patch cannot distinguish accounts left disabled by an old usersync bug from accounts disabled on purpose.
+ logger.warn("updateExternalUserStatus(): Skipping automatic reactivation of {} external disabled user(s). Re-enable affected accounts explicitly via Ranger Admin if required.", xXPortalUsers.size());
- private static final Logger logger = LoggerFactory.getLogger(PatchForExternalUserStatusUpdate_J10056.class);
-
- @Autowired
- private RangerDaoManager daoManager;
-
- @Autowired
- @Qualifier(value = "transactionManager")
- PlatformTransactionManager txManager;
-
- public static void main(String[] args) {
- try {
- PatchForExternalUserStatusUpdate_J10056 loader = (PatchForExternalUserStatusUpdate_J10056) CLIUtil
- .getBean(PatchForExternalUserStatusUpdate_J10056.class);
- loader.init();
- while (loader.isMoreToProcess()) {
- loader.load();
- }
- logger.info("Load complete. Exiting!!!");
- System.exit(0);
- } catch (Exception e) {
- logger.error("Error loading", e);
- System.exit(1);
- }
- }
-
- @Override
- public void init() throws Exception {
- // Do Nothing
- }
-
- @Override
- public void printStats() {
- // TODO Auto-generated method stub
- }
-
- @Override
- public void execLoad() {
- updateExternalUserStatus();
- }
-
- private void updateExternalUserStatus() {
- XXPortalUserDao dao = this.daoManager.getXXPortalUser();
- List<XXPortalUser> xXPortalUsers = dao.findByUserSourceAndStatus(RangerCommonEnums.USER_EXTERNAL,RangerCommonEnums.ACT_STATUS_DISABLED);
-
- if(CollectionUtils.isNotEmpty(xXPortalUsers)) {
- for (XXPortalUser xxPortalUser : xXPortalUsers) {
- if (xxPortalUser != null) {
- xxPortalUser.setStatus(RangerCommonEnums.ACT_STATUS_ACTIVE);
- TransactionTemplate txTemplate = new TransactionTemplate(txManager);
- txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
- try {
- txTemplate.execute(new TransactionCallback<Object>() {
- @Override
- public Object doInTransaction(TransactionStatus status) {
- dao.update(xxPortalUser, true);
- return null;
- }
- });
- } catch (Throwable ex) {
- logger.error("updateExternalUserStatus(): Failed to update DB for user: " + xxPortalUser.getLoginId() + " ", ex);
- throw new RuntimeException(ex);
- }
- }
- }
- }
- }
+ for (XXPortalUser xxPortalUser : xXPortalUsers) {
+ if (xxPortalUser != null) {
+ logger.warn("updateExternalUserStatus(): Left unchanged (loginId={})", xxPortalUser.getLoginId());
+ }
+ }
+ }
}
diff --git a/security-admin/src/test/java/org/apache/ranger/patch/TestPatchForExternalUserStatusUpdate_J10056.java b/security-admin/src/test/java/org/apache/ranger/patch/TestPatchForExternalUserStatusUpdate_J10056.java
new file mode 100644
index 000000000..c16772d29
--- /dev/null
+++ b/security-admin/src/test/java/org/apache/ranger/patch/TestPatchForExternalUserStatusUpdate_J10056.java
@@ -0,0 +1,143 @@
+/*
+ * 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.ranger.patch;
+
+import org.apache.ranger.biz.ServiceDBStore;
+import org.apache.ranger.common.JSONUtil;
+import org.apache.ranger.common.RangerCommonEnums;
+import org.apache.ranger.common.RangerValidatorFactory;
+import org.apache.ranger.common.StringUtil;
+import org.apache.ranger.db.RangerDaoManager;
+import org.apache.ranger.db.XXPortalUserDao;
+import org.apache.ranger.entity.XXPortalUser;
+import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
+import org.apache.ranger.service.RangerPolicyService;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * @generated by Cursor
+ * @description <Unit Test for PatchForExternalUserStatusUpdate_J10056 class>
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestPatchForExternalUserStatusUpdate_J10056 {
+ private static void setIfPresent(Object target, String fieldName, Object value) {
+ try {
+ Field f = target.getClass().getDeclaredField(fieldName);
+ f.setAccessible(true);
+ f.set(target, value);
+ } catch (NoSuchFieldException ignored) {
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Test
+ public void testExecLoadAndPrintStats() {
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock = Mockito.mockStatic(EmbeddedServiceDefsUtil.class)) {
+ EmbeddedServiceDefsUtil util = Mockito.mock(EmbeddedServiceDefsUtil.class);
+ utilMock.when(EmbeddedServiceDefsUtil::instance).thenReturn(util);
+
+ PatchForExternalUserStatusUpdate_J10056 patch = new PatchForExternalUserStatusUpdate_J10056();
+ ServiceDBStore svcStore = Mockito.mock(ServiceDBStore.class);
+ RangerDaoManager daoMgr = Mockito.mock(RangerDaoManager.class);
+ XXPortalUserDao xxPortalUserDao = Mockito.mock(XXPortalUserDao.class);
+ Mockito.when(daoMgr.getXXPortalUser()).thenReturn(xxPortalUserDao);
+ Mockito.when(xxPortalUserDao.findByUserSourceAndStatus(Mockito.anyInt(), Mockito.anyInt()))
+ .thenReturn(Collections.emptyList());
+
+ setIfPresent(patch, "daoManager", daoMgr);
+ setIfPresent(patch, "svcDBStore", svcStore);
+ setIfPresent(patch, "jsonUtil", new JSONUtil());
+ setIfPresent(patch, "policyService", Mockito.mock(RangerPolicyService.class));
+ setIfPresent(patch, "stringUtil", new StringUtil());
+ setIfPresent(patch, "validatorFactory", Mockito.mock(RangerValidatorFactory.class));
+ setIfPresent(patch, "svcStore", svcStore);
+
+ patch.execLoad();
+ patch.printStats();
+ }
+ }
+
+ @Test
+ public void testExecLoad_DoesNotReactivateDisabledExternalUsers() {
+ PatchForExternalUserStatusUpdate_J10056 patch = new PatchForExternalUserStatusUpdate_J10056();
+
+ RangerDaoManager daoMgr = Mockito.mock(RangerDaoManager.class);
+ XXPortalUserDao xxPortalUserDao = Mockito.mock(XXPortalUserDao.class);
+ Mockito.when(daoMgr.getXXPortalUser()).thenReturn(xxPortalUserDao);
+
+ XXPortalUser user = new XXPortalUser();
+ user.setLoginId("u1");
+ user.setStatus(RangerCommonEnums.ACT_STATUS_DISABLED);
+ Mockito.when(xxPortalUserDao.findByUserSourceAndStatus(Mockito.anyInt(), Mockito.anyInt()))
+ .thenReturn(Collections.singletonList(user));
+
+ setIfPresent(patch, "daoManager", daoMgr);
+
+ patch.execLoad();
+
+ Assertions.assertEquals(RangerCommonEnums.ACT_STATUS_DISABLED, user.getStatus());
+ Mockito.verify(xxPortalUserDao, Mockito.never()).update(Mockito.any(XXPortalUser.class), Mockito.eq(true));
+ }
+
+ @Test
+ public void testExecLoad_NoUsers_NoAction() {
+ PatchForExternalUserStatusUpdate_J10056 patch = new PatchForExternalUserStatusUpdate_J10056();
+ RangerDaoManager daoMgr = Mockito.mock(RangerDaoManager.class);
+ XXPortalUserDao xxPortalUserDao = Mockito.mock(XXPortalUserDao.class);
+ Mockito.when(daoMgr.getXXPortalUser()).thenReturn(xxPortalUserDao);
+ Mockito.when(xxPortalUserDao.findByUserSourceAndStatus(Mockito.anyInt(), Mockito.anyInt()))
+ .thenReturn(Collections.emptyList());
+ setIfPresent(patch, "daoManager", daoMgr);
+
+ patch.execLoad();
+
+ Mockito.verify(xxPortalUserDao, Mockito.never()).update(Mockito.any(XXPortalUser.class), Mockito.eq(true));
+ }
+
+ @Test
+ public void testExecLoad_NullUserEntry_Skipped() {
+ PatchForExternalUserStatusUpdate_J10056 patch = new PatchForExternalUserStatusUpdate_J10056();
+ RangerDaoManager daoMgr = Mockito.mock(RangerDaoManager.class);
+ XXPortalUserDao xxPortalUserDao = Mockito.mock(XXPortalUserDao.class);
+ Mockito.when(daoMgr.getXXPortalUser()).thenReturn(xxPortalUserDao);
+ Mockito.when(xxPortalUserDao.findByUserSourceAndStatus(Mockito.anyInt(), Mockito.anyInt()))
+ .thenReturn(new ArrayList<XXPortalUser>() {
+ {
+ add(null);
+ }
+ });
+ setIfPresent(patch, "daoManager", daoMgr);
+
+ patch.execLoad();
+
+ Mockito.verify(xxPortalUserDao, Mockito.never()).update(Mockito.any(XXPortalUser.class), Mockito.eq(true));
+ }
+}