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)
 | 
			
		||||
        else:
 | 
			
		||||
            default_settings["hostname"] = self.endpoint.host
 | 
			
		||||
        default_settings["client-name"] = "authentik"
 | 
			
		||||
        # default_settings["enable-drive"] = "true"
 | 
			
		||||
        # default_settings["drive-name"] = "authentik"
 | 
			
		||||
        if self.endpoint.protocol == Protocols.RDP:
 | 
			
		||||
            default_settings["resize-method"] = "display-update"
 | 
			
		||||
        default_settings["client-name"] = f"authentik - {self.session.user}"
 | 
			
		||||
        settings = {}
 | 
			
		||||
        always_merger.merge(settings, default_settings)
 | 
			
		||||
        always_merger.merge(settings, self.endpoint.provider.settings)
 | 
			
		||||
 | 
			
		||||
@ -50,9 +50,10 @@ class TestModels(TransactionTestCase):
 | 
			
		||||
            {
 | 
			
		||||
                "hostname": self.endpoint.host.split(":")[0],
 | 
			
		||||
                "port": "1324",
 | 
			
		||||
                "client-name": "authentik",
 | 
			
		||||
                "client-name": f"authentik - {self.user}",
 | 
			
		||||
                "drive-path": path,
 | 
			
		||||
                "create-drive-path": "true",
 | 
			
		||||
                "resize-method": "display-update",
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
        # Set settings in provider
 | 
			
		||||
@ -63,10 +64,11 @@ class TestModels(TransactionTestCase):
 | 
			
		||||
            {
 | 
			
		||||
                "hostname": self.endpoint.host.split(":")[0],
 | 
			
		||||
                "port": "1324",
 | 
			
		||||
                "client-name": "authentik",
 | 
			
		||||
                "client-name": f"authentik - {self.user}",
 | 
			
		||||
                "drive-path": path,
 | 
			
		||||
                "create-drive-path": "true",
 | 
			
		||||
                "level": "provider",
 | 
			
		||||
                "resize-method": "display-update",
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
        # Set settings in endpoint
 | 
			
		||||
@ -79,10 +81,11 @@ class TestModels(TransactionTestCase):
 | 
			
		||||
            {
 | 
			
		||||
                "hostname": self.endpoint.host.split(":")[0],
 | 
			
		||||
                "port": "1324",
 | 
			
		||||
                "client-name": "authentik",
 | 
			
		||||
                "client-name": f"authentik - {self.user}",
 | 
			
		||||
                "drive-path": path,
 | 
			
		||||
                "create-drive-path": "true",
 | 
			
		||||
                "level": "endpoint",
 | 
			
		||||
                "resize-method": "display-update",
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
        # Set settings in token
 | 
			
		||||
@ -95,10 +98,11 @@ class TestModels(TransactionTestCase):
 | 
			
		||||
            {
 | 
			
		||||
                "hostname": self.endpoint.host.split(":")[0],
 | 
			
		||||
                "port": "1324",
 | 
			
		||||
                "client-name": "authentik",
 | 
			
		||||
                "client-name": f"authentik - {self.user}",
 | 
			
		||||
                "drive-path": path,
 | 
			
		||||
                "create-drive-path": "true",
 | 
			
		||||
                "level": "token",
 | 
			
		||||
                "resize-method": "display-update",
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
        # Set settings in property mapping (provider)
 | 
			
		||||
@ -114,10 +118,11 @@ class TestModels(TransactionTestCase):
 | 
			
		||||
            {
 | 
			
		||||
                "hostname": self.endpoint.host.split(":")[0],
 | 
			
		||||
                "port": "1324",
 | 
			
		||||
                "client-name": "authentik",
 | 
			
		||||
                "client-name": f"authentik - {self.user}",
 | 
			
		||||
                "drive-path": path,
 | 
			
		||||
                "create-drive-path": "true",
 | 
			
		||||
                "level": "property_mapping_provider",
 | 
			
		||||
                "resize-method": "display-update",
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
        # Set settings in property mapping (endpoint)
 | 
			
		||||
@ -135,11 +140,12 @@ class TestModels(TransactionTestCase):
 | 
			
		||||
            {
 | 
			
		||||
                "hostname": self.endpoint.host.split(":")[0],
 | 
			
		||||
                "port": "1324",
 | 
			
		||||
                "client-name": "authentik",
 | 
			
		||||
                "client-name": f"authentik - {self.user}",
 | 
			
		||||
                "drive-path": path,
 | 
			
		||||
                "create-drive-path": "true",
 | 
			
		||||
                "level": "property_mapping_endpoint",
 | 
			
		||||
                "foo": "true",
 | 
			
		||||
                "bar": "6",
 | 
			
		||||
                "resize-method": "display-update",
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,12 @@ export class LoadingOverlay extends AKElement implements ILoadingOverlay {
 | 
			
		||||
    @property({ type: Boolean, attribute: "topmost" })
 | 
			
		||||
    topmost = false;
 | 
			
		||||
 | 
			
		||||
    @property({ type: Boolean })
 | 
			
		||||
    loading = true;
 | 
			
		||||
 | 
			
		||||
    @property({ type: String })
 | 
			
		||||
    icon = "";
 | 
			
		||||
 | 
			
		||||
    static get styles() {
 | 
			
		||||
        return [
 | 
			
		||||
            PFBase,
 | 
			
		||||
@ -40,7 +46,7 @@ export class LoadingOverlay extends AKElement implements ILoadingOverlay {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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>
 | 
			
		||||
        </ak-empty-state>`;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ import "@goauthentik/elements/LoadingOverlay";
 | 
			
		||||
import Guacamole from "guacamole-common-js";
 | 
			
		||||
 | 
			
		||||
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 AKGlobal from "@goauthentik/common/styles/authentik.css";
 | 
			
		||||
@ -21,6 +21,23 @@ enum GuacClientState {
 | 
			
		||||
    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 RECONNECT_ATTEMPTS_INITIAL = 5;
 | 
			
		||||
const RECONNECT_ATTEMPTS = 5;
 | 
			
		||||
@ -64,6 +81,9 @@ export class RacInterface extends Interface {
 | 
			
		||||
    @state()
 | 
			
		||||
    clientState?: GuacClientState;
 | 
			
		||||
 | 
			
		||||
    @state()
 | 
			
		||||
    clientStatus?: Guacamole.Status;
 | 
			
		||||
 | 
			
		||||
    @state()
 | 
			
		||||
    reconnectingMessage = "";
 | 
			
		||||
 | 
			
		||||
@ -138,6 +158,7 @@ export class RacInterface extends Interface {
 | 
			
		||||
        };
 | 
			
		||||
        this.client = new Guacamole.Client(this.tunnel);
 | 
			
		||||
        this.client.onerror = (err) => {
 | 
			
		||||
            this.clientStatus = err;
 | 
			
		||||
            console.debug("authentik/rac: error: ", err);
 | 
			
		||||
            this.reconnect();
 | 
			
		||||
        };
 | 
			
		||||
@ -175,6 +196,10 @@ export class RacInterface extends Interface {
 | 
			
		||||
        const params = new URLSearchParams();
 | 
			
		||||
        params.set("screen_width", Math.floor(RacInterface.domSize().width).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());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -221,6 +246,7 @@ export class RacInterface extends Interface {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        this.hasConnected = true;
 | 
			
		||||
        this.clientStatus = undefined;
 | 
			
		||||
        this.container = this.client.getDisplay().getElement();
 | 
			
		||||
        this.initMouse(this.container);
 | 
			
		||||
        this.client?.sendSize(
 | 
			
		||||
@ -310,19 +336,35 @@ export class RacInterface extends Interface {
 | 
			
		||||
        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 {
 | 
			
		||||
        return html`
 | 
			
		||||
            ${this.clientState !== GuacClientState.CONNECTED
 | 
			
		||||
                ? html`
 | 
			
		||||
                      <ak-loading-overlay>
 | 
			
		||||
                          <span>
 | 
			
		||||
                              ${this.hasConnected
 | 
			
		||||
                                  ? html`${this.reconnectingMessage}`
 | 
			
		||||
                                  : html`${msg("Connecting...")}`}
 | 
			
		||||
                          </span>
 | 
			
		||||
                      </ak-loading-overlay>
 | 
			
		||||
                  `
 | 
			
		||||
                : html``}
 | 
			
		||||
            ${this.renderOverlay()}
 | 
			
		||||
            <div class="container">${this.container}</div>
 | 
			
		||||
        `;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user