GUI Server

GUI Server provides user interface for monitoring and controlling Hat system functionality in real time. It provides multi-user environment with authentication and authorization control of available resources.

Running

By installing GUI Server from hat-gui package, executable hat-gui-server becomes available and can be used for starting this component.

usage: hat-gui-server [-h] [--conf PATH]

options:
  -h, --help   show this help message and exit
  --conf PATH  configuration defined by hat-gui://server.yaml (default
               $XDG_CONFIG_HOME/hat/gui.{yaml|yml|toml|json})

Overview

GUI functionality can be defined according to following components:

Functionality is dependent on active connection to Event Server. Adapters and Server are created when connection with Event Server is established and destroyed if this connection is closed. If connection with Event Server is closed, GUI will repeatedly try to establish new connection with currently active Event Server. If connection to Monitor Server could not be established or is closed, GUI terminates its process execution.

GUI Server can also run independently of Monitor Server. In this case, GUI Server connects to predefined Event Server address. If this connection could not be established or is broken, GUI Server terminates it’s process execution.

When connecting to Event Server, GUI will use client name gui/<name> where <name> represents configured component’s name.

Adapters

Adapters are mutually independent providers of server-side functionality and data exposed to GUI frontends. For providing this functionality and data, adapters rely primarily on their internal state and communication with Event Server. Adapter definitions are dynamically loaded during GUI server startup procedure.

GUI server can be configured to initialize arbitrary number of adapter instances with their custom configurations which will be validated with associated adapter’s optional JSON schema. During adapter instance initialization, each adapter instance is provided with instance of EventerClient, enabling queries and event registration. Each adapter is notified with events sent by Event Server based on its subscriptions.

Server is responsible for creating new instances of AdapterSessions associated with backend-frontend jugger communication session. AdapterSession represents adapter’s interface to single authenticated frontend client. It enables full juggler communication - request/response, server state and server notifications.

Implementation of single adapter is usually split between Adapter implementation and AdapterSession implementation where Adapter encapsulates shared data and AdapterSession encapsulates custom data and functionality specific for each client. Additionally, each AdapterSession is responsible for enforcing fine grained authorization rules in accordance to user authenticated with associated AdapterSession.

Adapters available as part of hat-gui package:

Views

Views are collection of frontend resources (HTML, JavaScript, CSS, …) responsible for graphical representation of adapters state and interaction with user. Each view is represented with content of file system directories. These files can be obtained by frontend using HTTP GET requests.

Server provides client’s views depending on authenticated user and its associated roles. Ordered list of all available views is defined as part of GUI Server’s configuration where each view has its associated roles. Server redirects client to first view that has at least one role matching one of authenticated user roles.

In addition to views for authenticated users, GUI Server’s configuration defines single view that is available to non authenticated users.

Views available as part of hat-gui package:

User sessions

User session is server side resource that represents lifetime of authenticated user session. It is uniquely identified with SESSION_ID that is provided as HTTP cookie as part of all HTTP requests sent from frontend to backend.

New user session is created after successful authentication procedure. Lifetime of user session is determined by server configuration parameters.

Once user session is closed, future HTTP requests identifying this session are considered unauthenticated. All active WebSocket connections, that are associated with session being closed, are closed during closing of session.

Backend - frontend communication

Server provides communication endpoints based on REST and Juggler communication.

REST Communication

Available endpoints are specified by OpenAPI Schema:

  • ‘/login/local’

    Login for localy defined users (users specified as part of Server’s configuration).

  • ‘/login/oidc/{name}’

    Redirects to OpenID Connect’s provider.

  • ‘/login/oidc/{name}/cb’

    OpenID Connect callback endpoint.

  • ‘/logout’

    User logout.

  • ‘/session’

    Information associated with currently active user session.

Juggler Communication

Juggler communication is available only to authenticated users.

Juggler connection is created by accessing ‘/ws’ WebSocket endpoint.

Supported communication includes:

  • request/response

    Juggler request/response communication is used for executing adapter specific actions. Request name is formatted as <adapter>/<action> where <adapter> is name of adapter instance and <action> is one of action names supported by referenced adapter instance type. Structure of request data and response results are defined by specific adapter action.

  • server state

    Juggler state is used for transfer of AdapterSession states from backend to frontend. State is single object where keys represent adapter instance names and values contain current associated AdapterSession state.

  • server notifications

    Juggler notifications enable backend to notify frontend with adapter specific notifications. Notification name is formatted as <adapter>/<notification> where <adapter> is name of adapter instance and <notification> is notification identification supported by referenced adapter instance type. Structure of notification data is defined by specific adapter notification.

GUI events

In addition to events registered by Adapters, Server registers events representing current state of authenticated Clients. These events have event type:

gui/<name>/clients

where <name> represents configured Server’s name.

Payload for clients events is defined by hat-gui://events.yaml#/$defs/events/clients.

JSON Schemas

Configuration

$schema: "https://json-schema.org/draft/2020-12/schema"
$id: "hat-gui://server.yaml"
title: GUI server
description: GUI server's configuration
type: object
required:
    - name
    - event_server
    - address
    - adapters
    - views
    - users
