arces.unibo.SEPA.client.api.SPARQL11SEProperties.java Source code

Java tutorial

Introduction

Here is the source code for arces.unibo.SEPA.client.api.SPARQL11SEProperties.java

Source

/* This class is part of the SPARQL 1.1 SE Protocol (an extension of the W3C SPARQL 1.1 Protocol) API
 * 
 * Author: Luca Roffia (luca.roffia@unibo.it)
    
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.
    
You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package arces.unibo.SEPA.client.api;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import java.security.*;

import java.util.Date;
import java.util.NoSuchElementException;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;

import arces.unibo.SEPA.commons.protocol.SPARQL11Properties;

import sun.misc.*;

/**
 * The Class SPARQL11SEProperties.
 * 
 * {"parameters":{
   "host":"localhost",
   "port":8000,
   "scheme":"http",
   "path":"/sparql",
   "query":{"method":"POST","format":"JSON"},
   "update":{"method":"URL_ENCODED_POST","format":"HTML"},
   "subscribe":{"port":9000,"scheme":"ws"},
   "securesubscribe":{"port":9443,"scheme":"wss","path":"/secure/sparql"},
   "secureupdate":{"port":8443,"scheme":"https"},
   "securequery":{"port":8443,"scheme":"https"},
   "authorizationserver":{
  "register":"/oauth/register","requesttoken":"/oauth/token",
  "port":8443,"scheme":"https"},
   "security":{
  "client_id":"2onesV7vDw9TvXTBt6JlrD0MV6f8eU+Xd8hqTpyok0PcnuFi19HwGTOwdJ56uZDR",
  "client_secret":"qp6AulTNzU3jMdUY45+eNgQ3+iilVaBuAADR64w9vqmVYtzk814g2x5ZLAgngT7s",
  "jwt":"xabtQWoH8RJJk1FyKJ78J8h8i2PcWmAugfJ4J6nMd+3Adk0TRGMLTGccxJUiJyyc2yRaVage8/Tz\ndZJiz2jdRP8bhkuNzFhGx6N1/1mgmvfKihLheMmcU0pLj5uKOYWFb+TB98n1IpNO4G69lia2YoR1\n5LScBzibBPpmKWF+XAr5TeDDHDZQK4N3VBS/e3tFL/yOhkfC9Mw45s3mz83oydQazps2cFzookIh\nydKJWfupSsIpj+KmOAjcfC9/tTs3K5uCw8It/0FKvsuW0MAboo4X49sDS+AHTOnVUf67wnnPqJ2M\n1thThv3dIr/WNn+8xJovJWkwcpGP4T7nH7MOCfZzVnKTHr4hN3q14VUWHYne1Mbui7F238uxPBhm\nGoMoSnd7dpaVGHZK9Kfa97HuiKN8s2SfRBcyLOnlBczjgQAaKYdJRUXndWQhPIu1W0oZUxH//6Kx\nA+cquekGC+mzeC8QscLmuwOkBaYIX2Va9600gErGqtHisgNwUUH/g73zjO4pD+xLL/cXuudp89Vq\nu+FyVDOqH5GoCX3G4PMPXLoVuBm4Zt2yQdPvpshH3mrGJsPxS8f1PeVnR6Iy5Wbc8a5jiGYHljbs\n0498sKRA0rko/LHSCZwQwuKwuMd110ZvvmQhBUX/23appJ1Wj9hrS1/G5mPXvFQGuZGf+dgynvPT\njeF4RZQVcsfY7jxTwxVC0VRq7dRIncRgmNOHmfKBA18h9fd6gix5RYEX69NvPKEolFyy2wJJxaci\nwW1ub235Gzd/gn+hnNox1g2rIKPu5XY6ttF0L5HwQmk8aYhusOY=",
  "expires":"gVpKtUqSbe+km85RCBcsBQ==",
  "type":"XPrHEX2xHy+5IuXHPHigMw=="}}
 */
public class SPARQL11SEProperties extends SPARQL11Properties {
    private long expires = 0;
    private String jwt = null;
    private String tokenType = null;
    private String authorization = null;
    private String id = null;
    private String secret = null;

