Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement verifier manager #74

Merged
merged 1 commit into from
Dec 27, 2019
Merged

feat: implement verifier manager #74

merged 1 commit into from
Dec 27, 2019

Conversation

Nebulis
Copy link
Contributor

@Nebulis Nebulis commented Dec 12, 2019

Quick summary

So the grand idea is that we will have a verificationManager that can take in verificationMethods

so each verificationMethod will have:
- a test to check if that method will run
- the verification mechanism itself

so, for the current one, we will have likely:
- OpenAttestationTamperCheck
- OpenAttestationEthereumDocumentStoreIssued
- OpenAttestationEthereumDocumentStoreRevoked
- OpenAttestationDnsTxtIdentity

it will also be loaded with:
- OpenCertsRegistryIdentity

each of these will be an object 
{
  test: (Document) => boolean,
  verify: (Document) => VerificationFragment
}

A VerificationFragement will be like: 

{
  type: "OpenAttestationDnsTxtIdentity",
  data: "mpa.gov.sg",
  message: "Error or warning message",
  status: "VALID" | "WARNING" | "ERROR"
}

The verificationManager will summarise all the Fragments and provide a summary as well (for those dev who are too lazy to go further)

The verification manager can also take in conditions to determine the summary status: ie Tamper && Issued && Revoke && (DNS || Registry), etc

Implementation details

  • verificationManager is a function that takes a list of verifiers and return a function. The function expect a signed document and some options as parameter. Options parameter expect the following:
    • a mandatory network string (for instance ropsten)
    • an optional infuraApiKey string
    • an optional promisesCallback callback function that will provide back the promises resolving to the verifications.
  • There are 4 verifiers:
    • openAttestationTamperCheck
    • openAttestationEthereumDocumentStoreIssued
    • openAttestationEthereumDocumentStoreRevoked
    • openAttestationDnsTxtIdentity
  • There is a defaultVerificationManager pre-built having in parameter all the verifiers available in this repository
  • There are 2 validations functions: isValid and isInvalid
  • A verifier is an object that expect 3 functions:
    • test: who must return true or false. The function must indicate whether condition are fulfilled for the verifier to run on a specific signed document
    • verify: who must return the result of the verification as a VerificationFragment
    • skip: who must return the result of a verification when it's skipped by providing additional data on why the validation didn't run.

TODO

  • add tests

@Nebulis Nebulis force-pushed the feat/verifier-manager branch from 661d150 to e95508b Compare December 12, 2019 10:59
@Nebulis
Copy link
Contributor Author

Nebulis commented Dec 13, 2019

I've added tests for verifiers (testing the verifier only not internals)
Didn't add test for the managers => there are already integration tests
Removed apikey as discussed

revokedOnAny: false,
message: "Certificate has not been issued",
status: "INVALID",
type: "OpenAttestationEthereumDocumentStoreIssued"
Copy link
Contributor

@yehjxraymond yehjxraymond Dec 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am thinking that the type should be succinct and general, serving more as a class of verification. We can put these as name of the verification method instead.

Valid class of checks:
INTEGRITY class verification methods checks if the document has been tampered with.
ISSUANCE_STATUES class verification methods checks if the document has been issued and is in the right status (ie. not revoked)
ISSUER_IDENTITY class verification methods checks for the issuer's identity.

In this case the default methods will be:
OpenAttestationTamperCheck -> INTEGRITY
OpenAttestationEthereumDocumentStoreIssued => ISSUANCE_STATUS
OpenAttestationEthereumDocumentStoreRevoked => ISSUANCE_STATUS
OpenAttestationDnsTxtIdentity => ISSUER_IDENTITY

Possible extension will look like:
OpenAttestationEthereumTokenRegistryIssued => ISSUANCE_STATUS
OpenCertsIdentityRegistry => ISSUER_IDENTITY
SomeCountryIdentityRegistry => ISSUER_IDENTITY
CustomExpiryCheck => ISSUANCE_STATUS

Using a known class, it can allow client application to check what type of checks has been performed it they like.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

});
{
message: 'Document issuers doesn\'t have "documentStore" or "token" property',
status: "SKIPPED",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a question...

If I have the OpenCertsRegistry extension:

  1. This method will show skipped
  2. OpenCertsRegistry method will show valid

How should I go about handling it in the method isValid?

src/index.ts Outdated
ReturnType<typeof verifyIssued>,
ReturnType<typeof verifyRevoked>,
Promise<boolean>
import { verificationManager } from "./verifiers/verificationManager";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import { verificationManager } from "./verifiers/verificationManager";
import { verificationBuilder } from "./verifiers/verificationBuilder";

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

src/index.ts Outdated
.catch(() => false);

return [hash, issued, revoked, valid];
const defaultVerificationManager = verificationManager(defaultVerifiers);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const defaultVerificationManager = verificationManager(defaultVerifiers);
const verify = verificationBuilder(defaultVerifiers);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

src/index.ts Outdated
Comment on lines 22 to 32
export {
verificationManager,
isValid,
isInvalid,
openAttestationEthereumDocumentStoreIssued,
openAttestationDnsTxtIdentity,
openAttestationTamperCheck,
openAttestationEthereumDocumentStoreRevoked,
defaultVerifiers,
defaultVerificationManager
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

export {
  verify,
  verificationBuilder,
  isValid,
  isInvalid,
  defaultVerifiers,
  verifiers
}

src/index.ts Outdated

return [hash, issued, revoked, valid];
const defaultVerificationManager = verificationManager(defaultVerifiers);
const isValid = (verificationFragments: VerificationFragment[]) =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isValid(document, requiredChecksClasses)

usage example
isValid(document, ["ISSUER_IDENTITY", "ISSUANCE_STATUS", "INTEGRITY"])

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically isValid checks the fragments that EVERY required checks classes to have at EVERY test either "VALID" or "SKIPPED" and has at least one "VALID".

For example for a documentStore
issued: valid
revoked: invalid
will result in "invalid"

In another case:
issued: valid
revoked: skipped
will result in "valid"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

return documentData.proof.method === v3.Method.TokenRegistry;
}
const documentData = getData(document);
return documentData.issuers.every(issuer => "tokenRegistry" in issuer);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For token registry, we should check of any/some instead of every.

The reason is that if it's using tokenRegistry it MUST be only one issuer, cannot mix it around with documentstore or other tokenregistry.

In the verify function we can throw INVALID if it has been mixed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, returning error if more than one token registry or mix of methods

return documentData.proof.method === v3.Method.DocumentStore;
}
const documentData = getData(document);
return documentData.issuers.every(issuer => "documentStore" in issuer || "certificateStore" in issuer);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we test using some instead?
This will make the verify run for documents that mixes around documentStore and other methods, and that's where this function should throw?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, returning error if one of the issuer is invalid (i.e. doesnt have document store or certificate store)

@Nebulis Nebulis force-pushed the feat/verifier-manager branch from 7012bd0 to 5b569b1 Compare December 27, 2019 05:05
@Nebulis Nebulis merged commit 02c6305 into master Dec 27, 2019
@Nebulis Nebulis deleted the feat/verifier-manager branch December 27, 2019 05:08
@john-dot-oa
Copy link
Contributor

🎉 This PR is included in version 2.2.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants