github-advanced-security[bot] commented on code in PR #1612:
URL: https://github.com/apache/syncope/pull/1612#discussion_r4524768224


##########
core/idrepo/logic/src/test/java/org/apache/syncope/core/logic/AbstractUserLogicTest.java:
##########
@@ -0,0 +1,303 @@
+/*
+ * 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.syncope.core.logic;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Optional;
+import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.request.StatusR;
+import org.apache.syncope.common.lib.request.UserCR;
+import org.apache.syncope.common.lib.request.UserUR;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.StatusRType;
+import org.apache.syncope.core.persistence.api.EncryptorManager;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
+import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
+import org.apache.syncope.core.provisioning.api.jexl.TemplateUtils;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class AbstractUserLogicTest {
+
+    private static class TestLogic extends AbstractUserLogic {
+
+        TestLogic(
+                final RealmSearchDAO realmSearchDAO,
+                final AnyTypeDAO anyTypeDAO,
+                final TemplateUtils templateUtils,
+                final UserDAO userDAO,
+                final UserDataBinder binder,
+                final UserProvisioningManager provisioningManager,
+                final EncryptorManager encryptorManager,
+                final ConfParamOps confParamOps) {
+
+            super(realmSearchDAO, anyTypeDAO, templateUtils, userDAO, binder, 
provisioningManager,
+                    encryptorManager, confParamOps);
+        }
+
+        ProvisioningResult<UserTO> create(final UserCR userCR) {
+            return doCreate(userCR, false, false);
+        }
+
+        ProvisioningResult<UserTO> update(final UserUR userUR) {
+            return doUpdate(userUR, false, false);
+        }
+
+        ProvisioningResult<UserTO> status(final StatusR statusR) {
+            return doStatus(statusR, false);
+        }
+
+        ProvisioningResult<UserTO> delete(final UserTO userTO) {
+            return doDelete(userTO, false, false);
+        }
+
+        public UserTO requestPasswordReset(final String username) {

Review Comment:
   ## CodeQL / Useless parameter
   
   The parameter 'username' is never used.
   
   [Show more 
details](https://github.com/apache/syncope/security/code-scanning/2707)



##########
core/self-keymaster-starter/src/test/java/org/apache/syncope/core/keymaster/rest/security/SelfKeymasterUsernamePasswordAuthenticationProviderTest.java:
##########
@@ -0,0 +1,190 @@
+/*
+ * 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.syncope.core.keymaster.rest.security;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Set;
+import javax.cache.Cache;
+import org.apache.syncope.common.keymaster.client.api.DomainOps;
+import org.apache.syncope.common.keymaster.client.api.KeymasterProperties;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.EntitlementsHolder;
+import org.apache.syncope.common.lib.types.IdRepoEntitlement;
+import org.apache.syncope.core.persistence.api.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.EncryptorManager;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
+import org.apache.syncope.core.spring.security.AuthDataAccessor;
+import org.apache.syncope.core.spring.security.SecurityProperties;
+import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
+import org.apache.syncope.core.spring.security.SyncopeGrantedAuthority;
+import org.apache.syncope.core.spring.security.throttle.ThrottlerAttempts;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.support.StaticApplicationContext;
+import org.springframework.security.authentication.BadCredentialsException;
+import 
org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+class SelfKeymasterUsernamePasswordAuthenticationProviderTest {
+
+    private final DomainOps domainOps = mock(DomainOps.class);
+
+    private final AuthDataAccessor dataAccessor = mock(AuthDataAccessor.class);
+
+    private final UserProvisioningManager provisioningManager = 
mock(UserProvisioningManager.class);
+
+    private final EncryptorManager encryptorManager = 
mock(EncryptorManager.class);
+
+    @SuppressWarnings("unchecked")
+    private final Cache<String, ThrottlerAttempts> throttlerCache = 
mock(Cache.class);
+
+    private SecurityProperties securityProperties;
+
+    private KeymasterProperties keymasterProperties;
+
+    private StaticApplicationContext context;
+
+    private SelfKeymasterUsernamePasswordAuthenticationProvider provider;
+
+    private ConfigurableApplicationContext previousContext;
+
+    private DefaultListableBeanFactory previousBeanFactory;
+
+    @BeforeEach
+    void setUp() {
+        previousContext = ApplicationContextProvider.getApplicationContext();
+        previousBeanFactory = ApplicationContextProvider.getBeanFactory();
+
+        SecurityContextHolder.clearContext();
+
+        EntitlementsHolder.getInstance().addAll(IdRepoEntitlement.values());
+
+        securityProperties = new SecurityProperties();
+        securityProperties.setAdminUser("admin");
+        securityProperties.getAuthenticationThrottle().setEnabled(false);
+
+        keymasterProperties = new KeymasterProperties();
+        keymasterProperties.setUsername("keymaster");
+        keymasterProperties.setPassword("keymaster-password");
+
+        context = new StaticApplicationContext();
+        context.getBeanFactory().registerSingleton("securityProperties", 
securityProperties);
+        context.refresh();
+
+        ApplicationContextProvider.setApplicationContext(context);
+        ApplicationContextProvider.setBeanFactory((DefaultListableBeanFactory) 
context.getBeanFactory());
+
+        provider = new SelfKeymasterUsernamePasswordAuthenticationProvider(
+                domainOps,
+                dataAccessor,
+                provisioningManager,
+                securityProperties,
+                encryptorManager,
+                throttlerCache,
+                keymasterProperties);
+    }
+
+    @AfterEach
+    void tearDown() {
+        SecurityContextHolder.clearContext();
+        ApplicationContextProvider.setApplicationContext(previousContext);
+        ApplicationContextProvider.setBeanFactory(previousBeanFactory);
+        context.close();
+    }
+
+    @Test
+    void supportsUsernamePasswordAuthentication() {
+        
assertTrue(provider.supports(UsernamePasswordAuthenticationToken.class));
+    }
+
+    @Test
+    void successfulAuthenticationAsKeymasterUser() {
+        SyncopeGrantedAuthority authority = new 
SyncopeGrantedAuthority(IdRepoEntitlement.USER_READ);
+        Set<SyncopeGrantedAuthority> authorities = Set.of(authority);
+        UsernamePasswordAuthenticationToken authentication =
+                new UsernamePasswordAuthenticationToken("keymaster", 
"keymaster-password");
+        authentication.setDetails(new SyncopeAuthenticationDetails(
+                SyncopeConstants.MASTER_DOMAIN, null));
+
+        when(dataAccessor.getAuthorities(eq("keymaster"), isNull())).
+                thenReturn(authorities);
+
+        Authentication result = provider.authenticate(authentication);
+
+        assertEquals("keymaster", result.getName());
+        assertNull(result.getCredentials());
+        assertSame(authentication.getDetails(), result.getDetails());
+        verify(dataAccessor, never()).authenticate(any(), any());
+    }
+
+    @Test
+    void failedAuthenticationAsKeymasterUserWithWrongPassword() {
+        UsernamePasswordAuthenticationToken authentication =
+                new UsernamePasswordAuthenticationToken("keymaster", 
"wrong-password");
+        authentication.setDetails(new SyncopeAuthenticationDetails(
+                SyncopeConstants.MASTER_DOMAIN, null));
+
+        BadCredentialsException ex = assertThrows(
+                BadCredentialsException.class,
+                () -> provider.authenticate(authentication));
+
+        assertEquals("keymaster: invalid password provided", ex.getMessage());
+        verify(dataAccessor, never()).authenticate(any(), any());
+    }
+
+    @Test
+    void nonKeymasterUserDelegatesToSuper() {
+        User user = mock(User.class);
+        when(user.getKey()).thenReturn("user-key");
+        when(user.getUsername()).thenReturn("bob");
+        Set<SyncopeGrantedAuthority> authorities = Set.of();

Review Comment:
   ## CodeQL / Unread local variable
   
   Variable 'Set<SyncopeGrantedAuthority> authorities' is never read.
   
   [Show more 
details](https://github.com/apache/syncope/security/code-scanning/2704)



##########
core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderTest.java:
##########
@@ -0,0 +1,94 @@
+/*
+ * 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.syncope.core.provisioning.java.data;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.List;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.provisioning.api.data.AnyTypeClassDataBinder;
+import org.apache.syncope.core.provisioning.api.data.SchemaDataBinder;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+class AnyTypeClassDataBinderTest extends AbstractDataBinderTest {
+
+    @Autowired
+    private AnyTypeClassDataBinder binder;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private SchemaDataBinder schemaDataBinder;
+
+    @Test
+    void get() {
+        AnyTypeClassTO user = 
binder.getAnyTypeClassTO(anyTypeClassDAO.findById("minimal 
user").orElseThrow());
+        assertEquals("minimal user", user.getKey());
+        assertTrue(user.getPlainSchemas().containsAll(List.of("fullname", 
"userId", "firstname", "surname", "email")));
+        assertTrue(user.getDerSchemas().containsAll(List.of("cn", "info")));
+        assertTrue(user.getInUseByTypes().contains(AnyTypeKind.USER.name()));
+    }
+
+    @Test
+    void createUpdate() {
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey("testSchema");
+        schemaTO.setType(AttrSchemaType.String);
+        schemaTO.setMultivalue(false);
+        schemaTO.setUniqueConstraint(false);
+        schemaTO.setReadonly(false);
+        PlainSchema schema = 
plainSchemaDAO.save(schemaDataBinder.create(schemaTO));

Review Comment:
   ## CodeQL / Unread local variable
   
   Variable 'PlainSchema schema' is never read.
   
   [Show more 
details](https://github.com/apache/syncope/security/code-scanning/2703)



##########
common/idrepo/lib/src/test/java/org/apache/syncope/common/lib/AnyOperationsTest.java:
##########
@@ -19,32 +19,509 @@
 package org.apache.syncope.common.lib;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.util.List;
+import java.util.Set;
 import org.apache.syncope.common.lib.request.AnyObjectUR;
+import org.apache.syncope.common.lib.request.AnyUR;
 import org.apache.syncope.common.lib.request.AttrPatch;
+import org.apache.syncope.common.lib.request.GroupUR;
+import org.apache.syncope.common.lib.request.LinkedAccountUR;
+import org.apache.syncope.common.lib.request.MembershipUR;
+import org.apache.syncope.common.lib.request.PasswordPatch;
+import org.apache.syncope.common.lib.request.RelationshipUR;
+import org.apache.syncope.common.lib.request.StringPatchItem;
+import org.apache.syncope.common.lib.request.StringReplacePatchItem;
+import org.apache.syncope.common.lib.request.UserUR;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.LinkedAccountTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.RelationshipTO;
+import org.apache.syncope.common.lib.to.TypeExtensionTO;
+import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.PatchOperation;
 import org.junit.jupiter.api.Test;
 
-public class AnyOperationsTest {
+class AnyOperationsTest {
 
     @Test
-    public void mindiff() {
-        AnyObjectTO oldOne = new AnyObjectTO();
-        oldOne.setName("name");
-        oldOne.getPlainAttrs().add(new 
Attr.Builder("plain").value("oldValue").build());
-        oldOne.getPlainAttrs().add(new 
Attr.Builder("encrypted").value("oldValue").build());
+    void diffUser() {
+        UserTO original = new UserTO();
+        original.setKey("key");
+        original.setUsername("oldUsername");
+        original.setPassword("oldPassword");
+        original.setSecurityQuestion("oldQuestion");
+        original.setMustChangePassword(true);
+        original.getRoles().add("roleToRemove");
+        original.getRoles().add("roleToKeep");
+        original.getAuxClasses().add("auxToRemove");
+        original.getResources().add("resourceToRemove");
+        original.getPlainAttrs().add(new 
Attr.Builder("plain").value("oldValue").build());
+        original.getPlainAttrs().add(new 
Attr.Builder("toRemove").value("value").build());
+        original.getPlainAttrs().add(new 
Attr.Builder("onlyOriginal").value("value").build());
+        original.getMemberships().add(new 
MembershipTO.Builder("groupToRemove").build());
+        original.getLinkedAccounts().add(new 
LinkedAccountTO.Builder("resourceToRemove", "key").build());
+        original.getRelationships().add(new 
RelationshipTO.Builder("typeToRemove").otherEnd("other").build());
 
-        AnyObjectTO newOne = new AnyObjectTO();
-        newOne.setName("name");
-        newOne.getPlainAttrs().add(new 
Attr.Builder("plain").value("newValue").build());
-        newOne.getPlainAttrs().add(new 
Attr.Builder("encrypted").value("oldValue").build());
+        UserTO updated = new UserTO();
+        updated.setKey("key");
+        updated.setUsername("newUsername");
+        updated.setPassword("newPassword");
+        updated.setSecurityQuestion("newQuestion");
+        updated.setMustChangePassword(false);
+        updated.getRoles().add("roleToKeep");
+        updated.getRoles().add("roleToAdd");
+        updated.getAuxClasses().add("auxToAdd");
+        updated.getResources().add("resourceToAdd");
+        updated.getPlainAttrs().add(new 
Attr.Builder("plain").value("newValue").build());
+        updated.getPlainAttrs().add(new Attr.Builder("toRemove").build());
+        updated.getPlainAttrs().add(new 
Attr.Builder("onlyUpdated").value("value").build());
+        updated.getMemberships().add(new 
MembershipTO.Builder("groupToAdd").build());
+        updated.getLinkedAccounts().add(new 
LinkedAccountTO.Builder("resourceToAdd", "key").build());
+        updated.getRelationships().add(new 
RelationshipTO.Builder("typeToAdd").otherEnd("other").build());
 
-        AnyObjectUR diff = AnyOperations.diff(newOne, oldOne, true);
-        assertEquals(1, diff.getPlainAttrs().size());
+        UserUR diff = AnyOperations.diff(updated, original, false);
 
-        AttrPatch patch = diff.getPlainAttrs().iterator().next();
-        assertEquals(PatchOperation.ADD_REPLACE, patch.getOperation());
-        assertEquals("plain", patch.getAttr().getSchema());
+        assertEquals("key", diff.getKey());
+        assertEquals("newUsername", diff.getUsername().getValue());
+        assertEquals("newPassword", diff.getPassword().getValue());
+        
assertTrue(diff.getPassword().getResources().contains("resourceToAdd"));
+        assertEquals("newQuestion", diff.getSecurityQuestion().getValue());
+        assertNull(diff.getSecurityAnswer());
+        assertFalse(diff.getMustChangePassword().getValue());
+
+        assertTrue(diff.getRoles().contains(
+                new 
StringPatchItem.Builder().operation(PatchOperation.DELETE).value("roleToRemove").build()));
+        assertTrue(diff.getRoles().contains(
+                new 
StringPatchItem.Builder().operation(PatchOperation.ADD_REPLACE).value("roleToAdd").build()));
+
+        assertTrue(diff.getAuxClasses().contains(
+                new 
StringPatchItem.Builder().operation(PatchOperation.DELETE).value("auxToRemove").build()));
+        assertTrue(diff.getAuxClasses().contains(
+                new 
StringPatchItem.Builder().operation(PatchOperation.ADD_REPLACE).value("auxToAdd").build()));
+
+        assertTrue(diff.getResources().contains(
+                new 
StringPatchItem.Builder().operation(PatchOperation.DELETE).value("resourceToRemove").build()));
+        assertTrue(diff.getResources().contains(
+                new 
StringPatchItem.Builder().operation(PatchOperation.ADD_REPLACE).value("resourceToAdd").build()));
+
+        assertEquals(PatchOperation.DELETE, plainAttrPatch(diff, 
"onlyOriginal", PatchOperation.DELETE).getOperation());
+        assertEquals(PatchOperation.DELETE, plainAttrPatch(diff, "toRemove", 
PatchOperation.DELETE).getOperation());
+        assertEquals("newValue",
+                plainAttrPatch(diff, "plain", 
PatchOperation.ADD_REPLACE).getAttr().getValues().get(0));
+        assertTrue(diff.getPlainAttrs().contains(plainAttrPatch(diff, 
"onlyUpdated", PatchOperation.ADD_REPLACE)));
+
+        assertEquals(PatchOperation.DELETE, membership(diff.getMemberships(), 
"groupToRemove",
+                PatchOperation.DELETE).getOperation());
+        assertEquals(PatchOperation.ADD_REPLACE, 
membership(diff.getMemberships(), "groupToAdd",
+                PatchOperation.ADD_REPLACE).getOperation());
+
+        assertEquals(PatchOperation.DELETE, 
relationship(diff.getRelationships(), "typeToRemove",
+                PatchOperation.DELETE).getOperation());
+        assertEquals(PatchOperation.ADD_REPLACE, 
relationship(diff.getRelationships(), "typeToAdd",
+                PatchOperation.ADD_REPLACE).getOperation());
+
+        assertEquals(2, diff.getLinkedAccounts().size());
+        assertEquals(PatchOperation.DELETE, 
linkedAccount(diff.getLinkedAccounts(), "resourceToRemove").getOperation());
+        assertEquals(PatchOperation.ADD_REPLACE,
+                linkedAccount(diff.getLinkedAccounts(), 
"resourceToAdd").getOperation());
+    }
+
+    @Test
+    void diffUserIncremental() {
+        UserTO original = new UserTO();
+        original.setKey("key");
+        original.setuManager("uManager");
+        original.getRoles().add("roleToRemove");
+        original.getAuxClasses().add("auxToRemove");
+        original.getResources().add("resourceToRemove");
+        original.getPlainAttrs().add(new 
Attr.Builder("toRemove").value("value").build());
+        original.getMemberships().add(new 
MembershipTO.Builder("groupToRemove").build());
+        original.getLinkedAccounts().add(new 
LinkedAccountTO.Builder("resourceToRemove", "key").build());
+        original.getRelationships().add(new 
RelationshipTO.Builder("typeToRemove").otherEnd("other").build());
+
+        UserTO updated = new UserTO();
+        updated.setKey("key");
+        updated.getPlainAttrs().add(new Attr.Builder("toRemove").build());
+
+        UserUR diff = AnyOperations.diff(updated, original, true);
+
+        assertNull(diff.getuManager());
+        assertTrue(diff.getRoles().isEmpty());
+        assertTrue(diff.getAuxClasses().isEmpty());
+        assertTrue(diff.getResources().isEmpty());
+        assertTrue(diff.getPlainAttrs().isEmpty());
+        assertTrue(diff.getMemberships().isEmpty());
+        assertTrue(diff.getLinkedAccounts().isEmpty());
+        assertTrue(diff.getRelationships().isEmpty());
+    }
+
+    @Test
+    void diffGroup() {
+        GroupTO original = new GroupTO();
+        original.setKey("key");
+        original.setName("oldName");
+
+        GroupTO updated = new GroupTO();
+        updated.setKey("key");
+        updated.setName("newName");
+        updated.getTypeExtensions().add(new TypeExtensionTO());
+
+        GroupUR diff = AnyOperations.diff(updated, original, false);
+
+        assertEquals("newName", diff.getName().getValue());
+        assertEquals(1, diff.getTypeExtensions().size());
+    }
+
+    @Test
+    void diffAnyObject() {
+        AnyObjectTO original = new AnyObjectTO();
+        original.setKey("key");
+        original.setName("oldName");
+        original.getMemberships().add(new 
MembershipTO.Builder("groupToRemove").build());
+
+        AnyObjectTO updated = new AnyObjectTO();
+        updated.setKey("key");
+        updated.setName("newName");
+        updated.getMemberships().add(new 
MembershipTO.Builder("groupToAdd").build());
+
+        AnyObjectUR diff = AnyOperations.diff(updated, original, false);
+
+        assertEquals("newName", diff.getName().getValue());
+        assertEquals(2, diff.getMemberships().size());
+    }
+
+    @Test
+    void diffWithDifferentKeys() {
+        UserTO updated = new UserTO();
+        updated.setKey("first");
+
+        UserTO original = new UserTO();
+        original.setKey("second");
+
+        assertThrows(IllegalArgumentException.class, () -> 
AnyOperations.diff(updated, original, false));
+    }
+
+    @Test
+    void diffWithMissingKey() {
+        UserTO updated = new UserTO();
+
+        UserTO original = new UserTO();
+        original.setKey("second");
+
+        assertThrows(IllegalArgumentException.class, () -> 
AnyOperations.diff(updated, original, false));
+    }
+
+    @Test
+    void genericDiff() {
+        AnyUR user = AnyOperations.diff(new UserTO(), new UserTO(), false);
+        AnyUR group = AnyOperations.diff(new GroupTO(), new GroupTO(), false);
+        AnyUR anyObject = AnyOperations.diff(new AnyObjectTO(), new 
AnyObjectTO(), false);
+
+        assertTrue(user instanceof UserUR);
+        assertTrue(group instanceof GroupUR);
+        assertTrue(anyObject instanceof AnyObjectUR);
+    }
+
+    @Test
+    void genericDiffUnsupported() {
+        AnyTO custom = new AnyTO() {
+
+            @Override
+            public String getDiscriminator() {
+                return "custom";
+            }
+        };
+
+        assertThrows(IllegalArgumentException.class,
+                () -> AnyOperations.<AnyTO, AnyUR>diff(custom, custom, false));
+    }
+
+    @Test
+    void patchUser() {
+        Attr oldMembershipAttr = new Attr.Builder("memb").value("old").build();
+        Attr newMembershipAttr = new Attr.Builder("memb").value("new").build();
+        RelationshipTO oldRelationship = new 
RelationshipTO.Builder("typeToRemove").otherEnd("other").build();
+        RelationshipTO newRelationship = new 
RelationshipTO.Builder("typeToAdd").otherEnd("other").build();

Review Comment:
   ## CodeQL / Unread local variable
   
   Variable 'RelationshipTO newRelationship' is never read.
   
   [Show more 
details](https://github.com/apache/syncope/security/code-scanning/2702)



##########
common/idrepo/lib/src/test/java/org/apache/syncope/common/lib/collections/CircularFifoQueueTest.java:
##########
@@ -0,0 +1,231 @@
+/*
+ * 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.syncope.common.lib.collections;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import org.apache.commons.lang3.SerializationUtils;
+import org.junit.jupiter.api.Test;
+
+class CircularFifoQueueTest {
+
+    @Test
+    void defaultConstructor() {
+        CircularFifoQueue<String> queue = new CircularFifoQueue<>();
+
+        assertEquals(32, queue.maxSize());
+        assertTrue(queue.isEmpty());
+        assertEquals(0, queue.size());
+        assertFalse(queue.isAtFullCapacity());
+        assertFalse(CircularFifoQueue.isFull());
+    }
+
+    @Test
+    void invalidSize() {
+        assertThrows(IllegalArgumentException.class, () -> new 
CircularFifoQueue<>(0));
+        assertThrows(IllegalArgumentException.class, () -> new 
CircularFifoQueue<>(-1));
+    }
+
+    @Test
+    void fromCollection() {
+        CircularFifoQueue<String> queue = new CircularFifoQueue<>(List.of("a", 
"b", "c"));
+
+        assertEquals(3, queue.maxSize());
+        assertEquals(3, queue.size());
+        assertEquals(List.of("a", "b", "c"), new ArrayList<>(queue));
+        assertEquals("a", queue.peek());
+        assertEquals("a", queue.get(0));
+        assertEquals("c", queue.get(2));
+    }
+
+    @Test
+    void addAndOffer() {
+        CircularFifoQueue<String> queue = new CircularFifoQueue<>(3);
+
+        assertTrue(queue.add("a"));
+        assertTrue(queue.offer("b"));
+        assertTrue(queue.add("c"));
+
+        assertEquals(3, queue.size());
+        assertTrue(queue.isAtFullCapacity());
+        assertEquals("a", queue.element());
+        assertThrows(NullPointerException.class, () -> queue.add(null));
+        assertThrows(NullPointerException.class, () -> queue.offer(null));

Review Comment:
   ## CodeQL / Ignored error status of call
   
   Method execute ignores exceptional return value of 
CircularFifoQueue<String>.offer.
   
   [Show more 
details](https://github.com/apache/syncope/security/code-scanning/2686)



##########
core/idrepo/logic/src/test/java/org/apache/syncope/core/logic/AbstractUserLogicTest.java:
##########
@@ -0,0 +1,303 @@
+/*
+ * 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.syncope.core.logic;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Optional;
+import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.request.StatusR;
+import org.apache.syncope.common.lib.request.UserCR;
+import org.apache.syncope.common.lib.request.UserUR;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.StatusRType;
+import org.apache.syncope.core.persistence.api.EncryptorManager;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
+import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
+import org.apache.syncope.core.provisioning.api.jexl.TemplateUtils;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class AbstractUserLogicTest {
+
+    private static class TestLogic extends AbstractUserLogic {
+
+        TestLogic(
+                final RealmSearchDAO realmSearchDAO,
+                final AnyTypeDAO anyTypeDAO,
+                final TemplateUtils templateUtils,
+                final UserDAO userDAO,
+                final UserDataBinder binder,
+                final UserProvisioningManager provisioningManager,
+                final EncryptorManager encryptorManager,
+                final ConfParamOps confParamOps) {
+
+            super(realmSearchDAO, anyTypeDAO, templateUtils, userDAO, binder, 
provisioningManager,
+                    encryptorManager, confParamOps);
+        }
+
+        ProvisioningResult<UserTO> create(final UserCR userCR) {
+            return doCreate(userCR, false, false);
+        }
+
+        ProvisioningResult<UserTO> update(final UserUR userUR) {
+            return doUpdate(userUR, false, false);
+        }
+
+        ProvisioningResult<UserTO> status(final StatusR statusR) {
+            return doStatus(statusR, false);
+        }
+
+        ProvisioningResult<UserTO> delete(final UserTO userTO) {
+            return doDelete(userTO, false, false);
+        }
+
+        public UserTO requestPasswordReset(final String username) {
+            return null;
+        }
+
+        public UserTO confirmPasswordReset(final String token) {

Review Comment:
   ## CodeQL / Useless parameter
   
   The parameter 'token' is never used.
   
   [Show more 
details](https://github.com/apache/syncope/security/code-scanning/2706)



##########
core/idrepo/logic/src/test/java/org/apache/syncope/core/logic/AbstractUserLogicTest.java:
##########
@@ -0,0 +1,303 @@
+/*
+ * 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.syncope.core.logic;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Optional;
+import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.request.StatusR;
+import org.apache.syncope.common.lib.request.UserCR;
+import org.apache.syncope.common.lib.request.UserUR;
+import org.apache.syncope.common.lib.to.ProvisioningResult;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.StatusRType;
+import org.apache.syncope.core.persistence.api.EncryptorManager;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.provisioning.api.ProvisioningManager;
+import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
+import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
+import org.apache.syncope.core.provisioning.api.jexl.TemplateUtils;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class AbstractUserLogicTest {
+
+    private static class TestLogic extends AbstractUserLogic {
+
+        TestLogic(
+                final RealmSearchDAO realmSearchDAO,
+                final AnyTypeDAO anyTypeDAO,
+                final TemplateUtils templateUtils,
+                final UserDAO userDAO,
+                final UserDataBinder binder,
+                final UserProvisioningManager provisioningManager,
+                final EncryptorManager encryptorManager,
+                final ConfParamOps confParamOps) {
+
+            super(realmSearchDAO, anyTypeDAO, templateUtils, userDAO, binder, 
provisioningManager,
+                    encryptorManager, confParamOps);
+        }
+
+        ProvisioningResult<UserTO> create(final UserCR userCR) {
+            return doCreate(userCR, false, false);
+        }
+
+        ProvisioningResult<UserTO> update(final UserUR userUR) {
+            return doUpdate(userUR, false, false);
+        }
+
+        ProvisioningResult<UserTO> status(final StatusR statusR) {
+            return doStatus(statusR, false);
+        }
+
+        ProvisioningResult<UserTO> delete(final UserTO userTO) {
+            return doDelete(userTO, false, false);
+        }
+
+        public UserTO requestPasswordReset(final String username) {
+            return null;
+        }
+
+        public UserTO confirmPasswordReset(final String token) {
+            return null;
+        }
+
+        public UserTO otherOperation(final Object value) {

Review Comment:
   ## CodeQL / Useless parameter
   
   The parameter 'value' is never used.
   
   [Show more 
details](https://github.com/apache/syncope/security/code-scanning/2705)



-- 
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]

  • [PR] Increase unit test... ilgrosso (via GitHub) via dev
    • Re: [PR] Increase ... github-advanced-security[bot] (via GitHub) via dev

Reply via email to