properties:
    type:
        const: gui
        description: configuration type identification
    version:
        type: string
        description: component version
    log:
        $ref: "hat-json://logging.yaml"
    name:
        type: string
        description: component name
    event_server:
        allOf:
          - type: object
            properties:
                require_operational:
                    type: boolean
          - oneOf:
              - type: object
                required:
                    - monitor_component
                properties:
                    monitor_component:
                        type: object
                        required:
                            - host
                            - port
                            - gui_group
                            - event_server_group
                        properties:
                            host:
                                type: string
                                default: "127.0.0.1"
                            port:
                                type: integer
                                default: 23010
                            gui_group:
                                type: string
                            event_server_group:
                                type: string
              - type: object
                required:
                    - eventer_server
                properties:
                    eventer_server:
                        type: object
                        required:
                            - host
                            - port
                        properties:
                            host:
                                type: string
                                default: "127.0.0.1"
                            port:
                                type: integer
                                default: 23012
    address:
        type: object
        required:
            - host
            - port
        properties:
            host:
                type: string
                default: "127.0.0.1"
            port:
                type: integer
                default: 23023
    adapters:
        type: array
        items:
            $ref: "hat-gui://server.yaml#/$defs/adapter"
    views:
        type: array
        items:
            $ref: "hat-gui://server.yaml#/$defs/view"
    users:
        type: object
        required:
            - max_sessions
        properties:
            max_sessions:
                type: integer
            snapshot_path:
                type: string
            session_duration:
                type: number
            session_cookie_max_age:
                type: integer
            local:
                type: array
                items:
                    $ref: "hat-gui://server.yaml#/$defs/local_user"
            oidc:
                type: array
                items:
                    type: object
                    required:
                        - name
                        - local_url
                        - authorize_url
                        - token_url
                        - client_id
                        - client_secret
                        - scope
                        - claims
                        - roles
                    properties:
                        name:
                            type: string
                        local_url:
                            type: string
                        authorize_url:
                            type: string
                        token_url:
                            type: string
                        client_id:
                            type: string
                        client_secret:
                            type: string
                        scope:
                            type: array
                            items:
                                type: string
                        claims:
                            type: object
                            required:
                                - name
                                - roles
                            properties:
                                name:
                                    type: string
                                roles:
                                    type: string
                        roles:
                            type: object
                            description: |
                                keys represents oidc user role and value
                                represents associated gui server user role
                            patternProperties:
                                '.+':
                                    type: string
    initial_view:
        type:
            - string
            - "null"
$defs:
    adapter:
        type: object
        required:
            - name
            - module
        properties:
            name:
                type: string
            module:
                type: string
    view:
        type: object
        required:
            - name
            - roles
            - paths
        properties:
            name:
                type: string
            roles:
                type: array
                items:
                    type: string
            paths:
                type: array
                items:
                    oneOf:
                      - type: object
                        required:
                            - path
                        properties:
                            path:
                                type: string
                      - type: object
                        required:
                            - builtin
                        properties:
                            builtin:
                                type: string
    local_user:
        type: object
        required:
            - name
            - password
            - roles
        properties:
            name:
                type: string
            password:
                $ref: "hat-gui://server.yaml#/$defs/password"
            roles:
                type: array
                items:
                    type: string
    password:
        type: object
        required:
            - hash
            - salt
        properties:
            hash:
                type: string
                description: |
                    SHA256(salt + SHA256(password)) hash encoded as hex string
            salt:
                type: string
                decription: |
                    unique salt used for generating hash encoded as hex string

Events

$schema: "https://json-schema.org/draft/2020-12/schema"
$id: "hat-gui://events.yaml"
definitions:
    events:
        clients:
            type: array
            items:
                type: object
                required:
                    - remote
                    - user
                properties:
                    remote:
                        type: string
                    user:
                        type: string

OpenAPI Schema

openapi: 3.2.0
info:
    title: hat-gui
    version: 0.0.1
paths:
    '/login/local':
        post:
            requestBody:
                content:
                    application/json:
                        schema:
                            type: object
                            required:
                                - name
                                - password
                            properties:
                                name:
                                    type: string
                                password:
                                    type: string
            responses:
                '200':
                    description: success
                default:
                    description: error
                    content:
                        text/plain:
                            schema:
                                type: string
    '/login/oidc/{name}':
        parameters:
          - name: name
            in: path
            required: true
            schema:
                type: string
        get:
            responses:
                '302':
                    description: redirect to oidc OP
    '/login/oidc/{name}/cb':
        parameters:
          - name: name
            in: path
            required: true
            schema:
                type: string
        get:
            parameters:
              - name: code
                in: query
                required: true
              - name: state
                in: query
                required: true
            responses:
                '302':
                    description: redirect to oidc OP
    '/logout':
        parameters:
          - name: SESSION_ID
            in: cookie
            required: true
            schema:
                type: string
        post:
            responses:
                '200':
                    description: success
        get:
            responses:
                '302':
                    description: success
    '/session':
        parameters:
          - name: SESSION_ID
            in: cookie
            required: true
            schema:
                type: string
        get:
            responses:
                '200':
                    description: success
                    content:
                        application/json:
                            schema:
                                type: object
                                required:
                                    - user
                                    - created
                                    - duration
                                properties:
                                    user:
                                        type: object
                                        required:
                                            - name
                                            - roles
                                            - views
                                        properties:
                                            name:
                                                type: string
                                            roles:
                                                type: array
                                                items:
                                                    type: string
                                            views:
                                                type: array
                                                items:
                                                    type: string
                                    created:
                                        type: number
                                    duration:
                                        type:
                                            - number
                                            - 'null'
    '/ws':
        parameters:
          - name: SESSION_ID
            in: cookie
            required: true
            schema:
                type: string
        get:
            responses:
                '101':
                    description: juggler websocket endpoint