Skip to content

Commit

Permalink
Incorporate Interoperability Event Features to wwwverifier
Browse files Browse the repository at this point in the history
Added the ability to chose between request scenarios, as well
as required checks + associated logging. Also added the ability
to render the returned portrait image.

Manually tested.
  • Loading branch information
suzannajiwani committed Oct 25, 2023
1 parent 9b37ddc commit 04132ec
Show file tree
Hide file tree
Showing 10 changed files with 375 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,13 @@ void parse(@NonNull byte[] encodedEngagement) {
if (Util.cborMapHasKey(map, 5)) {
List<DataItem> originInfoItems = Util.cborMapExtractArray(map, 5);
for (DataItem oiDataItem : originInfoItems) {
OriginInfo originInfo = OriginInfo.decode(oiDataItem);
if (originInfo != null) {
mOriginInfos.add(originInfo);
try {
OriginInfo originInfo = OriginInfo.decode(oiDataItem);
if (originInfo != null) {
mOriginInfos.add(originInfo);
}
} catch (Exception e) {
Logger.w(TAG, "OriginInfo is incorrectly formatted.", e);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 The Android Open Source Project
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 The Android Open Source Project
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
2 changes: 2 additions & 0 deletions wwwverifier/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ dependencies {
implementation 'co.nstant.in:cbor:0.9'
implementation 'org.json:json:20160810'
implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
implementation 'com.google.cloud:google-cloud-storage'
implementation platform('com.google.cloud:libraries-bom:26.22.0')
implementation project(path: ':identity')
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:3.2.4'
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
public class ServletConsts {
// Datastore constants
public static final String DEV_RESPONSE_PROP = "Device Response";
public static final String REQ_ATTR_PROP = "Requested Attributes";
public static final String LOGS_PROP = "Logs";
public static final String ENTITY_TYPE = "Main";
public static final String PUBKEY_PROP = "Reader Key Public";
public static final String PRIVKEY_PROP = "Reader Key Private";
Expand All @@ -33,6 +35,9 @@ public class ServletConsts {
public static final String SESSION_URL = "create-new-session";
public static final String RESPONSE_URL = "display-response";
public static final String DE_KEY = "deviceEngagementBytes";
public static final String DISPLAY_LOGS_URL = "display-logs";

public static final String REQUESTED_ATTRIBUTES_QUERY = "requested_attributes";

// website URL constants
public static final String MDOC_PREFIX = "mdoc://";
Expand Down
18 changes: 17 additions & 1 deletion wwwverifier/src/main/webapp/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,27 @@
<script src="script.js"></script>
</head>
<body>
<h1>Android Identity Credential MDoc Reader</h1>
<div id="buttons">
<button type="button" onclick="createSession('all')">
Request all mandatory license and holder data
</button>

<button type="button" onclick="createSession('age')">
Request age verification (over 18)
</button>
</div>

<div id="content">
<h1>Android Identity Credential MDoc Reader</h1>
<div id="mdoc-uri-text"></div>
<br />
<div id="portrait">
<img id="portrait-render" src="">
</div>
<br />
<div id="response-display"></div>
<br />
<div id="logs"></div>
</div>
</body>
</html>
60 changes: 55 additions & 5 deletions wwwverifier/src/main/webapp/script.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
const GET_URL = '/request-mdl';
const BASE_URL = '/request-mdl';
const CREATE_SESSION_URL = '/create-new-session';
const DISPLAY_RESPONSE_URL = '/display-response';
const DISPLAY_LOGS_URL = '/display-logs';

const MDOC_URI_ID = 'mdoc-uri-text'
const RESPONSE_ID = 'response-display';
const LOGS_ID = 'logs'
const PORTRAIT_ID = 'portrait-render'

const INTERVAL_MS = 5000; // 5 seconds

Expand All @@ -13,13 +16,51 @@ const CROSS_PLACEHOLDER = '+';
const CROSS_UNICODE = '\u274c';
const BOLD_PLACEHOLDER = '#';

const AGE_ONLY_REQUEST = 'age';
const ALL_LICENSE_HOLDER_REQUEST = 'all';

var sessionID = '';

window.onload = onLoad;
var devResponseInterval = window.setInterval(getDeviceResponse, INTERVAL_MS);
var readLogsInterval = window.setInterval(readLogs, INTERVAL_MS);
var logTextArr = '';

function readLogs() {
if (sessionID.length == 0) return;


fetch(BASE_URL + DISPLAY_LOGS_URL + '/' + String(sessionID)).then(response => response.text()).then((responseText) => {
if (responseText.length > 1) {
var textArr = responseText.substring(0, responseText.length - 2).split('\n');
if (responseText === logTextArr) return;
logTextArr = responseText;

document.getElementById(LOGS_ID).innerHTML = '';

function onLoad() {
fetch(GET_URL + CREATE_SESSION_URL).then(response => response.text()).then((responseText) => {
// create text instruction
var log_caption = document.createElement('div');
log_caption.innerHTML = 'Logs for Interop Event';
document.getElementById(LOGS_ID).append(document.createElement('br'));
document.getElementById(LOGS_ID).appendChild(log_caption);

var table = document.createElement('table');

for (var i = 0; i < textArr.length; i++) {
var row = table.insertRow(i);
var rowText = textArr[i]
row.insertCell(0).innerHTML = rowText;
}
document.getElementById(LOGS_ID).append(table);
}
});
}

function createSession(requestedAttributes) {
fetch(BASE_URL + CREATE_SESSION_URL + '?' + new URLSearchParams({ requested_attributes: requestedAttributes }).toString(),
{
method: "get",
})
.then(response => response.text()).then((responseText) => {
var responseArr = responseText.split(',');
var mdocURL = responseArr[0];
sessionID = responseArr[1];
Expand All @@ -36,20 +77,27 @@ function onLoad() {
a.innerHTML = mdocURL;
document.getElementById(MDOC_URI_ID).appendChild(a);
});
document.getElementById('buttons').style.display = 'none';
}

function getDeviceResponse() {
if (sessionID.length == 0) return;

document.getElementById(RESPONSE_ID).innerHTML = '';
fetch(GET_URL + DISPLAY_RESPONSE_URL + '/' + String(sessionID)).then(response => response.text()).then((responseText) => {
fetch(BASE_URL + DISPLAY_RESPONSE_URL + '/' + String(sessionID)).then(response => response.text()).then((responseText) => {
if (responseText.length > 1) {
var table = document.createElement('table');
var textArr = responseText.substring(1, responseText.length - 2).split(',');
for (var i = 0; i < textArr.length; i++) {
var row = table.insertRow(i);
var rowText = textArr[i].substring(1, textArr[i].length - 1).split(':');
var rowKey = rowText[0];
if (rowKey === 'portraitBytes') {
var rowVal = rowText[1].trim();
document.getElementById(PORTRAIT_ID).src = "data:image/jpeg;base64," + rowVal;
continue;
}

if (rowKey.charAt(0) == CHECKMARK_PLACEHOLDER) {
rowKey = CHECKMARK_UNICODE + rowKey.substring(1);
} else if (rowKey.charAt(0) == CROSS_PLACEHOLDER) {
Expand All @@ -59,13 +107,15 @@ function getDeviceResponse() {
rowKey = rowKey.substring(1).bold();
}
row.insertCell(0).innerHTML = rowKey;

if (rowText.length == 2) {
var rowVal = rowText[1].trim();
if (rowVal.charAt(0) == BOLD_PLACEHOLDER) {
rowVal = rowVal.substring(1).bold();
}
row.insertCell(1).innerHTML = rowVal;
}

}
document.getElementById(RESPONSE_ID).append(table);
window.clearInterval(devResponseInterval);
Expand Down
14 changes: 10 additions & 4 deletions wwwverifier/src/main/webapp/style.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
#content {
margin-left: auto;
margin-right: auto;
width: 650px;
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
}

#mdoc-uri-text, #response-display {
overflow-wrap:break-word;
overflow-wrap:break-word;
}

#buttons {
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ public class RequestServletTest {
public void setUp() throws IOException {
MockitoAnnotations.initMocks(this);
servlet = new RequestServlet();
servlet.setStoreLogs(false);
helper.setUp();
}

Expand Down Expand Up @@ -388,7 +389,7 @@ private void sendGetNewSessionRequest() throws IOException {
* Creates a new session, and returns a unique identifier associated with it
*/
private String createSessionKey() {
return RequestServlet.createNewSession().split(",")[1];
return RequestServlet.createNewSession("all").split(",")[1];
}

/**
Expand Down

0 comments on commit 04132ec

Please sign in to comment.