mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-04-23 16:09:20 -04:00
Rework
This commit is contained in:
@@ -76,7 +76,7 @@ public class ContextualFileReference {
|
||||
var start = getDataDir();
|
||||
var normalizedPath = FilePath.of(path).normalize().toUnix();
|
||||
if (normalizedPath.startsWith(start) && !normalizedPath.equals(start)) {
|
||||
return "<DATA>" + "/" + start.relativize(normalizedPath);
|
||||
return "<DATA>" + "/" + normalizedPath.relativize(start);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
@@ -133,11 +133,17 @@ public class DataStorageNode {
|
||||
}
|
||||
|
||||
public boolean hasAccess() {
|
||||
return !perUser || availableForUser;
|
||||
// In this case the loading failed
|
||||
// We have access to it, we just can't read it
|
||||
if (!perUser && !readableForUser) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !perUser || readableForUser;
|
||||
}
|
||||
|
||||
JsonNode contentNode;
|
||||
boolean perUser;
|
||||
boolean availableForUser;
|
||||
boolean readableForUser;
|
||||
boolean encrypted;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.xpipe.app.storage;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import io.xpipe.app.ext.DataStoreProvider;
|
||||
import io.xpipe.app.ext.DataStoreProviders;
|
||||
import io.xpipe.app.ext.UserScopeStore;
|
||||
@@ -285,8 +286,15 @@ public class DataStoreEntry extends StorageElement {
|
||||
notes = null;
|
||||
}
|
||||
|
||||
var fileNode = mapper.readTree(storeFile.toFile());
|
||||
var node = DataStorageNode.readPossiblyEncryptedNode(fileNode);
|
||||
DataStorageNode node = null;
|
||||
try {
|
||||
var fileNode = mapper.readTree(storeFile.toFile());
|
||||
node = DataStorageNode.readPossiblyEncryptedNode(fileNode);
|
||||
} catch (JacksonException ex) {
|
||||
ErrorEvent.fromThrowable(ex).omit().expected().handle();
|
||||
node = DataStorageNode.fail();
|
||||
}
|
||||
|
||||
var store = node.parseStore();
|
||||
return Optional.of(new DataStoreEntry(
|
||||
dir,
|
||||
@@ -481,7 +489,7 @@ public class DataStoreEntry extends StorageElement {
|
||||
var notesNode = JsonNodeFactory.instance.objectNode();
|
||||
notesNode.put("markdown", notes);
|
||||
var storageNode = DataStorageNode.encryptNodeIfNeeded(new DataStorageNode(
|
||||
notesNode, storeNode.isPerUser(), storeNode.isAvailableForUser(), storeNode.isEncrypted()));
|
||||
notesNode, storeNode.isPerUser(), storeNode.isReadableForUser(), storeNode.isEncrypted()));
|
||||
var string = mapper.writeValueAsString(storageNode);
|
||||
Files.writeString(encryptedNotesFile, string);
|
||||
} else if (notes != null) {
|
||||
|
||||
@@ -161,16 +161,6 @@ public class StandardStorage extends DataStorage {
|
||||
}
|
||||
|
||||
storeEntries.put(entry.get(), entry.get());
|
||||
} catch (JacksonException ex) {
|
||||
// Data corruption and schema changes are expected
|
||||
|
||||
// We only keep invalid entries in developer mode as there's no point in keeping them in
|
||||
// production.
|
||||
if (AppPrefs.get().isDevelopmentEnvironment()) {
|
||||
directoriesToKeep.add(path);
|
||||
}
|
||||
|
||||
ErrorEvent.fromThrowable(ex).expected().omit().build().handle();
|
||||
} catch (IOException ex) {
|
||||
// IO exceptions are not expected
|
||||
exception.set(new IOException("Unable to load data from " + path + ". Is it corrupted?", ex));
|
||||
|
||||
@@ -238,7 +238,7 @@ public class AppJacksonModule extends SimpleModule {
|
||||
var e = DataStorage.get()
|
||||
.getStoreEntryIfPresent(id)
|
||||
.filter(dataStoreEntry -> dataStoreEntry.getValidity() != DataStoreEntry.Validity.LOAD_FAILED
|
||||
|| !dataStoreEntry.getStoreNode().isAvailableForUser())
|
||||
|| !dataStoreEntry.getStoreNode().isReadableForUser())
|
||||
.orElse(null);
|
||||
if (e == null) {
|
||||
return null;
|
||||
|
||||
@@ -204,7 +204,7 @@ public class SshLocalBridge {
|
||||
var exec = CommandSupport.findProgram(sc, "sshd");
|
||||
if (exec.isEmpty()) {
|
||||
throw ErrorEvent.expected(new IllegalStateException(
|
||||
"No sshd executable found in PATH. The SSH terminal bridge requires a local ssh server"));
|
||||
"No sshd executable found in PATH. The SSH terminal bridge requires a local ssh server to connect to an SSH terminal"));
|
||||
}
|
||||
return exec.get();
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public interface ShellControl extends ProcessControl {
|
||||
|
||||
ShellControl withSourceStore(DataStore store);
|
||||
|
||||
List<ShellInitCommand> getInitCommands();
|
||||
List<ShellTerminalInitCommand> getInitCommands();
|
||||
|
||||
ParentSystemAccess getParentSystemAccess();
|
||||
|
||||
@@ -186,7 +186,7 @@ public interface ShellControl extends ProcessControl {
|
||||
|
||||
ShellControl elevated(ElevationFunction elevationFunction);
|
||||
|
||||
ShellControl withInitSnippet(ShellInitCommand snippet);
|
||||
ShellControl withInitSnippet(ShellTerminalInitCommand snippet);
|
||||
|
||||
default ShellControl subShell(@NonNull ShellDialect type) {
|
||||
var o = new ShellOpenFunction() {
|
||||
|
||||
@@ -138,7 +138,7 @@ public interface ShellDialect {
|
||||
|
||||
String runScriptCommand(ShellControl parent, String file);
|
||||
|
||||
String sourceScriptCommand(ShellControl parent, String file);
|
||||
String sourceScriptCommand(String file);
|
||||
|
||||
String executeCommandWithShell(String cmd);
|
||||
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
package io.xpipe.core.process;
|
||||
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface ShellInitCommand {
|
||||
|
||||
default void runDumb(ShellControl shellControl) throws Exception {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
default Optional<String> terminalContent(ShellControl shellControl) throws Exception {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
default boolean runInDumb() {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean canPotentiallyRunInDialect(ShellDialect dialect);
|
||||
|
||||
default boolean runInTerminal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
interface Terminal extends ShellInitCommand {
|
||||
|
||||
Optional<String> terminalContent(ShellControl shellControl);
|
||||
|
||||
default boolean runInTerminal() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class Simple implements ShellInitCommand {
|
||||
|
||||
@NonNull
|
||||
private final String content;
|
||||
|
||||
private final ShellDialect dialect;
|
||||
|
||||
private final boolean dumb;
|
||||
|
||||
private final boolean terminal;
|
||||
|
||||
public Simple(@NonNull String content, ShellDialect dialect, boolean dumb, boolean terminal) {
|
||||
this.content = content;
|
||||
this.dialect = dialect;
|
||||
this.dumb = dumb;
|
||||
this.terminal = terminal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runDumb(ShellControl shellControl) throws Exception {
|
||||
shellControl.executeSimpleCommand(content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> terminalContent(ShellControl shellControl) {
|
||||
return Optional.of(content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean runInDumb() {
|
||||
return dumb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPotentiallyRunInDialect(ShellDialect dialect) {
|
||||
return this.dialect == null || this.dialect.isCompatibleTo(dialect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean runInTerminal() {
|
||||
return terminal;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package io.xpipe.core.process;
|
||||
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface ShellTerminalInitCommand {
|
||||
|
||||
boolean isStatic();
|
||||
|
||||
Optional<String> content(ShellControl sc);
|
||||
|
||||
boolean canPotentiallyRunInDialect(ShellDialect dialect);
|
||||
|
||||
class Static implements ShellTerminalInitCommand {
|
||||
|
||||
private final String content;
|
||||
private final ShellDialect dialect;
|
||||
|
||||
public Static(String content, ShellDialect dialect) {
|
||||
this.content = content;
|
||||
this.dialect = dialect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> content(ShellControl sc) {
|
||||
return Optional.of(content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPotentiallyRunInDialect(ShellDialect dialect) {
|
||||
return this.dialect == null || this.dialect.isCompatibleTo(dialect);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ public class WrapperShellControl implements ShellControl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ShellInitCommand> getInitCommands() {
|
||||
public List<ShellTerminalInitCommand> getInitCommands() {
|
||||
return parent.getInitCommands();
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ public class WrapperShellControl implements ShellControl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShellControl withInitSnippet(ShellInitCommand snippet) {
|
||||
public ShellControl withInitSnippet(ShellTerminalInitCommand snippet) {
|
||||
return parent.withInitSnippet(snippet);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package io.xpipe.ext.base.identity;
|
||||
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.storage.ContextualFileReference;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.util.SecretRetrievalStrategy;
|
||||
@@ -176,7 +178,7 @@ public interface SshIdentityStrategy {
|
||||
|
||||
@Override
|
||||
public boolean isConnectionAttemptCostly() {
|
||||
return false;
|
||||
return password.expectsQuery() && AppPrefs.get().dontCachePasswords().get();
|
||||
}
|
||||
|
||||
public void checkComplete() throws ValidationException {
|
||||
|
||||
@@ -8,13 +8,12 @@ import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.ShellTemp;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.process.ShellDialect;
|
||||
import io.xpipe.core.process.ShellInitCommand;
|
||||
import io.xpipe.core.process.ShellTerminalInitCommand;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ScriptStoreSetup {
|
||||
|
||||
@@ -72,7 +71,7 @@ public class ScriptStoreSetup {
|
||||
|
||||
var source = pc.getSourceStoreId();
|
||||
if (source.isPresent()) {
|
||||
var useCached = pc.getSourceStore().map(dataStore -> dataStore instanceof ShellStore s && s.isConnectionAttemptCostly()).orElse(false);
|
||||
var useCached = true || pc.getSourceStore().map(dataStore -> dataStore instanceof ShellStore s && s.isConnectionAttemptCostly()).orElse(false);
|
||||
if (useCached) {
|
||||
var cached = hasGeneratedScriptsCached(source.get(), initFlattened) && hasGeneratedScriptsCached(source.get(), bringFlattened);
|
||||
if (cached) {
|
||||
@@ -81,11 +80,22 @@ public class ScriptStoreSetup {
|
||||
}
|
||||
}
|
||||
|
||||
initFlattened.forEach(simpleScriptStore -> {
|
||||
pc.withInitSnippet(simpleScriptStore.getStore());
|
||||
initFlattened.forEach(s -> {
|
||||
pc.withInitSnippet(new ShellTerminalInitCommand.Static(s.getStore().))
|
||||
pc.withInitSnippet(new ShellTerminalInitCommand() {
|
||||
@Override
|
||||
public Optional<String> terminalContent(ShellControl shellControl) {
|
||||
return Optional.ofNullable(s.getStore().assembleScriptChain(shellControl));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPotentiallyRunInDialect(ShellDialect dialect) {
|
||||
return s.getStore().getMinimumDialect().isCompatibleTo(dialect);
|
||||
}
|
||||
});
|
||||
});
|
||||
if (!bringFlattened.isEmpty() || source.isPresent()) {
|
||||
pc.withInitSnippet(new ShellInitCommand() {
|
||||
pc.withInitSnippet(new ShellTerminalInitCommand.Terminal() {
|
||||
|
||||
String dir;
|
||||
|
||||
@@ -116,11 +126,6 @@ public class ScriptStoreSetup {
|
||||
public boolean canPotentiallyRunInDialect(ShellDialect dialect) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean runInTerminal() {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
return pc;
|
||||
|
||||
@@ -6,7 +6,6 @@ import io.xpipe.app.util.ScriptHelper;
|
||||
import io.xpipe.app.util.Validators;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.process.ShellDialect;
|
||||
import io.xpipe.core.process.ShellInitCommand;
|
||||
import io.xpipe.core.util.ValidationException;
|
||||
import io.xpipe.ext.base.SelfReferentialStore;
|
||||
|
||||
@@ -20,7 +19,6 @@ import lombok.extern.jackson.Jacksonized;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@SuperBuilder(toBuilder = true)
|
||||
@@ -29,7 +27,7 @@ import java.util.stream.Collectors;
|
||||
@JsonTypeName("script")
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class SimpleScriptStore extends ScriptStore implements ShellInitCommand.Terminal, SelfReferentialStore {
|
||||
public class SimpleScriptStore extends ScriptStore implements SelfReferentialStore {
|
||||
|
||||
ShellDialect minimumDialect;
|
||||
String commands;
|
||||
@@ -62,7 +60,7 @@ public class SimpleScriptStore extends ScriptStore implements ShellInitCommand.T
|
||||
shellControl.getShellDialect().getNewLine().getNewLineString()));
|
||||
var targetType = shellControl.getOriginalShellDialect();
|
||||
var script = ScriptHelper.createExecScript(targetType, shellControl, fixedCommands);
|
||||
return targetType.sourceScriptCommand(shellControl, script.toString());
|
||||
return targetType.sourceScriptCommand(script.toString());
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -115,14 +113,4 @@ public class SimpleScriptStore extends ScriptStore implements ShellInitCommand.T
|
||||
.toList()
|
||||
: List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> terminalContent(ShellControl shellControl) {
|
||||
return Optional.ofNullable(assembleScriptChain(shellControl));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPotentiallyRunInDialect(ShellDialect dialect) {
|
||||
return this.minimumDialect.isCompatibleTo(dialect);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user