All Downloads are FREE. Search and download functionalities are using the official Maven repository.

craterdog.tokens.V1TokenizationProvider Maven / Gradle / Ivy

/************************************************************************
 * Copyright (c) Crater Dog Technologies(TM).  All Rights Reserved.     *
 ************************************************************************
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.        *
 *                                                                      *
 * This code is free software; you can redistribute it and/or modify it *
 * under the terms of The MIT License (MIT), as published by the Open   *
 * Source Initiative. (See http://opensource.org/licenses/MIT)          *
 ************************************************************************/
package craterdog.tokens;

import craterdog.notary.Notarization;
import craterdog.notary.NotaryCertificate;
import craterdog.notary.NotaryKey;
import craterdog.notary.NotarySeal;
import craterdog.notary.V1NotarizationProvider;
import java.net.URI;
import java.util.LinkedHashMap;
import java.util.Map;
import org.slf4j.ext.XLogger;
import org.slf4j.ext.XLoggerFactory;

/**
 * This class implements a version 1 provider of the TokenManagement interface.
 *
 * @author Derk Norton
 */
public final class V1TokenizationProvider implements Tokenization {

    static private final XLogger logger = XLoggerFactory.getXLogger(V1TokenizationProvider.class);
    static private final Notarization notarizationProvider = new V1NotarizationProvider();


    @Override
    public DigitalToken mintToken(
            URI tokenLocation,
            URI batchLocation,
            URI accountantLocation,
            String tokenType,
            int secondsToLive,
            NotaryKey guarantorKey) {
        logger.entry(tokenLocation, batchLocation, accountantLocation, tokenType, secondsToLive, guarantorKey);
        DigitalToken token = mintToken(tokenLocation, batchLocation, accountantLocation, tokenType, secondsToLive, null, guarantorKey);
        logger.exit(token);
        return token;
    }


    @Override
    public DigitalToken mintToken(
            URI tokenLocation,
            URI batchLocation,
            URI accountantLocation,
            String tokenType,
            int secondsToLive,
            Map additionalAttributes,
            NotaryKey guarantorKey) {
        logger.entry(tokenLocation, batchLocation, accountantLocation, tokenType, secondsToLive, additionalAttributes, guarantorKey);
        URI guarantorLocation = guarantorKey.verificationCertificate.attributes.identityLocation;

        logger.debug("Creating the new token...");
        TokenAttributes attributes = new TokenAttributes();
        attributes.myLocation = tokenLocation;
        attributes.batchLocation = batchLocation;
        attributes.guarantorLocation = guarantorLocation;
        attributes.accountantLocation = accountantLocation;
        attributes.tokenType = tokenType;
        attributes.watermark = notarizationProvider.generateWatermark(secondsToLive);
        if (additionalAttributes != null) {
            logger.debug("Adding additional attributes...");
            for (Map.Entry attribute : additionalAttributes.entrySet()) {
               attributes.put(attribute.getKey(), attribute.getValue());
            }
        }

        logger.debug("Validating the token attributes...");
        DigitalToken token = new DigitalToken();
        token.attributes = attributes;
        Map errors = new LinkedHashMap<>();
        validateTokenAttributes(token, batchLocation, guarantorLocation, accountantLocation, errors);
        notarizationProvider.throwExceptionOnErrors("invalid.token.attributes", errors);

        logger.debug("Notarizing the new token attributes with the guarantor's signing key...");
        String document = attributes.toString();
        token.guarantorSeal = notarizationProvider.notarizeDocument("Token Attributes", document, guarantorKey);

        logger.exit(token);
        return token;
    }


