Copilot commented on code in PR #13953:
URL: https://github.com/apache/cloudstack/pull/13953#discussion_r4334980491


##########
plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/SAML2AuthManagerImplTest.java:
##########
@@ -80,6 +97,39 @@ public void setUp() throws NoSuchFieldException, 
IllegalAccessException {
         Mockito.doReturn(true).when(saml2AuthManager).isSAMLPluginEnabled();
     }
 
+    @After
+    public void tearDown() {
+        resetConfigKeyValue(SAML2AuthManager.EnableLoginAfterSAMLDisable);
+    }
+
+    private static <T> void setConfigKeyValue(ConfigKey<T> configKey, T value) 
{
+        try {
+            Field valueField = ConfigKey.class.getDeclaredField("_value");
+            valueField.setAccessible(true);
+            valueField.set(configKey, value);
+
+            Field dynamicField = 
ConfigKey.class.getDeclaredField("_isDynamic");
+            dynamicField.setAccessible(true);
+            dynamicField.setBoolean(configKey, false);
+        } catch (IllegalAccessException | NoSuchFieldException e) {
+            throw new RuntimeException("Failed to set ConfigKey value", e);
+        }
+    }
+
+    private static void resetConfigKeyValue(ConfigKey<?> configKey) {
+        try {
+            Field valueField = ConfigKey.class.getDeclaredField("_value");
+            valueField.setAccessible(true);
+            valueField.set(configKey, null);
+
+            Field dynamicField = 
ConfigKey.class.getDeclaredField("_isDynamic");
+            dynamicField.setAccessible(true);
+            dynamicField.setBoolean(configKey, true);
+        } catch (IllegalAccessException | NoSuchFieldException e) {
+            throw new RuntimeException("Failed to reset ConfigKey value", e);
+        }
+    }

Review Comment:
   The tests mutate `ConfigKey` internals (`_value`, `_isDynamic`) globally via 
reflection, but the teardown resets to hardcoded defaults (`null` / `true`) 
instead of restoring the prior values. This can leak state into other tests in 
the same JVM and cause order-dependent failures. Prefer capturing the original 
`_value` and `_isDynamic` for `EnableLoginAfterSAMLDisable` before overriding 
(e.g., in `@Before`) and restoring those exact originals in `@After`; 
alternatively use any existing test utility/framework mechanism for temporarily 
overriding ConfigKeys to avoid reflective dependence on private fields.



##########
plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/SAML2AuthManagerImplTest.java:
##########
@@ -117,7 +167,142 @@ public void testAuthorizeUser() {
         Mockito.verify(userDao, 
Mockito.atLeastOnce()).update(Mockito.anyLong(), Mockito.any(user.getClass()));
     }
 
+    @Test
+    public void testAuthorizeUserStoresPreSamlSourceOnEnable() {
+        UserVO user = new UserVO(200L);
+        user.setUsername("someuser");
+        user.setSource(User.Source.LDAP);
+        when(userDao.getUser(Mockito.anyLong())).thenReturn(user);
+
+        saml2AuthManager.authorizeUser(200L, "someID", true);
+
+        verify(userDetailsDao).addDetail(200L, "PreSamlSource", "LDAP", false);
+        assertEquals(User.Source.SAML2, user.getSource());
+    }
+
+    @Test
+    public void testAuthorizeUserDoesNotStorePreSamlSourceWhenAlreadySaml() {

Review Comment:
   This hunk introduces CRLF/LF inconsistency (visible as stray `\r` characters 
after `@Test` / method lines). Mixed line endings frequently trigger 
formatting/checkstyle diffs and can be disruptive in reviews. Please normalize 
the file’s line endings (ideally LF) and re-save the file so these carriage 
returns are removed.



##########
plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java:
##########
@@ -446,26 +455,52 @@ public boolean isUserAuthorized(Long userId, String 
entityId) {
     @Override
     public boolean authorizeUser(Long userId, String entityId, boolean enable) 
{
         UserVO user = _userDao.getUser(userId);
-        if (user != null) {
-            if (enable) {
-                user.setExternalEntity(entityId);
-                user.setSource(User.Source.SAML2);
-            } else {
-                boolean enableLoginAfterSAMLDisable =  
SAML2AuthManager.EnableLoginAfterSAMLDisable.value();
-                if (user.getSource().equals(User.Source.SAML2)) {
-                    if(enableLoginAfterSAMLDisable) {
-                        user.setSource(User.Source.UNKNOWN);
-                    } else {
-                        user.setSource(User.Source.SAML2DISABLED);
-                    }
-                } else {
-                    return false;
-                }
+        if (user == null) {
+            return false;
+        }
+        if (enable) {
+            enableSAMLForUser(user, entityId);
+        } else if (!disableSAMLForUser(user)) {
+            return false;
+        }
+        _userDao.update(user.getId(), user);
+        return true;
+    }
+
+    private void enableSAMLForUser(UserVO user, String entityId) {
+        if (user.getSource() != null && 
!User.Source.SAML2.equals(user.getSource()) && 
!User.Source.SAML2DISABLED.equals(user.getSource())) {
+            userDetailsDao.addDetail(user.getId(), PRE_SAML_SOURCE_DETAIL_KEY, 
user.getSource().name(), false);
+        }
+        user.setExternalEntity(entityId);
+        user.setSource(User.Source.SAML2);
+    }

Review Comment:
   `addDetail(...)` is called every time SAML is enabled for a user with a 
non-SAML source, without checking for an existing `PreSamlSource` entry. If 
`addDetail` inserts rather than upserts, repeated enable operations could 
accumulate rows for the same key and complicate restores/debugging. Consider 
making this write idempotent by updating an existing detail (or 
deleting/replacing) when the key is already present.



##########
plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java:
##########
@@ -115,6 +121,9 @@ public String getSAMLIdentityProviderMetadataURL(){
     @Inject
     private UserDao _userDao;
 
+    @Inject
+    private UserDetailsDao userDetailsDao;

Review Comment:
   The newly added field name `userDetailsDao` is inconsistent with the 
surrounding member naming pattern (e.g., `_userDao`, `_domainMgr`). To keep the 
class consistent and easier to scan, rename this field to match the existing 
convention (for example `_userDetailsDao`) and update references accordingly.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to