    /** The Constant logger. */
    private static final Logger logger = LogManager.getLogger("SPARQL11SEProperties");

    /**
     * The new primitives introduced by the SPARQL 1.1 SE Protocol are: 
     * 
     * SECUREUPDATE,SECUREQUERY,SUBSCRIBE,SECURESUBSCRIBE,UNSUBSCRIBE,SECUREUNSUBSCRIBE,REGISTER,REQUESTTOKEN
     * 
     * 
    * @author Luca Roffia (luca.roffia@unibo.it)
    * @version 0.1
    * */
    public enum SPARQL11SEPrimitive {
        /** A secure update primitive */
        SECUREUPDATE,
        /** A subscribe primitive */
        SUBSCRIBE,
        /** A secure subscribe primitive. */
        SECURESUBSCRIBE,
        /** A unsubscribe primitive. */
        UNSUBSCRIBE,
        /** A secure unsubscribe primitive. */
        SECUREUNSUBSCRIBE,
        /** A register primitive. */
        REGISTER,
        /** A request token primitive. */
        REQUESTTOKEN,
        /** A secure query primitive. */
        SECUREQUERY
    };

    /**
     * Instantiates a new SPARQL 11 SE properties.
     *
     * @param propertiesFile the properties file
     * @param secret the secret
     * @throws IOException 
     * @throws NoSuchElementException 
     * @throws FileNotFoundException 
     */
    public SPARQL11SEProperties(String propertiesFile, byte[] secret)
            throws FileNotFoundException, NoSuchElementException, IOException {
        super(propertiesFile);
        SEPAEncryption.init(secret);
    }

    /**
     * Instantiates a new SPARQL 11 SE properties.
     *
     * @param propertiesFile the properties file
     * @throws IOException 
     * @throws NoSuchElementException 
     * @throws FileNotFoundException 
     */
    public SPARQL11SEProperties(String propertiesFile)
            throws FileNotFoundException, NoSuchElementException, IOException {
        this(propertiesFile, null);
    }

    public String toString() {
        return parameters.toString();
    }

    @Override
    protected void defaults() {
        super.defaults();

        JsonObject subscribe = new JsonObject();
        subscribe.add("port", new JsonPrimitive(9000));
        subscribe.add("scheme", new JsonPrimitive("ws"));
        subscribe.add("path", new JsonPrimitive("/sparql"));
        parameters.add("subscribe", subscribe);

        JsonObject securesubscribe = new JsonObject();
        securesubscribe.add("port", new JsonPrimitive(9443));
        securesubscribe.add("scheme", new JsonPrimitive("wss"));
        securesubscribe.add("path", new JsonPrimitive("/secure/sparql"));
        parameters.add("securesubscribe", securesubscribe);

        JsonObject secureUpdate = new JsonObject();
        secureUpdate.add("port", new JsonPrimitive(8443));
        secureUpdate.add("scheme", new JsonPrimitive("https"));
        parameters.add("secureupdate", secureUpdate);

        JsonObject secureQuery = new JsonObject();
        secureQuery.add("port", new JsonPrimitive(8443));
        secureQuery.add("scheme", new JsonPrimitive("https"));
        parameters.add("securequery", secureQuery);

        JsonObject register = new JsonObject();
        register.add("register", new JsonPrimitive("/oauth/register"));
        register.add("requesttoken", new JsonPrimitive("/oauth/token"));
        register.add("port", new JsonPrimitive(8443));
        register.add("scheme", new JsonPrimitive("https"));
        parameters.add("authorizationserver", register);
    }

    protected void loadProperties() throws FileNotFoundException, NoSuchElementException, IOException {
        super.loadProperties();

        if (doc.get("security") != null) {
            if (doc.get("security").getAsJsonObject().get("expires") != null)
                expires = Long.decode(
                        SEPAEncryption.decrypt(doc.get("security").getAsJsonObject().get("expires").getAsString()));
            else
                expires = 0;

            if (doc.get("security").getAsJsonObject().get("jwt") != null)
                jwt = SEPAEncryption.decrypt(doc.get("security").getAsJsonObject().get("jwt").getAsString());
            else
                jwt = null;

            if (doc.get("security").getAsJsonObject().get("type") != null)
                tokenType = SEPAEncryption.decrypt(doc.get("security").getAsJsonObject().get("type").getAsString());
            else
                tokenType = null;

            if (doc.get("security").getAsJsonObject().get("client_id") != null
                    && doc.get("security").getAsJsonObject().get("client_secret") != null) {
                id = SEPAEncryption.decrypt(doc.get("security").getAsJsonObject().get("client_id").getAsString());
                secret = SEPAEncryption
                        .decrypt(doc.get("security").getAsJsonObject().get("client_secret").getAsString());
                try {
                    authorization = new BASE64Encoder().encode((id + ":" + secret).getBytes("UTF-8"));

                    //TODO need a "\n", why?
                    authorization = authorization.replace("\n", "");
                } catch (UnsupportedEncodingException e) {
                    logger.error(e.getMessage());
                }
            } else
                authorization = null;
        }
    }

    public int getSubscribePort() {
        return getParameter("subscribe", "port", 9000);
    }

    public String getSubscribePath() {
        return getParameter("subscribe", "path", "/sparql");
    }

    public String getSubscribeScheme() {
        return getParameter("subscribe", "scheme", "ws");
    }

    public int getSubscribeSecurePort() {
        return getParameter("securesubscribe", "port", 9443);
    }

    public int getUpdateSecurePort() {
        return getParameter("secureupdate", "port", 8443);
    }

    public int getQuerySecurePort() {
        return getParameter("securequery", "port", 8443);
    }

    public String getRegistrationScheme() {
        return getParameter("authorizationserver", "scheme", "https");
    }

    public String getRequestTokenScheme() {
        return getParameter("authorizationserver", "scheme", "https");
    }

    public String getRegistrationPath() {
        return getParameter("authorizationserver", "register", "/oauth/register");
    }

    public String getRequestTokenPath() {
        return getParameter("authorizationserver", "requesttoken", "/oauth/token");
    }

    public int getRegistrationPort() {
        return getParameter("authorizationserver", "port", 8443);
    }

    public int getRequestTokenPort() {
        return getParameter("authorizationserver", "port", 8443);
    }

    /**
     * Checks if is token expired.
     *
     * @return true, if is token expired
     */
    public boolean isTokenExpired() {
        return (new Date().getTime() >= expires);
    }

    /**
     * Gets the expiring seconds.
     *
     * @return the expiring seconds
     */
    public long getExpiringSeconds() {
        long seconds = ((expires - new Date().getTime()) / 1000);
        if (seconds < 0)
            seconds = 0;
        return seconds;
    }

    /**
     * Gets the access token.
     *
     * @return the access token
     */
    public String getAccessToken() {
        return jwt;
    }

    /**
     * Gets the token type.
     *
     * @return the token type
     */
    public String getTokenType() {
        return tokenType;
    }

    /**
     * Gets the basic authorization.
     *
     * @return the basic authorization
     */
    public String getBasicAuthorization() {
        return authorization;
    }

    /**
     * Sets the credentials.
     *
     * @param id the username
     * @param secret the password
     * @throws IOException 
     */
    public void setCredentials(String id, String secret) throws IOException {
        logger.debug("Set credentials Id: " + id + " Secret:" + secret);

        this.id = id;
        this.secret = secret;

        try {
            authorization = new BASE64Encoder().encode((id + ":" + secret).getBytes("UTF-8"));

            //TODO need a "\n", why?
            authorization = authorization.replace("\n", "");
        } catch (UnsupportedEncodingException e) {
            logger.error(e.getMessage());
        }

        //Save on file the encrypted version   
        if (parameters.get("security") == null) {
            JsonObject credentials = new JsonObject();
            credentials.add("client_id", new JsonPrimitive(SEPAEncryption.encrypt(id)));
            credentials.add("client_secret", new JsonPrimitive(SEPAEncryption.encrypt(secret)));
            parameters.add("security", credentials);
        } else {
            parameters.get("security").getAsJsonObject().add("client_id",
                    new JsonPrimitive(SEPAEncryption.encrypt(id)));
            parameters.get("security").getAsJsonObject().add("client_secret",
                    new JsonPrimitive(SEPAEncryption.encrypt(secret)));
        }

        storeProperties(propertiesFile);
    }

