enterprise/rac: Improve client connection status & bugfixes (#12684) * enterprise/rac: improve status message when connecting/connection failed * set fixed DPI * automatically set resize method for RDP --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io> Co-authored-by: Jens L. <jens@goauthentik.io>
This commit is contained in:
committed by
GitHub
parent
9d81f0598c
commit
01959132e8
@ -159,9 +159,9 @@ class ConnectionToken(ExpiringModel):
|
|||||||
default_settings["port"] = str(port)
|
default_settings["port"] = str(port)
|
||||||
else:
|
else:
|
||||||
default_settings["hostname"] = self.endpoint.host
|
default_settings["hostname"] = self.endpoint.host
|
||||||
default_settings["client-name"] = "authentik"
|
if self.endpoint.protocol == Protocols.RDP:
|
||||||
# default_settings["enable-drive"] = "true"
|
default_settings["resize-method"] = "display-update"
|
||||||
# default_settings["drive-name"] = "authentik"
|
default_settings["client-name"] = f"authentik - {self.session.user}"
|
||||||
settings = {}
|
settings = {}
|
||||||
always_merger.merge(settings, default_settings)
|
always_merger.merge(settings, default_settings)
|
||||||
always_merger.merge(settings, self.endpoint.provider.settings)
|
always_merger.merge(settings, self.endpoint.provider.settings)
|
||||||
|
|||||||
@ -50,9 +50,10 @@ class TestModels(TransactionTestCase):
|
|||||||
{
|
{
|
||||||
"hostname": self.endpoint.host.split(":")[0],
|
"hostname": self.endpoint.host.split(":")[0],
|
||||||
"port": "1324",
|
"port": "1324",
|
||||||
"client-name": "authentik",
|
"client-name": f"authentik - {self.user}",
|
||||||
"drive-path": path,
|
"drive-path": path,
|
||||||
"create-drive-path": "true",
|
"create-drive-path": "true",
|
||||||
|
"resize-method": "display-update",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
# Set settings in provider
|
# Set settings in provider
|
||||||
@ -63,10 +64,11 @@ class TestModels(TransactionTestCase):
|
|||||||
{
|
{
|
||||||
"hostname": self.endpoint.host.split(":")[0],
|
"hostname": self.endpoint.host.split(":")[0],
|
||||||
"port": "1324",
|
"port": "1324",
|
||||||
"client-name": "authentik",
|
"client-name": f"authentik - {self.user}",
|
||||||
"drive-path": path,
|
"drive-path": path,
|
||||||
"create-drive-path": "true",
|
"create-drive-path": "true",
|
||||||
"level": "provider",
|
"level": "provider",
|
||||||
|
"resize-method": "display-update",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
# Set settings in endpoint
|
# Set settings in endpoint
|
||||||
@ -79,10 +81,11 @@ class TestModels(TransactionTestCase):
|
|||||||
{
|
{
|
||||||
"hostname": self.endpoint.host.split(":")[0],
|
"hostname": self.endpoint.host.split(":")[0],
|
||||||
"port": "1324",
|
"port": "1324",
|
||||||
"client-name": "authentik",
|
"client-name": f"authentik - {self.user}",
|
||||||
"drive-path": path,
|
"drive-path": path,
|
||||||
"create-drive-path": "true",
|
"create-drive-path": "true",
|
||||||
"level": "endpoint",
|
"level": "endpoint",
|
||||||
|
"resize-method": "display-update",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
# Set settings in token
|
# Set settings in token
|
||||||
@ -95,10 +98,11 @@ class TestModels(TransactionTestCase):
|
|||||||
{
|
{
|
||||||
"hostname": self.endpoint.host.split(":")[0],
|
"hostname": self.endpoint.host.split(":")[0],
|
||||||
"port": "1324",
|
"port": "1324",
|
||||||
"client-name": "authentik",
|
"client-name": f"authentik - {self.user}",
|
||||||
"drive-path": path,
|
"drive-path": path,
|
||||||
"create-drive-path": "true",
|
"create-drive-path": "true",
|
||||||
"level": "token",
|
"level": "token",
|
||||||
|
"resize-method": "display-update",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
# Set settings in property mapping (provider)
|
# Set settings in property mapping (provider)
|
||||||
@ -114,10 +118,11 @@ class TestModels(TransactionTestCase):
|
|||||||
{
|
{
|
||||||
"hostname": self.endpoint.host.split(":")[0],
|
"hostname": self.endpoint.host.split(":")[0],
|
||||||
"port": "1324",
|
"port": "1324",
|
||||||
"client-name": "authentik",
|
"client-name": f"authentik - {self.user}",
|
||||||
"drive-path": path,
|
"drive-path": path,
|
||||||
"create-drive-path": "true",
|
"create-drive-path": "true",
|
||||||
"level": "property_mapping_provider",
|
"level": "property_mapping_provider",
|
||||||
|
"resize-method": "display-update",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
# Set settings in property mapping (endpoint)
|
# Set settings in property mapping (endpoint)
|
||||||
@ -135,11 +140,12 @@ class TestModels(TransactionTestCase):
|
|||||||
{
|
{
|
||||||
"hostname": self.endpoint.host.split(":")[0],
|
"hostname": self.endpoint.host.split(":")[0],
|
||||||
"port": "1324",
|
"port": "1324",
|
||||||
"client-name": "authentik",
|
"client-name": f"authentik - {self.user}",
|
||||||
"drive-path": path,
|
"drive-path": path,
|
||||||
"create-drive-path": "true",
|
"create-drive-path": "true",
|
||||||
"level": "property_mapping_endpoint",
|
"level": "property_mapping_endpoint",
|
||||||
"foo": "true",
|
"foo": "true",
|
||||||
"bar": "6",
|
"bar": "6",
|
||||||
|
"resize-method": "display-update",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@ -18,6 +18,12 @@ export class LoadingOverlay extends AKElement implements ILoadingOverlay {
|
|||||||
@property({ type: Boolean, attribute: "topmost" })
|
@property({ type: Boolean, attribute: "topmost" })
|
||||||
topmost = false;
|
topmost = false;
|
||||||
|
|
||||||
|
@property({ type: Boolean })
|
||||||
|
loading = true;
|
||||||
|
|
||||||
|
@property({ type: String })
|
||||||
|
icon = "";
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return [
|
return [
|
||||||
PFBase,
|
PFBase,
|
||||||
@ -40,7 +46,7 @@ export class LoadingOverlay extends AKElement implements ILoadingOverlay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`<ak-empty-state loading header="">
|
return html`<ak-empty-state ?loading=${this.loading} header="" icon=${this.icon}>
|
||||||
<span slot="body"><slot></slot></span>
|
<span slot="body"><slot></slot></span>
|
||||||
</ak-empty-state>`;
|
</ak-empty-state>`;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import "@goauthentik/elements/LoadingOverlay";
|
|||||||
import Guacamole from "guacamole-common-js";
|
import Guacamole from "guacamole-common-js";
|
||||||
|
|
||||||
import { msg, str } from "@lit/localize";
|
import { msg, str } from "@lit/localize";
|
||||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
import { CSSResult, TemplateResult, css, html, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators.js";
|
import { customElement, property, state } from "lit/decorators.js";
|
||||||
|
|
||||||
import AKGlobal from "@goauthentik/common/styles/authentik.css";
|
import AKGlobal from "@goauthentik/common/styles/authentik.css";
|
||||||
@ -21,6 +21,23 @@ enum GuacClientState {
|
|||||||
DISCONNECTED = 5,
|
DISCONNECTED = 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function GuacStateToString(state: GuacClientState): string {
|
||||||
|
switch (state) {
|
||||||
|
case GuacClientState.IDLE:
|
||||||
|
return msg("Idle");
|
||||||
|
case GuacClientState.CONNECTING:
|
||||||
|
return msg("Connecting");
|
||||||
|
case GuacClientState.WAITING:
|
||||||
|
return msg("Waiting");
|
||||||
|
case GuacClientState.CONNECTED:
|
||||||
|
return msg("Connected");
|
||||||
|
case GuacClientState.DISCONNECTING:
|
||||||
|
return msg("Disconnecting");
|
||||||
|
case GuacClientState.DISCONNECTED:
|
||||||
|
return msg("Disconnected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const AUDIO_INPUT_MIMETYPE = "audio/L16;rate=44100,channels=2";
|
const AUDIO_INPUT_MIMETYPE = "audio/L16;rate=44100,channels=2";
|
||||||
const RECONNECT_ATTEMPTS_INITIAL = 5;
|
const RECONNECT_ATTEMPTS_INITIAL = 5;
|
||||||
const RECONNECT_ATTEMPTS = 5;
|
const RECONNECT_ATTEMPTS = 5;
|
||||||
@ -64,6 +81,9 @@ export class RacInterface extends Interface {
|
|||||||
@state()
|
@state()
|
||||||
clientState?: GuacClientState;
|
clientState?: GuacClientState;
|
||||||
|
|
||||||
|
@state()
|
||||||
|
clientStatus?: Guacamole.Status;
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
reconnectingMessage = "";
|
reconnectingMessage = "";
|
||||||
|
|
||||||
@ -138,6 +158,7 @@ export class RacInterface extends Interface {
|
|||||||
};
|
};
|
||||||
this.client = new Guacamole.Client(this.tunnel);
|
this.client = new Guacamole.Client(this.tunnel);
|
||||||
this.client.onerror = (err) => {
|
this.client.onerror = (err) => {
|
||||||
|
this.clientStatus = err;
|
||||||
console.debug("authentik/rac: error: ", err);
|
console.debug("authentik/rac: error: ", err);
|
||||||
this.reconnect();
|
this.reconnect();
|
||||||
};
|
};
|
||||||
@ -175,6 +196,10 @@ export class RacInterface extends Interface {
|
|||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.set("screen_width", Math.floor(RacInterface.domSize().width).toString());
|
params.set("screen_width", Math.floor(RacInterface.domSize().width).toString());
|
||||||
params.set("screen_height", Math.floor(RacInterface.domSize().height).toString());
|
params.set("screen_height", Math.floor(RacInterface.domSize().height).toString());
|
||||||
|
// https://github.com/goauthentik/authentik/pull/11757
|
||||||
|
// there are DPI issues when using SSH on HiDPi screens
|
||||||
|
// but if we're not setting DPI at all the resolution is not respected at all
|
||||||
|
params.set("screen_dpi", "96");
|
||||||
this.client.connect(params.toString());
|
this.client.connect(params.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,6 +246,7 @@ export class RacInterface extends Interface {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.hasConnected = true;
|
this.hasConnected = true;
|
||||||
|
this.clientStatus = undefined;
|
||||||
this.container = this.client.getDisplay().getElement();
|
this.container = this.client.getDisplay().getElement();
|
||||||
this.initMouse(this.container);
|
this.initMouse(this.container);
|
||||||
this.client?.sendSize(
|
this.client?.sendSize(
|
||||||
@ -310,19 +336,35 @@ export class RacInterface extends Interface {
|
|||||||
console.debug("authentik/rac: Sent clipboard");
|
console.debug("authentik/rac: Sent clipboard");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderOverlay() {
|
||||||
|
if (!this.clientState || this.clientState == GuacClientState.CONNECTED) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
let message = html`${GuacStateToString(this.clientState)}`;
|
||||||
|
if (this.clientState == GuacClientState.WAITING) {
|
||||||
|
message = html`${msg("Connecting...")}`;
|
||||||
|
}
|
||||||
|
if (this.hasConnected) {
|
||||||
|
message = html`${this.reconnectingMessage}`;
|
||||||
|
}
|
||||||
|
if (this.clientStatus?.message) {
|
||||||
|
message = html`${message}<br />${this.clientStatus.message}`;
|
||||||
|
}
|
||||||
|
const isLoading = [
|
||||||
|
GuacClientState.CONNECTING,
|
||||||
|
GuacClientState.DISCONNECTING,
|
||||||
|
GuacClientState.WAITING,
|
||||||
|
].includes(this.clientState);
|
||||||
|
return html`
|
||||||
|
<ak-loading-overlay ?loading=${isLoading} icon="fa fa-times">
|
||||||
|
<span> ${message} </span>
|
||||||
|
</ak-loading-overlay>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
render(): TemplateResult {
|
render(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
${this.clientState !== GuacClientState.CONNECTED
|
${this.renderOverlay()}
|
||||||
? html`
|
|
||||||
<ak-loading-overlay>
|
|
||||||
<span>
|
|
||||||
${this.hasConnected
|
|
||||||
? html`${this.reconnectingMessage}`
|
|
||||||
: html`${msg("Connecting...")}`}
|
|
||||||
</span>
|
|
||||||
</ak-loading-overlay>
|
|
||||||
`
|
|
||||||
: html``}
|
|
||||||
<div class="container">${this.container}</div>
|
<div class="container">${this.container}</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user