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