    /**
     * Sets the JWT.
     *
     * @param jwt the JSON Web Token
     * @param expires the date when the token will expire
     * @param type the token type (e.g., bearer)
     * @throws IOException 
     */
    public void setJWT(String jwt, Date expires, String type) throws IOException {

        this.jwt = jwt;
        this.expires = expires.getTime();
        this.tokenType = type;

        //Save on file the encrypted version
        if (parameters.get("security") == null) {
            JsonObject credentials = new JsonObject();
            credentials.add("jwt", new JsonPrimitive(SEPAEncryption.encrypt(jwt)));
            credentials.add("expires",
                    new JsonPrimitive(SEPAEncryption.encrypt(String.format("%d", expires.getTime()))));
            credentials.add("type", new JsonPrimitive(SEPAEncryption.encrypt(type)));
            parameters.add("security", credentials);
        } else {
            parameters.get("security").getAsJsonObject().add("jwt", new JsonPrimitive(SEPAEncryption.encrypt(jwt)));
            parameters.get("security").getAsJsonObject().add("expires",
                    new JsonPrimitive(SEPAEncryption.encrypt(String.format("%d", expires.getTime()))));
            parameters.get("security").getAsJsonObject().add("type",
                    new JsonPrimitive(SEPAEncryption.encrypt(type)));
        }

        storeProperties(propertiesFile);
    }

    /**
     * The Class SEPAEncryption.
     */
    private static class SEPAEncryption {

        /** The Constant ALGO. */
        //AES 128 bits (16 bytes)
        private static final String ALGO = "AES";

        /** The key value. */
        private static byte[] keyValue = new byte[] { '0', '1', 'R', 'a', 'v', 'a', 'm', 'i', '!', 'I', 'e', '2',
                '3', '7', 'A', 'N' };

        /** The key. */
        private static Key key = new SecretKeySpec(keyValue, ALGO);

        /**
         * Inits the.
         *
         * @param secret the secret
         */
        private static void init(byte[] secret) {
            if (secret != null && secret.length == 16)
                keyValue = secret;
            key = new SecretKeySpec(keyValue, ALGO);
        }

        /**
         * Encrypt.
         *
         * @param Data the data
         * @return the string
         */
        public static String encrypt(String Data) {
            try {
                Cipher c = Cipher.getInstance(ALGO);
                c.init(Cipher.ENCRYPT_MODE, key);
                byte[] encVal = c.doFinal(Data.getBytes());
                return new BASE64Encoder().encode(encVal);
            } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
                    | IllegalBlockSizeException | BadPaddingException e) {
                logger.fatal(e.getMessage());
                return null;
            }
        }

        /**
         * Decrypt.
         *
         * @param encryptedData the encrypted data
         * @return the string
         */
        public static String decrypt(String encryptedData) {
            try {
                Cipher c = Cipher.getInstance(ALGO);
                c.init(Cipher.DECRYPT_MODE, key);
                byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
                byte[] decValue = c.doFinal(decordedValue);
                return new String(decValue);
            } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IOException
                    | IllegalBlockSizeException | BadPaddingException e) {
                logger.fatal(e.getMessage());
                return null;
            }
        }
    }

    public String getSecureQueryScheme() {
        return getParameter("securequery", "scheme", "https");
    }

    public String getSecureUpdateScheme() {
        return getParameter("secureupdate", "scheme", "https");
    }

    public Object getSecureSubscribeScheme() {
        return getParameter("securesubscribe", "scheme", "wss");
    }

    public String getSecureUpdatePath() {
        return getParameter("secureupdate", "path", "/sparql");
    }

    public String getSecureQueryPath() {
        return getParameter("securequery", "path", "/sparql");
    }

    public int getSecureSubscribePort() {
        return getParameter("securesubscribe", "port", 9443);
    }

    public String getSecureSubscribePath() {
        return getParameter("securesubscribe", "path", "/secure/sparql");
    }

}