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

com.vendasta.common.v1.VendastaCredentialsManager Maven / Gradle / Ivy

The newest version!
package com.vendasta.common.v1;

import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.crypto.ECDSASigner;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.security.KeyPair;
import java.security.Security;
import java.security.interfaces.ECPrivateKey;
import java.util.Date;

public class VendastaCredentialsManager implements CredentialsManager {
    private Gson gson = new Gson();
    private String audience;
    private Credentials creds;
    private ECPrivateKey privateKey;
    private String currentToken;
    private Date currentTokenExpiry;

    public VendastaCredentialsManager(InputStream serviceAccount, String audience) throws IOException {
        this.audience = audience;
        creds = gson.fromJson(new InputStreamReader(serviceAccount), Credentials.class);
        currentToken = null;
        currentTokenExpiry = null;

        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        StringReader reader = new StringReader(creds.privateKey);
        Object parsed = new org.bouncycastle.openssl.PEMParser(reader).readObject();
        KeyPair pair = new org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter().getKeyPair((org.bouncycastle.openssl.PEMKeyPair) parsed);
        privateKey = (ECPrivateKey) pair.getPrivate();
    }

    public String getAuthorization() throws CredentialsException {
        Date currentTime = new Date();
        if (currentTokenExpiry != null && currentTime.after(currentTokenExpiry)) {
            refreshToken();
        }

        if (currentToken == null) {
            refreshToken();
        }

        if (currentToken == null) {
            throw new CredentialsException("Could not refresh token");
        }

        return currentToken;
    }

    public void invalidateAuthorization() {
        currentToken = null;
    }

    private void refreshToken() throws CredentialsException {
        String jwtAccess;
        try {
            jwtAccess = buildJWT();
        } catch (Exception e) {
            throw new CredentialsException("Something went wrong with building the credentials", e);
        }

        HttpClient httpClient = HttpClientBuilder.create().build();

        try {
            HttpPost request = new HttpPost(creds.tokenURI);
            StringEntity params = new StringEntity("{\"token\":\"" + jwtAccess + "\"}");
            request.addHeader("content-type", "application/json");
            request.setEntity(params);
            HttpResponse response = httpClient.execute(request);
            String responseAsString = EntityUtils.toString(response.getEntity());
            GetTokenResponse tokenResponse = gson.fromJson(responseAsString, GetTokenResponse.class);
            currentToken = "Bearer " + tokenResponse.token;
            SignedJWT signedJWT = SignedJWT.parse(tokenResponse.token);
            currentTokenExpiry = signedJWT.getJWTClaimsSet().getExpirationTime();
        } catch (Exception e) {
            throw new CredentialsException("An error occured while fetching the token", e);
        }
    }

    private String buildJWT() throws CredentialsException {
        ECDSASigner signer = null;
        try {
            signer = new ECDSASigner(privateKey);
        } catch (JOSEException e) {
            throw new CredentialsException("Could not create ECDSASigner from private key", e);
        }
        JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
                .audience(audience)
                .subject(creds.email)
                .expirationTime(new Date(new Date().getTime() + 60 * 5000))
                .claim("kid", creds.privateKeyID)
                .build();

        SignedJWT signedJWT = new SignedJWT(
                new JWSHeader(JWSAlgorithm.ES256),
                claimsSet);

        try {
            signedJWT.sign(signer);
        } catch (JOSEException e) {
            throw new CredentialsException("Could not sign JWT", e);
        }

        return signedJWT.serialize();
    }

    private class Credentials {
        @SerializedName("private_key_id")
        private String privateKeyID;
        @SerializedName("private_key")
        private String privateKey;
        @SerializedName("client_email")
        private String email;
        @SerializedName("token_uri")
        private String tokenURI;
    }

    private class GetTokenResponse {
        private String token;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy