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]
