From e591742e40c391875e3b96895d03ed1e4e0d5917 Mon Sep 17 00:00:00 2001 From: Michael Bumann Date: Sat, 20 Apr 2019 01:10:46 +0200 Subject: [PATCH 1/3] Add Contributor validation against JSON schema based on the Contribution validation. --- lib/contracts/contributor.js | 12 +++-- lib/serializers/contributor.js | 92 +++++++++++++++++++++------------- scripts/add-contributor.js | 2 +- 3 files changed, 65 insertions(+), 41 deletions(-) diff --git a/lib/contracts/contributor.js b/lib/contracts/contributor.js index 8afb820..3d8ce87 100644 --- a/lib/contracts/contributor.js +++ b/lib/contracts/contributor.js @@ -37,12 +37,16 @@ class Contributor extends Record { }); } - add(contributorAttr, callOptions = {}) { - let json = ContributorSerializer.serialize(contributorAttr); - // TODO: validate against schema + async add(contributorAttr, callOptions = {}) { + let contributor = new ContributorSerializer(contributorAttr); + + try { await contributor.validate(); } + catch (error) { return Promise.reject(error); } + + const jsonStr = contributor.serialize(); return this.ipfs - .add(json) + .add(jsonStr) .then((ipfsHashAttr) => { let contributor = [ contributorAttr.account, diff --git a/lib/serializers/contributor.js b/lib/serializers/contributor.js index d426370..b653594 100644 --- a/lib/serializers/contributor.js +++ b/lib/serializers/contributor.js @@ -1,3 +1,5 @@ +const schemas = require('kosmos-schemas'); +const validator = require('../utils/validator'); /** * Handle serialization for JSON-LD object of the contributor, according to * https://github.com/67P/kosmos-schemas/blob/master/schemas/contributor.json @@ -6,41 +8,9 @@ * @public */ class Contributor { - /** - * Deserialize JSON to object - * - * @method - * @public - */ - static deserialize(serialized) { - let { - name, - kind, - url, - accounts, - } = JSON.parse(serialized.toString('utf8')); - let github_username, github_uid, wiki_username; - let github = accounts.find((a) => a.site === 'github.com'); - let wiki = accounts.find((a) => a.site === 'wiki.kosmos.org'); - - if (github) { - (({ username: github_username, uid: github_uid} = github)); - } - if (wiki) { - (({ username: wiki_username } = wiki)); - } - - return { - name, - kind, - url, - accounts, - github_uid, - github_username, - wiki_username, - ipfsData: serialized, - }; + constructor(attrs) { + Object.keys(attrs).forEach(a => this[a] = attrs[a]); } /** @@ -49,7 +19,7 @@ class Contributor { * @method * @public */ - static serialize(deserialized) { + serialize () { let { name, kind, @@ -57,7 +27,7 @@ class Contributor { github_uid, github_username, wiki_username, - } = deserialized; + } = this; let data = { "@context": "https://schema.kosmos.org", @@ -91,6 +61,56 @@ class Contributor { // Write it pretty to ipfs return JSON.stringify(data, null, 2); } + + /** + * Validate serialized data against schema + * + * @public + */ + validate () { + const serialized = JSON.parse(this.serialize()); + console.log(serialized); + const valid = validator.validate(serialized, schemas['contributor']); + return valid ? Promise.resolve() : Promise.reject(validator.error); + } + + /** + * Deserialize JSON to object + * + * @method + * @public + */ + deserialize (serialized) { + let { + name, + kind, + url, + accounts, + } = JSON.parse(serialized.toString('utf8')); + + let github_username, github_uid, wiki_username; + let github = accounts.find((a) => a.site === 'github.com'); + let wiki = accounts.find((a) => a.site === 'wiki.kosmos.org'); + + if (github) { + (({ username: github_username, uid: github_uid} = github)); + } + if (wiki) { + (({ username: wiki_username } = wiki)); + } + + return { + name, + kind, + url, + accounts, + github_uid, + github_username, + wiki_username, + ipfsData: serialized, + }; + } + } module.exports = Contributor; diff --git a/scripts/add-contributor.js b/scripts/add-contributor.js index a3f632f..a5528e7 100644 --- a/scripts/add-contributor.js +++ b/scripts/add-contributor.js @@ -26,7 +26,7 @@ module.exports = async function(callback) { kind: await prompt('Kind (default person): ', {default: 'person'}), url: await prompt('URL: '), github_username: await prompt('GitHub username: '), - github_uid: await prompt('GitHub UID: '), + github_uid: parseInt(await prompt('GitHub UID: ')), wiki_username: await prompt('Wiki username: '), }; -- 2.25.1 From 59614201b5156d049f58cc77640575113e2d2eea Mon Sep 17 00:00:00 2001 From: Michael Bumann Date: Sat, 20 Apr 2019 02:15:53 +0200 Subject: [PATCH 2/3] Ups... --- lib/serializers/contributor.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/serializers/contributor.js b/lib/serializers/contributor.js index b653594..df59bf1 100644 --- a/lib/serializers/contributor.js +++ b/lib/serializers/contributor.js @@ -69,7 +69,6 @@ class Contributor { */ validate () { const serialized = JSON.parse(this.serialize()); - console.log(serialized); const valid = validator.validate(serialized, schemas['contributor']); return valid ? Promise.resolve() : Promise.reject(validator.error); } @@ -80,7 +79,7 @@ class Contributor { * @method * @public */ - deserialize (serialized) { + static deserialize (serialized) { let { name, kind, -- 2.25.1 From 9714926e1129fe8ad84e7dbb4e03414fdf2147a1 Mon Sep 17 00:00:00 2001 From: Michael Bumann Date: Sat, 20 Apr 2019 02:17:38 +0200 Subject: [PATCH 3/3] Add function to update contributor profile to wrapper The function updates the contributor profile, adds the new profile to IPFS and does the contract call to update the profile hash --- lib/contracts/contributor.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/contracts/contributor.js b/lib/contracts/contributor.js index 3d8ce87..82b0c4f 100644 --- a/lib/contracts/contributor.js +++ b/lib/contracts/contributor.js @@ -58,6 +58,30 @@ class Contributor extends Record { return this.functions.addContributor(...contributor, callOptions); }); } + + updateProfile(contributorId, updateAttr, callOptions = {}) { + return this.getById(contributorId).then(async (contributor) => { + let updatedContributorAttr = Object.assign(contributor, updateAttr) + let updatedContributor = new ContributorSerializer(updatedContributorAttr); + + try { await updatedContributor.validate(); } + catch (error) { return Promise.reject(error); } + + const jsonStr = updatedContributor.serialize(); + + return this.ipfs + .add(jsonStr) + .then(ipfsHashAttr => { + return this.functions.updateContributorProfileHash( + contributorId, + ipfsHashAttr.hashDigest, + ipfsHashAttr.hashFunction, + ipfsHashAttr.hashSize, + callOptions + ); + }); + }); + } } module.exports = Contributor; -- 2.25.1