@Override public Path move(final Path file, final Path renamed, final TransferStatus status, final Delete.Callback callback, final ConnectionCallback connectionCallback) throws BackgroundException { // Move inside vault moves actual files and only metadata files for directories but not the actual directories final Path target = proxy.move( vault.encrypt(session, file, file.isDirectory()), vault.encrypt(session, renamed, file.isDirectory()), status, callback, connectionCallback); return vault.decrypt(session, target); }
@Override public void post(final Transfer.Type type, final Map<TransferItem, TransferStatus> files, final ConnectionCallback callback) throws BackgroundException { for(Map.Entry<TransferItem, TransferStatus> file : files.entrySet()) { registry.find(session, file.getKey().remote).getFeature(session, Bulk.class, proxy).post(type, Collections.singletonMap(file.getKey(), file.getValue()), callback); } }
@Override public void archive(final Archive archive, final Path workdir, final List<Path> files, final ProgressListener listener, final TranscriptListener transcript) throws BackgroundException { final List<Path> encrypted = new ArrayList<>(); for(Path f : files) { encrypted.add(vault.encrypt(session, f)); } delegate.archive(archive, vault.encrypt(session, workdir), encrypted, listener, transcript); }
@Override public PathAttributes find(final Path file) throws BackgroundException { final PathAttributes attributes = new PathAttributes(delegate.withCache(new CryptoPathCache(cache)).find(vault.encrypt(session, file))); if(file.isFile()) { attributes.setSize(vault.toCleartextSize(attributes.getSize())); } return attributes; }
@Override public void visit(final AttributedList<Path> list, final int index, final Path f) { try { f.getType().add(Path.Type.encrypted); list.set(index, vault.decrypt(session, f)); } catch(BackgroundException e) { log.error(String.format("Failure decrypting %s. %s", f, e.getDetail())); f.getType().remove(Path.Type.encrypted); } }
@Override public AttributedList<Path> list(final Path directory, final ListProgressListener listener) throws BackgroundException { try { final Vault vault = registry.find(session, directory); if(vault.contains(directory)) { return vault.getFeature(session, ListService.class, proxy).list(directory, listener); } if(autodetect) { return new VaultFinderListService(session, proxy, new VaultFinderListProgressListener(lookup)).list(directory, listener); } return proxy.list(directory, listener); } catch(VaultUnlockCancelException e) { log.warn(String.format("Canceled loading vault %s. %s", e.getVault(), e.getDetail())); throw e; } }
@Override public boolean contains(final Path directory) { for(Vault vault : this) { if(directory.equals(vault.getHome())) { return true; } } return false; }
@Override public Vault load(final Path directory, final String masterkey, final byte[] pepper) throws VaultUnlockCancelException { synchronized(registry) { if(registry.contains(directory)) { return registry.find(session, directory); } final Vault vault = VaultFactory.get(directory, masterkey, pepper); if(log.isInfoEnabled()) { log.info(String.format("Loading vault %s for session %s", vault, session)); } try { registry.add(vault.load(session, prompt, keychain)); } catch(BackgroundException e) { log.warn(String.format("Failure loading vault %s. %s", vault, e.getDetail())); throw new VaultUnlockCancelException(vault, e); } return vault; } } }
/** * @param session Connection * @param file File * @param lookup Find and load any vault * @return Open or disabled vault */ public Vault find(final Session session, final Path file, final boolean lookup) throws VaultUnlockCancelException { for(Vault vault : this) { if(vault.contains(file)) { if(log.isDebugEnabled()) { log.debug(String.format("Found vault %s for file %s", vault, file)); } return vault; } } if(lookup) { final LoadingVaultLookupListener listener = new LoadingVaultLookupListener(session, this, keychain, prompt); if(file.attributes().getVault() != null) { return listener.load(file.attributes().getVault(), DEFAULT_MASTERKEY_FILE_NAME, DEFAULT_PEPPER); } final Path directory = file.getParent(); if(directory.attributes().getVault() != null) { return listener.load(directory.attributes().getVault(), DEFAULT_MASTERKEY_FILE_NAME, DEFAULT_PEPPER); } } return Vault.DISABLED; }
@Override public boolean offset(final Path file) throws BackgroundException { try { return proxy.offset(vault.encrypt(session, file)); } catch(NotfoundException e) { return false; } }
@Override public String getActivity() { return MessageFormat.format(LocaleFactory.localizedString("Making directory {0}", "Status"), vault.getHome().getName()); }
@Override public LifecycleConfiguration getConfiguration(final Path container) throws BackgroundException { return delegate.getConfiguration(vault.encrypt(session, container)); }
@Override public R pre(final Transfer.Type type, final Map<TransferItem, TransferStatus> files, final ConnectionCallback callback) throws BackgroundException { for(Map.Entry<TransferItem, TransferStatus> file : files.entrySet()) { registry.find(session, file.getKey().remote).getFeature(session, Bulk.class, proxy).pre(type, Collections.singletonMap(file.getKey(), file.getValue()), callback); } return proxy.pre(type, files, callback); }
@Override public Algorithm getDefault(final Path file) throws BackgroundException { return delegate.getDefault(vault.encrypt(session, file)); }
@Override @SuppressWarnings("unchecked") public T lock(final Path file) throws BackgroundException { return (T) registry.find(session, file).getFeature(session, Lock.class, proxy).lock(file); }
@Override public Set<Algorithm> getKeys(final Path file, final LoginCallback prompt) throws BackgroundException { return delegate.getKeys(vault.encrypt(session, file), prompt); }
@Override @SuppressWarnings("unchecked") public Output upload(final Path file, final Local local, final BandwidthThrottle throttle, final StreamListener listener, final TransferStatus status, final ConnectionCallback callback) throws BackgroundException { return (Output) registry.find(session, file).getFeature(session, Upload.class, proxy).upload(file, local, throttle, listener, status, callback); }
@Override public void unarchive(final Archive archive, final Path file, final ProgressListener listener, final TranscriptListener transcript) throws BackgroundException { delegate.unarchive(archive, vault.encrypt(session, file), listener, transcript); }
@Override public boolean isRevertable(final Path file) { try { return registry.find(session, file).getFeature(session, Versioning.class, proxy).isRevertable(file); } catch(VaultUnlockCancelException e) { return false; } }