Skip to content

Commit

Permalink
[INJICERT-434] compute svg template multibase&sha256 per spec (#125)
Browse files Browse the repository at this point in the history
* [INJICERT-434] compute svg template multibase&sha256 per spec

ref: https://w3c-ccg.github.io/vc-render-method/#svgrenderingtemplate

Signed-off-by: Harsh Vardhan <[email protected]>

* [INJICERT-434] only fetch SVG template if VC 2.0 is requested

Signed-off-by: Harsh Vardhan <[email protected]>

---------

Signed-off-by: Harsh Vardhan <[email protected]>
  • Loading branch information
vharsh authored Nov 8, 2024
1 parent 7bbc340 commit 7151588
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.mosip.certify.core.constants;

public class VCDM1Constants {
public static final String URL = "https://www.w3.org/2018/credentials/v1";
public static final String ISSUANCE_DATE = "issuanceDate";
public static final String EXPIRATION_DATE = "expirationDate";
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* ref:
*/
public class VCDM2Constants {
public static final String URL = "https://www.w3.org/ns/credentials/v2";
public static final String VALID_UNITL = "validUntil";
public static final String VALID_FROM = "validFrom";
}
11 changes: 11 additions & 0 deletions certify-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
<version>0.10.0-SNAPSHOT</version>
<name>certify-service</name>
<description>certify vci service</description>
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>

<dependencies>
<dependency>
Expand Down Expand Up @@ -79,6 +85,11 @@
<artifactId>tink</artifactId>
<version>1.13.0</version>
</dependency>
<dependency>
<groupId>com.github.multiformats</groupId>
<artifactId>java-multibase</artifactId>
<version>v1.1.1</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
*/
package io.mosip.certify.services;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nimbusds.jose.JWSAlgorithm;
import foundation.identity.jsonld.JsonLDObject;
import io.mosip.certify.api.dto.VCRequestDto;
Expand Down Expand Up @@ -34,6 +32,7 @@
import io.mosip.certify.exception.InvalidNonceException;
import io.mosip.certify.proof.ProofValidator;
import io.mosip.certify.proof.ProofValidatorFactory;
import io.mosip.certify.services.templating.VelocityTemplatingConstants;
import io.mosip.certify.utils.CredentialUtils;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
Expand Down Expand Up @@ -88,6 +87,9 @@ public class CertifyIssuanceServiceImpl implements VCIssuanceService {
@Value("${mosip.certify.issuer.vc-sign-algo:Ed25519Signature2018}")
private String VCSignAlgo;

@Value("${mosip.certify.issuer.svg.template.id}")
private String svg;

@Autowired
private AuditPlugin auditWrapper;

Expand Down Expand Up @@ -158,8 +160,11 @@ private VCResult<?> getVerifiableCredential(CredentialRequest credentialRequest,
// TODO(multitenancy): later decide which plugin out of n plugins is the correct one
JSONObject jsonObject = dataModelService.fetchData(parsedAccessToken.getClaims());
Map<String, Object> templateParams = new HashMap<>();
templateParams.put("templateName", CredentialUtils.getTemplateName(vcRequestDto));
templateParams.put("issuerURI", issuerURI);
templateParams.put(VelocityTemplatingConstants.TEMPLATE_NAME, CredentialUtils.getTemplateName(vcRequestDto));
templateParams.put(VelocityTemplatingConstants.ISSUER_URI, issuerURI);
if (svg != null) {
templateParams.put(VelocityTemplatingConstants.SVG_TEMPLATE, svg);
}
String templatedVC = vcFormatter.format(jsonObject, templateParams);
Map<String, String> vcSignerParams = new HashMap<>();
// TODO: Collate this into simpler APIs where just key-type is specified
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.mosip.certify.services;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import io.ipfs.multibase.Multibase;

public class SVGRenderUtils {
/**
* Generate SVG digest for @param svg image as per spec.
* ref: https://w3c-ccg.github.io/vc-render-method/#svgrenderingtemplate
*
* @param svg
* @return
*/
public static String getDigestMultibase(String svg) {
/*
digestMultibase: An optional multibase-encoded multihash of the SVG image.
The multibase value MUST be z and the multihash value MUST
be SHA-2 with 256-bits of output (0x12).
*/
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] sha256 = digest.digest(svg.getBytes(StandardCharsets.UTF_8));
return Multibase.encode(Multibase.Base.Base58BTC, sha256);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.mosip.certify.services.templating;

public class VelocityTemplatingConstants {
public static final String TEMPLATE_NAME = "templateName";
public static final String ISSUER_URI = "issuerURI";
public static final String SVG_TEMPLATE = "svgTemplate";
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@
import io.mosip.certify.api.spi.VCFormatter;
import io.mosip.certify.core.constants.Constants;
import io.mosip.certify.core.constants.VCDM2Constants;
import io.mosip.certify.core.exception.TemplateException;
import io.mosip.certify.core.repository.TemplateRepository;
import io.mosip.certify.core.spi.SvgTemplateService;
import io.mosip.certify.services.SVGRenderUtils;
import jakarta.annotation.PostConstruct;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
Expand All @@ -28,13 +32,18 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import static io.mosip.certify.services.templating.VelocityTemplatingConstants.*;

@Slf4j
@Service
public class VelocityTemplatingEngineImpl implements VCFormatter {
VelocityEngine engine;
public static final String DELIMITER = ":";
Map<String, String> templateCache;
@Autowired
TemplateRepository templateRepository;
@Autowired
SvgTemplateService svgTemplateService;
@Value("${mosip.certify.vcformat.vc.expiry:true}")
boolean shouldHaveDates;

Expand Down Expand Up @@ -66,8 +75,8 @@ public void initialize() {
@Override
public String format(JSONObject templateInput, Map<String, Object> defaultSettings) {
// TODO: Isn't template name becoming too complex with VC_CONTEXTS & CREDENTIAL_TYPES both?
String templateName = defaultSettings.get("templateName").toString();
String issuer = defaultSettings.get("issuerURI").toString();
String templateName = defaultSettings.get(TEMPLATE_NAME).toString();
String issuer = defaultSettings.get(ISSUER_URI).toString();
String t = templateCache.get(templateName);
StringWriter writer = new StringWriter();
// 1. Prepare map
Expand Down Expand Up @@ -98,6 +107,15 @@ public String format(JSONObject templateInput, Map<String, Object> defaultSettin
finalTemplate.put("_esc", new EscapeTool());
// add the issuer value
finalTemplate.put("issuer", issuer);
if (defaultSettings.containsKey(SVG_TEMPLATE) && templateName.contains(VCDM2Constants.URL)) {
try {
finalTemplate.put("_renderMethodSVGdigest",
SVGRenderUtils.getDigestMultibase(svgTemplateService.getSvgTemplate(
UUID.fromString((String) defaultSettings.get(SVG_TEMPLATE))).getTemplate()));
} catch (TemplateException e) {
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))) {
String time = ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern(Constants.UTC_DATETIME_PATTERN));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.mosip.certify.services;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class SVGRenderUtilsTest {

@Test
void getDigestMultibase() {
String svg = """
<svg viewBox=".5 .5 3 4" fill="none" stroke="#20b2a" stroke-linecap="round"> <path d=" M1 4h-.001 V1h2v.001 M1 2.6 h1v.001"/> </svg>
""";
String actual = SVGRenderUtils.getDigestMultibase(svg);
String expected = "z4po9QkJj1fhMt6cxHSnDnAUat4PEVrerUGGsPHLxJnK5";
assertEquals(expected, actual);
}

}

0 comments on commit 7151588

Please sign in to comment.