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

com.nequi.auth.NequiAuth Maven / Gradle / Ivy

package com.nequi.auth;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.commons.codec.binary.Base64;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;

public class NequiAuth implements Serializable {
    private final String DEFAULT_AUTH_GRANT_TYPE = "client_credentials";

    private static NequiAuth instance;
    private String token, tokenType;
    private String authUri, authGranType = DEFAULT_AUTH_GRANT_TYPE;
    private String clientId, clientSecret;
    private Date tokenExpiresAt;

    private NequiAuth() {
        if (instance != null) {
            throw new RuntimeException("Use getInstance() method to get the single instance of this class.");
        }
    }

    public static NequiAuth getInstance() {
        if (instance == null) {
            instance = new NequiAuth();
        }

        return instance;
    }

    /**
     * Sets the HTTP URI for the OAuth service
     * @param authUri Endpoint URI
     * @return NequiAuth
     */
    public NequiAuth withAuthUri(String authUri) {
        this.authUri = authUri;

        return this;
    }

    /**
     * Sets the grant type for the OAuth service
     * @param authGranType Auth grant type
     * @return NequiAuth
     */
    public NequiAuth withAuthGranType(String authGranType) {
        this.authGranType = authGranType;

        return this;
    }

    /**
     * Sets the client id used in header authentication for the OAuth service
     * @param clientId  Client id provided by Nequi
     * @return NequiAuth
     */
    public NequiAuth withClientId(String clientId) {
        this.clientId = clientId;

        return this;
    }

    /**
     * Sets the client secret used in header authentication for the OAuth service
     * @param clientSecret Client secret provided by Nequi
     * @return NequiAuth
     */
    public NequiAuth withClientSecret(String clientSecret) {
        this.clientSecret = clientSecret;

        return this;
    }

    /**
     * Loads all needed vars from environment vars
     * @return NequiAuth
     */
    public NequiAuth fromEnvVars() {
        this.clientId = System.getenv("NEQUI_CLIENT_ID");
        this.clientSecret = System.getenv("NEQUI_CLIENT_SECRET");
        this.authUri = System.getenv("NEQUI_AUTH_URI");
        this.authGranType = System.getenv("NEQUI_AUTH_GRANT_TYPE");

        return this;
    }

    /**
     * Loads all needed vars passed by arguments
     * @param clientId Client id provided by Nequi
     * @param clientSecret Client secret provided by Nequi
     * @param authUri Auth endpoint URI
     * @param authGranType Auth grant type
     * @return NequiAuth
     */
    public NequiAuth with(String clientId, String clientSecret, String authUri, String authGranType) {
        this.clientId = clientId;
        this.clientSecret = clientSecret;
        this.authUri = authUri;
        this.authGranType = authGranType;

        return this;
    }

    /**
     * Loads all needed vars passed by arguments
     * @param clientId Client id provided by Nequi
     * @param clientSecret Client secret provided by Nequi
     * @param authUri Auth endpoint URI
     * @return NequiAuth
     */
    public NequiAuth with(String clientId,  String clientSecret, String authUri) {
        return this.with(clientId, clientSecret, authUri, DEFAULT_AUTH_GRANT_TYPE);
    }

    /**
     * Calls the OAuth service and stores the token information
     * @throws Exception
     */
    private void auth() throws Exception {
        HttpURLConnection connection = null;

        if (this.authUri == null || this.clientId == null || this.clientSecret == null) {
            throw new Exception("Invalid credentials, please provide a valid AuthUri, ClientId and ClientSecret.");
        }

        try {
            URL url = new URL(String.format("%s?grant_type=%s", this.authUri, this.authGranType));
            connection = (HttpURLConnection) url.openConnection();

            String basicAuth = String.format("%s:%s", this.clientId, this.clientSecret);
            String auth = Base64.encodeBase64String(basicAuth.getBytes());

            connection.setRequestMethod("POST");
            connection.setRequestProperty("Accept", "application/json");
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.setRequestProperty("Authorization", String.format("Basic %s", auth));

            int status = connection.getResponseCode();

            if (status == 200) {
                // Load HTTP response
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String inputLine;
                StringBuilder content = new StringBuilder();
                while ((inputLine = bufferedReader.readLine()) != null) {
                    content.append(inputLine);
                }

                bufferedReader.close();

                // Parse response to JSON and save information
                JsonObject tokenData = new JsonParser().parse(content.toString()).getAsJsonObject();

                this.token = tokenData.get("access_token").getAsString();
                this.tokenType = tokenData.get("token_type").getAsString();

                long tokenExpiresSecs = tokenData.get("expires_in").getAsLong();
                this.tokenExpiresAt = new Date(System.currentTimeMillis() + (tokenExpiresSecs * 1000));
            } else {
                throw new Exception(
                    String.format("Error %d: Unable to auth with Conecta Nequi, please check the information sent.", status)
                );
            }
        } catch (Exception e) {
            throw e;
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    /**
     * Checks if the current token is valid
     * @return True if the current token is valid
     */
    private boolean isValidToken() {
        if (this.tokenExpiresAt == null) {
            return false;
        }

        return new Date().before(this.tokenExpiresAt);
    }

    /**
     * Get a valid token
     * @param full Indicates if the token includes the token type
     * @return Token(If the value full is passed in true, it will return the token type and token joined)
     * @throws Exception
     */
    public String getToken(boolean full) throws Exception {
        if (!this.isValidToken()) {
            this.auth();
        }

        return full ? String.format("%s %s", this.tokenType, this.token) : this.token;
    }

    /**
     * Get a valid token
     * @return Token without token type
     * @throws Exception
     */
    public String getToken() throws Exception {
        return this.getToken(true);
    }

    /**
     * Make singleton from serialize and deserialize operation
     * @return NequiAuth
     */
    protected NequiAuth readResolve() {
        return getInstance();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy