diff --git a/docs/PowerAuth-Server-1.6.0.md b/docs/PowerAuth-Server-1.6.0.md new file mode 100644 index 000000000..6101a7856 --- /dev/null +++ b/docs/PowerAuth-Server-1.6.0.md @@ -0,0 +1,9 @@ +# Migration from 1.5.x to 1.6.0 + +This guide contains instructions for migration from PowerAuth Server version `1.5.x` to version `1.6.0`. + +## Database Changes + +### Forbid name duplication for operation templates. + +Add unique constraint to `templateName` column in `pa_operation_template` table. diff --git a/docs/db/changelog/changesets/powerauth-java-server/1.6.x/20231018-add-constraint-operation-template-name.xml b/docs/db/changelog/changesets/powerauth-java-server/1.6.x/20231018-add-constraint-operation-template-name.xml new file mode 100644 index 000000000..b44048f4d --- /dev/null +++ b/docs/db/changelog/changesets/powerauth-java-server/1.6.x/20231018-add-constraint-operation-template-name.xml @@ -0,0 +1,15 @@ + + + + + + + + + + Add unique constraint to pa_operation_template.template_name + + + diff --git a/docs/db/changelog/changesets/powerauth-java-server/1.6.x/db.changelog-version.xml b/docs/db/changelog/changesets/powerauth-java-server/1.6.x/db.changelog-version.xml new file mode 100644 index 000000000..d362d850e --- /dev/null +++ b/docs/db/changelog/changesets/powerauth-java-server/1.6.x/db.changelog-version.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/docs/db/changelog/changesets/powerauth-java-server/db.changelog-module.xml b/docs/db/changelog/changesets/powerauth-java-server/db.changelog-module.xml index 59f6011e5..cae01c7d2 100644 --- a/docs/db/changelog/changesets/powerauth-java-server/db.changelog-module.xml +++ b/docs/db/changelog/changesets/powerauth-java-server/db.changelog-module.xml @@ -14,5 +14,6 @@ + \ No newline at end of file diff --git a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/OperationTemplateEntity.java b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/OperationTemplateEntity.java index 144545087..d2667980c 100644 --- a/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/OperationTemplateEntity.java +++ b/powerauth-java-server/src/main/java/io/getlime/security/powerauth/app/server/database/model/entity/OperationTemplateEntity.java @@ -45,7 +45,7 @@ public class OperationTemplateEntity implements Serializable { @Column(name = "id") private Long id; - @Column(name = "template_name", nullable=false) + @Column(name = "template_name", nullable=false, unique = true) private String templateName; @Column(name = "operation_type", nullable=false) diff --git a/powerauth-java-server/src/test/java/io/getlime/security/powerauth/app/server/database/repository/OperationTemplateRepositoryTest.java b/powerauth-java-server/src/test/java/io/getlime/security/powerauth/app/server/database/repository/OperationTemplateRepositoryTest.java new file mode 100644 index 000000000..2e5efcb1f --- /dev/null +++ b/powerauth-java-server/src/test/java/io/getlime/security/powerauth/app/server/database/repository/OperationTemplateRepositoryTest.java @@ -0,0 +1,76 @@ +/* + * PowerAuth Server and related software components + * Copyright (C) 2023 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package io.getlime.security.powerauth.app.server.database.repository; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.getlime.security.powerauth.app.server.database.model.entity.OperationTemplateEntity; +import io.getlime.security.powerauth.crypto.lib.enums.PowerAuthSignatureTypes; +import org.hibernate.exception.ConstraintViolationException; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; +import org.springframework.context.annotation.Import; + +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Test for {@link OperationTemplateRepository}. + * + * @author Jan Pesek, jan.pesek@wultra.com + */ +@DataJpaTest +@Import(ObjectMapper.class) +class OperationTemplateRepositoryTest { + + @Autowired + private OperationTemplateRepository repository; + + @Autowired + private TestEntityManager entityManager; + + @Test + void testDuplicateOperationTemplateCreation() { + final String templateName = "login"; + + repository.save(createOperationTemplateEntity(templateName)); + entityManager.flush(); + + Optional entity = repository.findTemplateByName(templateName); + assertTrue(entity.isPresent()); + assertEquals(templateName, entity.get().getTemplateName()); + + repository.save(createOperationTemplateEntity(templateName)); + assertThrows(ConstraintViolationException.class, () -> entityManager.flush()); + } + + private static OperationTemplateEntity createOperationTemplateEntity(String templateName) { + final OperationTemplateEntity entity = new OperationTemplateEntity(); + entity.setTemplateName(templateName); + entity.setOperationType(templateName); + entity.setDataTemplate("A2"); + PowerAuthSignatureTypes[] signatureTypes = {PowerAuthSignatureTypes.POSSESSION}; + entity.setSignatureType(signatureTypes); + entity.setMaxFailureCount(5L); + entity.setExpiration(300L); + return entity; + } + +} diff --git a/powerauth-java-server/src/test/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/OperationTemplateServiceBehaviorTest.java b/powerauth-java-server/src/test/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/OperationTemplateServiceBehaviorTest.java new file mode 100644 index 000000000..ab4b1782e --- /dev/null +++ b/powerauth-java-server/src/test/java/io/getlime/security/powerauth/app/server/service/behavior/tasks/OperationTemplateServiceBehaviorTest.java @@ -0,0 +1,64 @@ +/* + * PowerAuth Server and related software components + * Copyright (C) 2023 Wultra s.r.o. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package io.getlime.security.powerauth.app.server.service.behavior.tasks; + +import com.wultra.security.powerauth.client.model.enumeration.SignatureType; +import com.wultra.security.powerauth.client.model.request.OperationTemplateCreateRequest; +import io.getlime.security.powerauth.app.server.service.exceptions.GenericServiceException; +import io.getlime.security.powerauth.app.server.service.model.ServiceError; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Test for {@link OperationTemplateServiceBehavior}. + * + * @author Jan Pesek, jan.pesek@wultra.com + */ +@SpringBootTest +class OperationTemplateServiceBehaviorTest { + + @Autowired + private OperationTemplateServiceBehavior service; + + @Test + void testDuplicateOperationTemplateCreation() throws Exception { + final String templateName = "login"; + + service.createOperationTemplate(createOperationTemplateCreateRequest(templateName)); + assertFalse(service.getAllTemplates().isEmpty()); + + final GenericServiceException exception = assertThrows(GenericServiceException.class, () -> + service.createOperationTemplate(createOperationTemplateCreateRequest(templateName))); + assertEquals(ServiceError.OPERATION_TEMPLATE_ALREADY_EXISTS, exception.getCode()); + } + + private static OperationTemplateCreateRequest createOperationTemplateCreateRequest(String templateName) { + final OperationTemplateCreateRequest request = new OperationTemplateCreateRequest(); + request.setTemplateName(templateName); + request.setOperationType(templateName); + request.setDataTemplate("A2"); + request.getSignatureType().add(SignatureType.POSSESSION_KNOWLEDGE); + request.setMaxFailureCount(5L); + request.setExpiration(300L); + return request; + } + +}