diff --git a/src/Controller/VerificationController.php b/src/Controller/VerificationController.php index 3c4dd3e..3ea5429 100644 --- a/src/Controller/VerificationController.php +++ b/src/Controller/VerificationController.php @@ -16,6 +16,9 @@ /** * Accepts incoming requests for data verification e.g. from within the CMS * or framework's admin area, and sends them on their way. + * + * Will proxy validation requests to the currently configured backend for both + * {@link SiteTree} and {@link DataObject} subclasses. */ class VerificationController extends Controller { @@ -29,12 +32,13 @@ class VerificationController extends Controller ]; /** - * Verify a page. + * Verify a page: /verify/page/ by echoing a JSON response for + * consumption by client-side logic. * * @param HTTPRequest $request - * @return bool True if verified, false otherwise. + * @return void */ - public function page(HTTPRequest $request) : bool + public function page(HTTPRequest $request) { $id = $request->param('ID'); @@ -47,17 +51,19 @@ public function page(HTTPRequest $request) : bool } $proof = $record->dbObject('Proof'); + $result = json_decode($this->verifiableService->read($proof->getHashIdNode()), true); - return $this->verifiableService->read($proof->getHashIdNode()); + echo $this->verificationResponse($record, $result); } /** - * Verify a data model. + * Verify a data model: /verify/model// by echoing a JSON response for + * consumption by client-side logic. * * @param HTTPRequest $request - * @return bool True if verified, false otherwise. + * @return void */ - public function model(HTTPRequest $request) : bool + public function model(HTTPRequest $request) { $class = $request->param('Class'); $id = $request->param('ID'); @@ -70,9 +76,10 @@ public function model(HTTPRequest $request) : bool return false; } - $proof = $record->dbObject('Proof')->getHashIdNode(); + $proof = $record->dbObject('Proof'); + $result = json_decode($this->verifiableService->read($proof->getHashIdNode()), true); - return $this->verifiableService->read($proof); + echo $this->verificationResponse($record, $result); } /** @@ -88,4 +95,23 @@ private function getVersionedRecord(string $class, int $id) : DataObject return Versioned::get_latest_version($class, $id); } + /** + * Return an JSON representation of the verification result for internal + * use. + * + * @param DataObject $record + * @param string $result + * @return string + */ + private function verificationResponse($record, $result) + { + $isVerified = $record->verify($result, false) ? 'true' : 'false'; + + return json_encode([ + 'ID' => "$record->ID", + 'Class' => get_class($record), + 'IsVerified' => $isVerified, + ], JSON_UNESCAPED_UNICODE); + } + } diff --git a/src/ORM/FieldType/ChainpointProof.php b/src/ORM/FieldType/ChainpointProof.php index c63d217..d89a2d2 100644 --- a/src/ORM/FieldType/ChainpointProof.php +++ b/src/ORM/FieldType/ChainpointProof.php @@ -31,16 +31,26 @@ public function getHashIdNode() : string return $this->query('->>', 'hash_id_node')['hash_id_node']; } + /** + * Returns the generated value of the proof's "hash" key. + * + * @return string + */ + public function getHash() : string + { + $this->setReturnType('array'); + + return $this->query('->>', 'hash')['hash']; + } + /** * Does the passed $hash match in the stored proof? * - * @return boolean + * @return bool */ public function match(string $hash) : bool { - $hashFromProof = json_decode($this->getHashIdNode(), true) ?: ''; - - return $hash === array_values($hashFromProof)[0]; + return $hash === $this->getHash(); } } diff --git a/src/Verify/VerifiableService.php b/src/Verify/VerifiableService.php index ef2ac4f..961982f 100644 --- a/src/Verify/VerifiableService.php +++ b/src/Verify/VerifiableService.php @@ -58,7 +58,7 @@ public function __construct() */ public function write(array $data) { - return $this->backend->hashes([$this->hash($data)]); + return $this->backend->writeHash([$this->hash($data)]); } /** @@ -91,9 +91,13 @@ public function verify(string $proof) : bool */ public function isVerifiedPartial(string $body) : bool { - $anchors = json_decode($body, true)['anchors']; + $data = json_decode($body, true); - return count($anchors) === 1 && $anchors[0]['type'] === 'cal'; + if (isset($data['anchors_complete']) && count($data['anchors_complete']) === 0) { + return false; + } + + return true; } /** @@ -104,10 +108,14 @@ public function isVerifiedPartial(string $body) : bool */ public function isVerifiedFull(string $body) : bool { - $anchors = json_decode($body, true)['anchors']; + $data = json_decode($body, true); + + if (empty($data['anchors_complete']) || empty($data['anchors'])) { + return false; + } // "Full" means anchors to both Etheruem and Bitcoin blockchains - return count($anchors) === 3; // "cal" + "btc" + "eth" + return count($data['anchors']) === 3; // "cal" + "btc" + "eth" } /** @@ -158,7 +166,7 @@ public function getBackend() public function hash(array $data) : string { $func = $this->config()->get('hash_func'); - $text = implode('', $data); + $text = json_encode($data); // Simply used to stringify arrays of arbitary depth return $func($text); }