From cf0d03e7fbffdfcf9f5e1dd4c643bf5030f3d8ca Mon Sep 17 00:00:00 2001 From: Sam Vitello Date: Fri, 17 May 2019 16:21:01 -0600 Subject: [PATCH] Revert "refactor: change signature requirements for justifications and user settings" --- package.json | 2 +- serverless.yml | 14 +----- src/court/justifications.js | 90 ++++++++++++++++++++----------------- src/global/user-settings.js | 21 ++++----- 4 files changed, 61 insertions(+), 66 deletions(-) diff --git a/package.json b/package.json index fa5d6b7..7ca4d2b 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "commitmsg": "kleros-scripts commitmsg", "cz": "kleros-scripts cz", "invoke": "env-cmd ./.env serverless invoke -l -f", - "build": "docker run --rm -v $PWD:/data -w /data lambci/lambda:build-nodejs8.10 npm rebuild scrypt", + "build": "docker run --rm -v $PWD:/data -w /data node:8 npm rebuild scrypt", "deploy:function": "env-cmd ./.env serverless deploy function -f", "deploy:staging": "env-cmd ./.env serverless deploy", "deploy": "env-cmd ./.env serverless deploy -s production" diff --git a/serverless.yml b/serverless.yml index 680e938..194af8a 100644 --- a/serverless.yml +++ b/serverless.yml @@ -251,12 +251,7 @@ functions: - { Effect: Allow, Action: ['dynamodb:Query'], - Resource: 'arn:aws:dynamodb:us-east-2:547511976516:table/kovan-justifications', - } - - { - Effect: Allow, - Action: ['dynamodb:Query'], - Resource: 'arn:aws:dynamodb:us-east-2:547511976516:table/mainnet-justifications', + Resource: 'arn:aws:dynamodb:us-east-2:547511976516:table/justifications', } documentation: summary: 'Get justifications for a dispute round.' @@ -295,12 +290,7 @@ functions: - { Effect: Allow, Action: ['dynamodb:PutItem'], - Resource: 'arn:aws:dynamodb:us-east-2:547511976516:table/kovan-justifications', - } - - { - Effect: Allow, - Action: ['dynamodb:PutItem'], - Resource: 'arn:aws:dynamodb:us-east-2:547511976516:table/mainnet-justifications', + Resource: 'arn:aws:dynamodb:us-east-2:547511976516:table/justifications', } documentation: summary: 'Put justification for a vote.' diff --git a/src/court/justifications.js b/src/court/justifications.js index 9e5e43d..6f1fe4b 100644 --- a/src/court/justifications.js +++ b/src/court/justifications.js @@ -17,7 +17,7 @@ module.exports.get = async (event, _context, callback) => { } }, KeyConditionExpression: 'disputeIDAndAppeal = :disputeIDAndAppeal', - TableName: `${payload.network}-justifications` + TableName: 'justifications' }) } }) @@ -32,63 +32,71 @@ module.exports.put = async (event, _context, callback) => { process.env.KLEROS_LIQUID_ADDRESS ) + // Validate signature const payload = JSON.parse(event.body).payload - - // Verify votes belong to user - const dispute = await klerosLiquid.methods.getDispute( - payload.justification.disputeID - ).call() - - // Get number of votes in current round - const votesInRound = dispute.votesLengths[payload.justification.appeal] - - let drawn = false - let voteID - for (let i = 0; i < Number(votesInRound); i++) { - const vote = await klerosLiquid.methods - .getVote(payload.justification.disputeID, payload.justification.appeal, i) - .call() - if (vote.account === payload.address) { - // If voted, can no longer submit justification. - if (vote.voted) { - return callback(null, { - statusCode: 403, - headers: { 'Access-Control-Allow-Origin': '*' }, - body: JSON.stringify({ - error: 'This address has already cast their vote.' - }) - }) - } - // Once we know address has been drawn we can stop searching. - drawn = true - voteID = i - break - } - } - - if (!drawn) { + try { + if ( + (await web3.eth.accounts.recover( + JSON.stringify(payload.justification), + payload.signature + )) !== + (await dynamoDB.getItem({ + Key: { address: { S: payload.address } }, + TableName: 'user-settings', + ProjectionExpression: 'derivedAccountAddress' + })).Item.derivedAccountAddress.S + ) + throw new Error( + "Signature does not match the supplied address' derived account address for justifications." + ) + } catch (err) { + console.error(err) return callback(null, { statusCode: 403, headers: { 'Access-Control-Allow-Origin': '*' }, body: JSON.stringify({ - error: 'This address was not drawn.' + error: + "Signature is invalid or does not match the supplied address' derived account address for justifications." }) }) } - // Save justification. + // Verify votes belong to user + for (const voteID of payload.justification.voteIDs) { + const vote = await klerosLiquid.methods + .getVote( + payload.justification.disputeID, + payload.justification.appeal, + voteID + ) + .call() + if (vote.account !== payload.address || vote.voted) + return callback(null, { + statusCode: 403, + headers: { 'Access-Control-Allow-Origin': '*' }, + body: JSON.stringify({ + error: + 'Not all of the supplied vote IDs belong to the supplied address and are not cast.' + }) + }) + } + + // Save justification await dynamoDB.putItem({ Item: { disputeIDAndAppeal: { S: `${payload.justification.disputeID}-${payload.justification.appeal}` }, - address: { - S: payload.address + voteID: { + N: String( + payload.justification.voteIDs[ + payload.justification.voteIDs.length - 1 + ] + ) }, - voteID: { N: String(voteID) }, justification: { S: payload.justification.justification } }, - TableName: `${payload.network}-justifications` + TableName: 'justifications' }) callback(null, { statusCode: 200, diff --git a/src/global/user-settings.js b/src/global/user-settings.js index 0bf365d..d658d53 100644 --- a/src/global/user-settings.js +++ b/src/global/user-settings.js @@ -27,19 +27,16 @@ module.exports.get = async (event, _context, callback) => { // Validate signature const payload = JSON.parse(event.body).payload try { - const account = await web3.eth.accounts.recover( - JSON.stringify(payload.settings), - payload.signature - ) - // accept if sig is from account or derived account if ( - account !== payload.address && - account !== - (await dynamoDB.getItem({ - Key: { address: { S: payload.address } }, - TableName: 'user-settings', - ProjectionExpression: 'derivedAccountAddress' - })).Item.derivedAccountAddress.S + (await web3.eth.accounts.recover( + JSON.stringify(payload.settings), + payload.signature + )) !== + (await dynamoDB.getItem({ + Key: { address: { S: payload.address } }, + TableName: 'user-settings', + ProjectionExpression: 'derivedAccountAddress' + })).Item.derivedAccountAddress.S ) throw new Error('Signature does not match supplied address.') } catch (err) {