    @Override
    public void certifyToken(DigitalToken token, URI batchLocation, NotaryCertificate guarantorCertificate, NotaryKey accountantKey) {
        logger.entry(batchLocation, token, guarantorCertificate, accountantKey);

        logger.debug("Validating the token attributes...");
        Map errors = new LinkedHashMap<>();
        URI guarantorLocation = guarantorCertificate.attributes.identityLocation;
        URI accountantLocation = accountantKey.verificationCertificate.attributes.identityLocation;
        validateTokenAttributes(token, batchLocation, guarantorLocation, accountantLocation, errors);

        logger.debug("Validating the token guarantor seal...");
        String document = token.attributes.toString();
        NotarySeal guarantorSeal = token.guarantorSeal;
        notarizationProvider.validateDocument(document, guarantorSeal, guarantorCertificate, errors);

        logger.debug("Checking for an existing accountant seal...");
        if (token.accountantSeal != null) {
            logger.error("The token is already certified...");
            errors.put("token.is.already.certified", token);
        }
        notarizationProvider.throwExceptionOnErrors("invalid.token", errors);

        logger.debug("Notarizing the token with the accountant signing key...");
        token.accountantSeal = notarizationProvider.notarizeDocument("Guarantor Seal", token.guarantorSeal.toString(), accountantKey);

        logger.exit();
    }


    @Override
    public void validateToken(DigitalToken token, URI batchLocation, NotaryCertificate guarantorCertificate, NotaryCertificate accountantCertificate, Map errors) {
        logger.entry(token, guarantorCertificate, accountantCertificate, errors);

        logger.debug("Validating the token's attributes...");
        URI guarantorLocation = guarantorCertificate.attributes.identityLocation;
        URI accountantLocation = accountantCertificate.attributes.identityLocation;
        validateTokenAttributes(token, batchLocation, guarantorLocation, accountantLocation, errors);

        logger.debug("Validating the guarantor seal...");
        validateGuarantorSeal(token, guarantorCertificate, errors);

        logger.debug("Validating the accountant seal...");
        validateAccountantSeal(token, accountantCertificate, errors);

        logger.exit(errors);
    }


    private void validateTokenAttributes(DigitalToken token, URI batchLocation, URI guarantorLocation, URI accountantLocation, Map errors) {
        TokenAttributes attributes = token.attributes;
        if (attributes == null) {
            logger.error("The token attributes are missing...");
            errors.put("token.attributes.are.missing", token);
        } else {
            if (attributes.myLocation == null) {
                logger.error("The token location is missing...");
                errors.put("token.location.is.missing", token);
            }
            if (attributes.batchLocation == null) {
                logger.error("The batch location is missing...");
                errors.put("batch.location.is.missing", token);
            } else if (!attributes.batchLocation.equals(batchLocation)) {
                logger.error("The batch location is wrong...");
                errors.put("batch.location.is.wrong", token);
            }
            if (attributes.guarantorLocation == null) {
                logger.error("The guarantor location is missing...");
                errors.put("guarantor.location.is.missing", token);
            } else if (!attributes.guarantorLocation.equals(guarantorLocation)) {
                logger.error("The guarantor location is wrong...");
                errors.put("guarantor.location.is.wrong", token);
            }
            if (attributes.accountantLocation == null) {
                logger.error("The accountant location is missing...");
                errors.put("accountant.location.is.missing", token);
            } else if (!attributes.accountantLocation.equals(accountantLocation)) {
                logger.error("The accountant location is wrong...");
                errors.put("accountant.location.is.wrong", token);
            }
            if (attributes.tokenType == null || attributes.tokenType.isEmpty()) {
                logger.error("The token type is missing...");
                errors.put("token.type.is.missing", token);
            }
            notarizationProvider.validateWatermark(attributes.watermark, errors);
        }
    }


    private void validateGuarantorSeal(DigitalToken token, NotaryCertificate guarantorCertificate, Map errors) {
        TokenAttributes attributes = token.attributes;  // already verified not to be null
        NotarySeal guarantorSeal = token.guarantorSeal;
        if (guarantorSeal == null) {
            logger.error("The token guarantor seal is missing...");
            errors.put("token.guarantor.seal.is.missing", token);
        } else {
            String document = attributes.toString();
            notarizationProvider.validateDocument(document, guarantorSeal, guarantorCertificate, errors);
        }
    }


    private void validateAccountantSeal(DigitalToken token, NotaryCertificate accountantCertificate, Map errors) {
        NotarySeal guarantorSeal = token.guarantorSeal;  // already verified not to be null
        NotarySeal accountantSeal = token.accountantSeal;
        if (accountantSeal == null) {
            logger.error("The token accountant seal is missing...");
            errors.put("token.accountant.seal.is.missing", token);
        } else {
            String document = guarantorSeal.toString();
            notarizationProvider.validateDocument(document, accountantSeal, accountantCertificate, errors);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy