mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-21 23:20:23 +00:00
Various fixes
This commit is contained in:
parent
2d67443f22
commit
4f3f2bbfd2
16 changed files with 41 additions and 84 deletions
|
@ -51,7 +51,7 @@ dependencies {
|
||||||
api files("$rootDir/gradle/gradle_scripts/markdowngenerator-1.3.1.1.jar")
|
api files("$rootDir/gradle/gradle_scripts/markdowngenerator-1.3.1.1.jar")
|
||||||
api files("$rootDir/gradle/gradle_scripts/vernacular-1.16.jar")
|
api files("$rootDir/gradle/gradle_scripts/vernacular-1.16.jar")
|
||||||
api 'info.picocli:picocli:4.7.6'
|
api 'info.picocli:picocli:4.7.6'
|
||||||
api ('org.kohsuke:github-api:1.321') {
|
api ('org.kohsuke:github-api:1.322') {
|
||||||
exclude group: 'org.apache.commons', module: 'commons-lang3'
|
exclude group: 'org.apache.commons', module: 'commons-lang3'
|
||||||
}
|
}
|
||||||
api 'org.apache.commons:commons-lang3:3.14.0'
|
api 'org.apache.commons:commons-lang3:3.14.0'
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class ListBoxViewComp<T> extends Comp<CompStructure<ScrollPane>> {
|
||||||
Map<T, Region> cache = new IdentityHashMap<>();
|
Map<T, Region> cache = new IdentityHashMap<>();
|
||||||
|
|
||||||
VBox vbox = new VBox();
|
VBox vbox = new VBox();
|
||||||
vbox.getStyleClass().add("content");
|
vbox.getStyleClass().add("list-box-content");
|
||||||
vbox.setFocusTraversable(false);
|
vbox.setFocusTraversable(false);
|
||||||
|
|
||||||
refresh(vbox, shown, all, cache, false);
|
refresh(vbox, shown, all, cache, false);
|
||||||
|
|
|
@ -34,7 +34,7 @@ public class ListSelectorComp<T> extends SimpleComp {
|
||||||
protected Region createSimple() {
|
protected Region createSimple() {
|
||||||
var vbox = new VBox();
|
var vbox = new VBox();
|
||||||
vbox.setSpacing(8);
|
vbox.setSpacing(8);
|
||||||
vbox.getStyleClass().add("content");
|
vbox.getStyleClass().add("list-content");
|
||||||
var cbs = new ArrayList<CheckBox>();
|
var cbs = new ArrayList<CheckBox>();
|
||||||
for (var v : values) {
|
for (var v : values) {
|
||||||
var cb = new CheckBox(null);
|
var cb = new CheckBox(null);
|
||||||
|
|
|
@ -151,7 +151,7 @@ public class StoreSectionComp extends Comp<CompStructure<VBox>> {
|
||||||
topEntryList,
|
topEntryList,
|
||||||
Comp.separator().hide(expanded.not()),
|
Comp.separator().hide(expanded.not()),
|
||||||
new HorizontalComp(List.of(content))
|
new HorizontalComp(List.of(content))
|
||||||
.styleClass("content")
|
.styleClass("children-content")
|
||||||
.apply(struc -> struc.get().setFillHeight(true))
|
.apply(struc -> struc.get().setFillHeight(true))
|
||||||
.hide(Bindings.or(
|
.hide(Bindings.or(
|
||||||
Bindings.not(section.getWrapper().getExpanded()),
|
Bindings.not(section.getWrapper().getExpanded()),
|
||||||
|
|
|
@ -46,6 +46,7 @@ public class AppExtensionManager {
|
||||||
INSTANCE.determineExtensionDirectories();
|
INSTANCE.determineExtensionDirectories();
|
||||||
INSTANCE.loadBaseExtension();
|
INSTANCE.loadBaseExtension();
|
||||||
INSTANCE.loadAllExtensions();
|
INSTANCE.loadAllExtensions();
|
||||||
|
INSTANCE.loadUaccExtension();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (load) {
|
if (load) {
|
||||||
|
@ -139,7 +140,7 @@ public class AppExtensionManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadAllExtensions() {
|
private void loadAllExtensions() {
|
||||||
for (var ext : List.of("jdbc", "proc", "uacc")) {
|
for (var ext : List.of("jdbc", "proc")) {
|
||||||
var extension = findAndParseExtension(ext, baseLayer)
|
var extension = findAndParseExtension(ext, baseLayer)
|
||||||
.orElseThrow(() -> ExtensionException.corrupt("Missing module " + ext));
|
.orElseThrow(() -> ExtensionException.corrupt("Missing module " + ext));
|
||||||
loadedExtensions.add(extension);
|
loadedExtensions.add(extension);
|
||||||
|
@ -154,6 +155,21 @@ public class AppExtensionManager {
|
||||||
.layer();
|
.layer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void loadUaccExtension() {
|
||||||
|
var extension = findAndParseExtension("uacc", extendedLayer)
|
||||||
|
.orElseThrow(() -> ExtensionException.corrupt("Missing module uacc"));
|
||||||
|
loadedExtensions.add(extension);
|
||||||
|
leafModuleLayers.add(extension.getModule().getLayer());
|
||||||
|
|
||||||
|
var scl = ClassLoader.getSystemClassLoader();
|
||||||
|
var cfs = leafModuleLayers.stream().map(ModuleLayer::configuration).toList();
|
||||||
|
var finder = ModuleFinder.ofSystem();
|
||||||
|
var cf = Configuration.resolve(finder, cfs, finder, List.of());
|
||||||
|
extendedLayer = ModuleLayer.defineModulesWithOneLoader(cf, leafModuleLayers, scl)
|
||||||
|
.layer();
|
||||||
|
}
|
||||||
|
|
||||||
private Optional<Extension> findAndParseExtension(String name, ModuleLayer parent) {
|
private Optional<Extension> findAndParseExtension(String name, ModuleLayer parent) {
|
||||||
var inModulePath = ModuleLayer.boot().findModule("io.xpipe.ext." + name);
|
var inModulePath = ModuleLayer.boot().findModule("io.xpipe.ext." + name);
|
||||||
if (inModulePath.isPresent()) {
|
if (inModulePath.isPresent()) {
|
||||||
|
|
|
@ -106,6 +106,7 @@ public class UserReportComp extends SimpleComp {
|
||||||
layout.setCenter(reportSection);
|
layout.setCenter(reportSection);
|
||||||
layout.setBottom(buttons);
|
layout.setBottom(buttons);
|
||||||
layout.getStyleClass().add("error-report");
|
layout.getStyleClass().add("error-report");
|
||||||
|
layout.getStyleClass().add("background");
|
||||||
layout.setPrefWidth(600);
|
layout.setPrefWidth(600);
|
||||||
layout.setPrefHeight(550);
|
layout.setPrefHeight(550);
|
||||||
return layout;
|
return layout;
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
package io.xpipe.app.util;
|
|
||||||
|
|
||||||
import io.xpipe.app.storage.DataStorage;
|
|
||||||
import io.xpipe.core.store.DataStore;
|
|
||||||
|
|
||||||
public abstract class LicenseConnectionLimit {
|
|
||||||
|
|
||||||
private final int limit;
|
|
||||||
private final LicensedFeature feature;
|
|
||||||
|
|
||||||
public LicenseConnectionLimit(int limit, LicensedFeature feature) {
|
|
||||||
this.limit = limit;
|
|
||||||
this.feature = feature;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract boolean matches(DataStore store);
|
|
||||||
|
|
||||||
public void checkLimit() {
|
|
||||||
if (feature.isSupported()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var found = DataStorage.get().getStoreEntries().stream()
|
|
||||||
.filter(entry -> entry.getValidity().isUsable() && matches(entry.getStore()))
|
|
||||||
.toList();
|
|
||||||
if (found.size() > limit) {
|
|
||||||
throw new LicenseRequiredException(feature, limit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -26,9 +26,5 @@ public interface LicensedFeature {
|
||||||
|
|
||||||
boolean isPreviewSupported();
|
boolean isPreviewSupported();
|
||||||
|
|
||||||
default void throwIfUnsupported() throws LicenseRequiredException {
|
void throwIfUnsupported() throws LicenseRequiredException;
|
||||||
if (!isSupported()) {
|
|
||||||
throw new LicenseRequiredException(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,8 @@ Prior to sending requests to the API, you first have to establish a new API sess
|
||||||
In the response you will receive a session token that you can use to authenticate during this session.
|
In the response you will receive a session token that you can use to authenticate during this session.
|
||||||
|
|
||||||
This is done so that the daemon knows what kind of clients are connected and can manage individual capabilities for clients.
|
This is done so that the daemon knows what kind of clients are connected and can manage individual capabilities for clients.
|
||||||
|
If your client is running on the same system as the daemon, you can choose the local authentication method to avoid having to deal with API keys.
|
||||||
|
If your client does not have file system access, e.g. if it is running remotely, then you have to use an API key.
|
||||||
|
|
||||||
Note that for development you can also turn off the required authentication in the XPipe settings menu, allowing you to send unauthenticated requests.
|
Note that for development you can also turn off the required authentication in the XPipe settings menu, allowing you to send unauthenticated requests.
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
-fx-spacing: 0.3em;
|
-fx-spacing: 0.3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-report .attachments .attachment-list .content {
|
.error-report .attachments .attachment-list .list-box-content {
|
||||||
-fx-padding: 0.5em 1em;
|
-fx-padding: 0.5em 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@
|
||||||
-fx-border-insets: 0px;
|
-fx-border-insets: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.store-entry-section-comp > .content {
|
.store-entry-section-comp > .children-content {
|
||||||
-fx-padding: 5px 0 5px 25px;
|
-fx-padding: 5px 0 5px 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@
|
||||||
-fx-background-radius: 0;
|
-fx-background-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.store-entry-section-comp .list-box-view-comp .content {
|
.store-entry-section-comp .list-box-view-comp .list-box-content {
|
||||||
-fx-spacing: 0.2em;
|
-fx-spacing: 0.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
.store-mini-list-comp > * > * > .children-content {
|
|
||||||
-fx-spacing: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.store-mini-list-comp:root {
|
.store-mini-list-comp:root {
|
||||||
-fx-border-color: transparent;
|
-fx-border-color: transparent;
|
||||||
-fx-background-color: transparent;
|
-fx-background-color: transparent;
|
||||||
|
@ -118,7 +114,7 @@
|
||||||
-fx-border-color: -color-border-default;
|
-fx-border-color: -color-border-default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.store-section-mini-comp .list-box-view-comp .children-content {
|
.store-section-mini-comp:root .list-box-view-comp .list-box-content {
|
||||||
-fx-spacing: 0.4em;
|
-fx-spacing: 0.4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,14 @@
|
||||||
-fx-background-color: derive(-color-bg-default, -9%);
|
-fx-background-color: derive(-color-bg-default, -9%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.root:dark.background {
|
||||||
|
-fx-background-color: derive(-color-bg-default, 1%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.root:light.background {
|
||||||
|
-fx-background-color: derive(-color-bg-default, -9%);
|
||||||
|
}
|
||||||
|
|
||||||
.root:seamless-frame.layout > .background {
|
.root:seamless-frame.layout > .background {
|
||||||
-fx-background-insets: 5 0 0 0;
|
-fx-background-insets: 5 0 0 0;
|
||||||
-fx-border-insets: 5 0 0 0;
|
-fx-border-insets: 5 0 0 0;
|
||||||
|
|
|
@ -2,6 +2,7 @@ package io.xpipe.ext.base.service;
|
||||||
|
|
||||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||||
import io.xpipe.app.util.HostHelper;
|
import io.xpipe.app.util.HostHelper;
|
||||||
|
import io.xpipe.app.util.LicenseProvider;
|
||||||
import io.xpipe.app.util.Validators;
|
import io.xpipe.app.util.Validators;
|
||||||
import io.xpipe.core.store.*;
|
import io.xpipe.core.store.*;
|
||||||
import io.xpipe.core.util.JacksonizedValue;
|
import io.xpipe.core.util.JacksonizedValue;
|
||||||
|
@ -32,7 +33,7 @@ public abstract class AbstractServiceStore extends JacksonizedValue
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkTunnelSession newSession() throws Exception {
|
public NetworkTunnelSession newSession() throws Exception {
|
||||||
ServiceLicenseCheck.check();
|
LicenseProvider.get().getFeature("services").throwIfUnsupported();
|
||||||
var l = localPort != null ? localPort : HostHelper.findRandomOpenPortOnAllLocalInterfaces();
|
var l = localPort != null ? localPort : HostHelper.findRandomOpenPortOnAllLocalInterfaces();
|
||||||
return getHost().getStore().sessionChain(l, remotePort);
|
return getHost().getStore().sessionChain(l, remotePort);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
package io.xpipe.ext.base.service;
|
|
||||||
|
|
||||||
import io.xpipe.app.util.LicenseConnectionLimit;
|
|
||||||
import io.xpipe.app.util.LicenseProvider;
|
|
||||||
import io.xpipe.app.util.LicensedFeature;
|
|
||||||
import io.xpipe.core.store.DataStore;
|
|
||||||
|
|
||||||
public class ServiceLicenseCheck {
|
|
||||||
|
|
||||||
public static LicensedFeature getFeature() {
|
|
||||||
return LicenseProvider.get().getFeature("services");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void check() {
|
|
||||||
if (getFeature().isSupported()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var limit = getConnectionLimit();
|
|
||||||
limit.checkLimit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LicenseConnectionLimit getConnectionLimit() {
|
|
||||||
// We check before starting a new service
|
|
||||||
return new LicenseConnectionLimit(0, getFeature()) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean matches(DataStore store) {
|
|
||||||
return store instanceof AbstractServiceStore abstractServiceStore
|
|
||||||
&& abstractServiceStore.requiresTunnel()
|
|
||||||
&& abstractServiceStore.isSessionRunning();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -39,6 +39,8 @@ paths:
|
||||||
In the response you will receive a session token that you can use to authenticate during this session.
|
In the response you will receive a session token that you can use to authenticate during this session.
|
||||||
|
|
||||||
This is done so that the daemon knows what kind of clients are connected and can manage individual capabilities for clients.
|
This is done so that the daemon knows what kind of clients are connected and can manage individual capabilities for clients.
|
||||||
|
If your client is running on the same system as the daemon, you can choose the local authentication method to avoid having to deal with API keys.
|
||||||
|
If your client does not have file system access, e.g. if it is running remotely, then you have to use an API key.
|
||||||
|
|
||||||
Note that for development you can also turn off the required authentication in the XPipe settings menu, allowing you to send unauthenticated requests.
|
Note that for development you can also turn off the required authentication in the XPipe settings menu, allowing you to send unauthenticated requests.
|
||||||
operationId: handshake
|
operationId: handshake
|
||||||
|
|
Loading…
Reference in a new issue