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

com.piiano.vault.orm.encryption.Encrypted Maven / Gradle / Ivy

There is a newer version: 1.3.3
Show newest version
package com.piiano.vault.orm.encryption;

import com.piiano.vault.client.openapi.model.EncryptionType;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.DynamicParameterizedType;
import org.hibernate.usertype.UserType;

import javax.persistence.Column;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.*;
import java.util.stream.Collectors;

/**
 * This class is used to tokenize a field of an entity. it implements the UserType interface
 * This class implements the nullSafeSet method which is called by the ORM before persisting the entity and
 * before executing the find queries
 * In the implementation of the nullSafeSet method, the field value is being replaced by the token id and
 * is set to the field.
 * The token id is calculated before the entity is persisted and is stored in the vault by using the hash
 * method of the TokenApi which retrieves equal token id for deterministic token for the same value.
 */
public class Encrypted implements UserType, DynamicParameterizedType {

	public static final String TYPE = "type";
	public static final String COLLECTION = "collection";
	public static final String PROPERTY = "property";

	private Encryptor encryptor;

	@Override
	public int[] sqlTypes() {
		return new int[] { Types.VARCHAR };
	}

	@Override
	public Class returnedClass() {
		return String.class;
	}

	@Override
	public boolean equals(Object x, Object y) throws HibernateException {
		return Objects.equals(x, y);
	}

	@Override
	public int hashCode(Object x) throws HibernateException {
		return x != null ? x.hashCode() : 0;
	}

	@Override
	public Object deepCopy(Object value) throws HibernateException {
		return value;
	}

	@Override
	public boolean isMutable() {
		return false;
	}

	@Override
	public Serializable disassemble(Object value) throws HibernateException {
		Object deepCopy = deepCopy(value);
		if ((deepCopy instanceof Serializable)) {
			return (Serializable) deepCopy;
		}
		return null;
	}

	@Override
	public Object assemble(Serializable cached, Object owner) throws HibernateException {
		return deepCopy(cached);
	}

	@Override
	public Object replace(Object original, Object target, Object owner) throws HibernateException {
		return deepCopy(original);
	}

	@Override
	public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner)
			throws HibernateException, SQLException {

		try {
			String value = rs.getString(names[0]);

			saveEncryptedValueOnOwner(owner, value);

			if (encryptor.isEncrypted(value)) {
				value = encryptor.decrypt(value).toString();
			}
			return value;
		} catch (Exception e) {
			throw new HibernateException(e);
		}
	}

	@Override
	public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session)
			throws HibernateException, SQLException {

		if (value == null) {
			st.setNull(index, Types.VARCHAR);
			return;
		}

		try {
			String propValue = value.toString();

			if (propValue != null && !encryptor.isEncrypted(propValue)) {
				propValue = encryptor.encrypt(propValue);
			}

			st.setString(index, propValue);
		} catch (Exception e) {
			throw new HibernateException(e);
		}
	}

	@Override
	public void setParameterValues(Properties parameters) {

		EncryptionType encryptionType = EncryptionType.DETERMINISTIC;
		if (EncryptionType.RANDOMIZED.toString().equalsIgnoreCase(parameters.getProperty(TYPE))) {
			encryptionType = EncryptionType.RANDOMIZED;
		}

		ParameterType parameterType = (ParameterType) parameters.get(DynamicParameterizedType.PARAMETER_TYPE);

		String collection = parameters.getProperty(COLLECTION) != null ?
				parameters.getProperty(COLLECTION) :
				parameterType.getTable();

		String propertyName = parameters.getProperty(PROPERTY);
		if (propertyName == null) {
			Optional columnName =
					Arrays.stream(parameterType.getAnnotationsMethod())
							.filter(a -> a.annotationType().isAssignableFrom(Column.class))
							.map(c -> ((Column) c).name())
							.findFirst();

			if (columnName.isPresent()) {
				propertyName = columnName.get();
			}
		}

		encryptor = new Encryptor(encryptionType, collection, propertyName);
	}

	private void saveEncryptedValueOnOwner(Object owner, String encryptedValue) throws IllegalAccessException {
		Class clazz = owner.getClass();
		Optional propertyField = Arrays.stream(clazz.getDeclaredFields())
			.filter(f -> f.getName().equals(encryptor.getPropertyName()))
			.collect(Collectors.toList())
			.stream().findFirst();

		if (propertyField.isPresent()) {
			Field field = propertyField.get();
			field.setAccessible(true);
			field.set(owner, encryptedValue);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy