diff --git a/certify-service/src/main/java/io/mosip/certify/services/templating/VelocityTemplatingEngineImpl.java b/certify-service/src/main/java/io/mosip/certify/services/templating/VelocityTemplatingEngineImpl.java index a82aebcd..28726748 100644 --- a/certify-service/src/main/java/io/mosip/certify/services/templating/VelocityTemplatingEngineImpl.java +++ b/certify-service/src/main/java/io/mosip/certify/services/templating/VelocityTemplatingEngineImpl.java @@ -18,9 +18,11 @@ import io.mosip.certify.core.repository.TemplateRepository; import io.mosip.certify.core.spi.SvgTemplateService; import io.mosip.certify.services.SVGRenderUtils; +import io.mosip.certify.utils.CredentialUtils; import jakarta.annotation.PostConstruct; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.RuntimeConstants; @@ -44,8 +46,8 @@ public class VelocityTemplatingEngineImpl implements VCFormatter { TemplateRepository templateRepository; @Autowired SvgTemplateService svgTemplateService; - @Value("${mosip.certify.vcformat.vc.expiry:true}") - boolean shouldHaveDates; + @Value("${mosip.certify.issuer.default.expiry.duration:2y}") + String defaultExpiryDuration; @PostConstruct public void initialize() { @@ -116,16 +118,18 @@ public String format(JSONObject templateInput, Map defaultSettin log.error("SVG Template: " + defaultSettings.get(SVG_TEMPLATE) + " not available in DB", e); } } - if (shouldHaveDates && !(templateInput.has(VCDM2Constants.VALID_FROM) - && templateInput.has(VCDM2Constants.VALID_UNITL))) { + + if (!(templateInput.has(VCDM2Constants.VALID_FROM) + && templateInput.has(VCDM2Constants.VALID_UNITL)) && StringUtils.isNotEmpty(defaultExpiryDuration)) { String time = ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern(Constants.UTC_DATETIME_PATTERN)); - // hardcoded time - String expiryTime = ZonedDateTime.now(ZoneOffset.UTC).plusYears(2).format(DateTimeFormatter.ofPattern(Constants.UTC_DATETIME_PATTERN)); + String expiryTime = ZonedDateTime.now(ZoneOffset.UTC) + .plusSeconds(CredentialUtils.toSeconds(defaultExpiryDuration)) + .format(DateTimeFormatter.ofPattern(Constants.UTC_DATETIME_PATTERN)); finalTemplate.put(VCDM2Constants.VALID_FROM, time); finalTemplate.put(VCDM2Constants.VALID_UNITL, expiryTime); } VelocityContext context = new VelocityContext(finalTemplate); - engine.evaluate(context, writer, /*logTag */ templateName,t.toString()); + engine.evaluate(context, writer, /*logTag */ templateName, t.toString()); return writer.toString(); } } diff --git a/certify-service/src/main/java/io/mosip/certify/utils/CredentialUtils.java b/certify-service/src/main/java/io/mosip/certify/utils/CredentialUtils.java index 6dc0392d..34212557 100644 --- a/certify-service/src/main/java/io/mosip/certify/utils/CredentialUtils.java +++ b/certify-service/src/main/java/io/mosip/certify/utils/CredentialUtils.java @@ -2,11 +2,16 @@ import io.mosip.certify.api.dto.VCRequestDto; +import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalUnit; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class CredentialUtils { + public static final long DEFAULT_EXPIRY_DURATION_SECONDS = 2 * ChronoUnit.YEARS.getDuration().getSeconds(); // returns true for VC 2.0 VCI requests public static boolean isVC2_0Request(VCRequestDto r) { return r.getContext().get(0).equals("https://www.w3.org/ns/credentials/v2"); @@ -26,4 +31,28 @@ public static String getTemplateName(VCRequestDto vcRequestDto) { String typeKey = String.join(",", t); return String.join(":", typeKey, contextKey); } + + /** + * Converts a String time duration to seconds + * @param duration + * @return + */ + public static long toSeconds(String duration) { + Pattern pattern = Pattern.compile("(?:(\\d+)y)?(?:(\\d+)M)?(?:(\\d+)d)?(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?"); + Matcher matcher = pattern.matcher(duration); + long total = 0; + TemporalUnit[] durationArray = {ChronoUnit.YEARS, ChronoUnit.MONTHS, ChronoUnit.DAYS, ChronoUnit.HOURS, ChronoUnit.MINUTES, ChronoUnit.SECONDS }; + if (matcher.matches()) { + for (int i = 1; i <= matcher.groupCount(); i++) { + if (matcher.group(i) != null) { + total += Integer.parseInt(matcher.group(i)) * durationArray[i-1].getDuration().getSeconds(); + } + } + if (total == 0) { + return DEFAULT_EXPIRY_DURATION_SECONDS; + } + return total; + } + return DEFAULT_EXPIRY_DURATION_SECONDS; + } } diff --git a/certify-service/src/main/resources/application-local.properties b/certify-service/src/main/resources/application-local.properties index bc0d2ac2..917de275 100644 --- a/certify-service/src/main/resources/application-local.properties +++ b/certify-service/src/main/resources/application-local.properties @@ -20,7 +20,7 @@ mosip.certify.authorization.url=http://localhost:8088 mosip.certify.discovery.issuer-id=${mosip.certify.domain.url}${server.servlet.path} mosip.certify.issuer.vc-sign-algo=Ed25519Signature2018 mosip.certify.issuer=CertifyIssuer - +mosip.certify.issuer.default.expiry.duration=2y ##--------------change this later--------------------------------- mosip.certify.supported.jwt-proof-alg={'RS256','PS256','ES256'} diff --git a/certify-service/src/test/java/io/mosip/certify/services/templating/VelocityTemplatingEngineImplTest.java b/certify-service/src/test/java/io/mosip/certify/services/templating/VelocityTemplatingEngineImplTest.java index 8e3d9225..5d67fc7f 100644 --- a/certify-service/src/test/java/io/mosip/certify/services/templating/VelocityTemplatingEngineImplTest.java +++ b/certify-service/src/test/java/io/mosip/certify/services/templating/VelocityTemplatingEngineImplTest.java @@ -119,7 +119,7 @@ public void setUp() { "https://vharsh.github.io/DID/mock-context.json,https://www.w3.org/2018/credentials/v1" ); when(templateRepository.findAll()).thenReturn(List.of(vc1, vc2, vc3)); - ReflectionTestUtils.setField(formatter, "shouldHaveDates", true); + ReflectionTestUtils.setField(formatter, "defaultExpiryDuration", "2y"); formatter.initialize(); // engine = new VelocityEngine(); // engine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); diff --git a/certify-service/src/test/java/io/mosip/certify/utils/CredentialUtilsTest.java b/certify-service/src/test/java/io/mosip/certify/utils/CredentialUtilsTest.java index e6c4c0e1..7fc7b506 100644 --- a/certify-service/src/test/java/io/mosip/certify/utils/CredentialUtilsTest.java +++ b/certify-service/src/test/java/io/mosip/certify/utils/CredentialUtilsTest.java @@ -2,17 +2,44 @@ import io.mosip.certify.api.dto.VCRequestDto; import junit.framework.TestCase; +import org.apache.commons.validator.Arg; +import org.junit.Assert; +import org.junit.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.ArgumentsSource; +import org.junit.jupiter.params.provider.MethodSource; +import java.time.temporal.ChronoUnit; import java.util.List; +import java.util.stream.Stream; -public class CredentialUtilsTest extends TestCase { +public class CredentialUtilsTest { + @Test public void testGetTemplateName() { VCRequestDto request = new VCRequestDto(); request.setContext(List.of("https://www.w3.org/ns/credentials/v2", "https://example.org/Person.json")); request.setType(List.of("VerifiableCredential", "UniversityCredential")); String expected = "UniversityCredential,VerifiableCredential:https://example.org/Person.json,https://www.w3.org/ns/credentials/v2"; - assertEquals(expected, CredentialUtils.getTemplateName(request)); + Assert.assertEquals(expected, CredentialUtils.getTemplateName(request)); + } + + @ParameterizedTest + @MethodSource("provideTimeDuration") + public void testToSeconds(long expectedDuration, String duration) { + Assert.assertEquals(expectedDuration, CredentialUtils.toSeconds(duration)); + } + + private static Stream provideTimeDuration() { + return Stream.of( + Arguments.of(14519, "4h1m59s"), + Arguments.of(59, "59s"), + Arguments.of(3_15_56_952, "1y"), + Arguments.of(60, "1m"), + Arguments.of(86400, "1d"), + Arguments.of(6_31_13_904, ""), + Arguments.of(6_31_13_904, "0s") + ); } } \ No newline at end of file diff --git a/certify-service/src/test/resources/application-test.properties b/certify-service/src/test/resources/application-test.properties index 0c6aeaa1..738e6765 100644 --- a/certify-service/src/test/resources/application-test.properties +++ b/certify-service/src/test/resources/application-test.properties @@ -8,7 +8,8 @@ mosip.certify.integration.scan-base-package=io.mosip.certify mosip.certify.integration.audit-plugin=TestAuditPlugin mosip.certify.integration.vci-plugin=TestVCIPluginImpl mosip.certify.issuer=PluginIssuer -mosip.certify.issuer.vc-sign-algo=Ed25519Signature2018 +mosip.certify.issuer.vc-sign-algo=Ed25519Signature2020 +mosip.certify.issuer.default.expiry.duration=2y # mosip.certify.issuer.vc-sign-algo:Ed25519Signature2018 for CertifyIssuer test ## ------------------------------------------ Discovery openid-configuration -------------------------------------------