001package org.syncany.plugins.transfer;
002
003import java.lang.reflect.Field;
004import java.util.List;
005
006import org.simpleframework.xml.convert.Converter;
007import org.simpleframework.xml.stream.InputNode;
008import org.simpleframework.xml.stream.OutputNode;
009import org.syncany.config.UserConfig;
010import org.syncany.util.ReflectionUtil;
011
012import com.google.common.collect.Lists;
013
014/**
015 * Converter to encrypt fields marked with the {@link Encrypted}
016 * annotation. Every marked field is encrypted with the user-specific
017 * config key from {@link UserConfig}.
018 * 
019 * @author Christian Roth (christian.roth@port17.de)
020 */
021public class EncryptedTransferSettingsConverter implements Converter<String> {
022        private List<String> encryptedFields;
023
024        public EncryptedTransferSettingsConverter() {
025                // Nothing.
026        }
027
028        public EncryptedTransferSettingsConverter(Class<? extends TransferSettings> transferSettingsClass) {
029                this.encryptedFields = getEncryptedFields(transferSettingsClass);
030        }
031
032        @Override
033        public String read(InputNode node) throws Exception {
034                InputNode encryptedAttribute = node.getAttribute("encrypted");
035                
036                if (encryptedAttribute != null && encryptedAttribute.getValue().equals(Boolean.TRUE.toString())) {
037                        return TransferSettings.decrypt(node.getValue());
038                }
039
040                return node.getValue();
041        }
042
043        @Override
044        public void write(OutputNode node, String raw) throws Exception {
045                if (encryptedFields.contains(node.getName())) {
046                        node.setValue(TransferSettings.encrypt(raw));
047                        node.setAttribute("encrypted", Boolean.TRUE.toString());
048                }
049                else {
050                        node.setValue(raw);
051                }
052        }
053
054        private List<String> getEncryptedFields(Class<? extends TransferSettings> clazz) {
055                List<String> encryptedFields = Lists.newArrayList();
056                
057                for (Field field : ReflectionUtil.getAllFieldsWithAnnotation(clazz, Encrypted.class)) {
058                        encryptedFields.add(field.getName());
059                }
060                
061                return encryptedFields;
062        }
063}