Skip to content

Commit 6e2065b

Browse files
Task/69145 improve plugin docs (#511)
* Refine plugin system documentation for clarity and consistency * Enhance authentication section in plugin documentation for clarity * Refine plugin documentation for clarity and completeness, including YAML configuration and token handling details. * Added code snippets from Frontend side --------- Co-authored-by: Emanuel <[email protected]>
1 parent b4bb3de commit 6e2065b

File tree

1 file changed

+120
-11
lines changed

1 file changed

+120
-11
lines changed
Lines changed: 120 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
# Plugin System
22

3-
The plugin system enables services to expose an embedded UI inside Deployment Details (rendered as an iframe), and optionally add a shortcut in the environment’s left sidebar. Managed services populate these fields automatically via the Managed Framework; Non‑managed services can be configured in the yaml.
3+
The plugin system enables services to expose an embedded UI inside Deployment Details (rendered as an iframe), and optionally add a shortcut in the environment’s left sidebar.
4+
5+
Managed services may populate these plugin properties automatically via the Managed Framework, and you can always override them explicitly in YAML.
6+
7+
Non-managed services can also define these properties in YAML, making any deployment behave like a plugin without being a managed service.
48

59
## What it does
610

7-
- Embed a UI in Deployment Details when enabled
11+
* Embed a UI in Deployment Details when enabled
812

913
![Embedded View](images/dynamic-configuration-embedded-view.png){width=80%}
1014

11-
- Optionally show a sidebar shortcut to the embedded view
15+
* Optionally show a sidebar shortcut to the embedded view
1216

1317
![Sidebar example](images/plugin-sidebar.png){height=50%}
1418

15-
## YAML
19+
* Provide basic authentication integration with Quix Cloud so publicly exposed services don’t require a separate login
20+
21+
## YAML configuration
1622

1723
In your deployment YAML, you can enable the embedded UI and, optionally, a sidebar item:
1824

@@ -28,14 +34,117 @@ plugin:
2834
2935
Notes
3036
31-
- plugin.embeddedView: boolean. true → FE renders embedded UI.
32-
- plugin.sidebarItem: optional object configuring the Environment’s left sidebar item.
37+
* plugin.embeddedView: boolean. true → FE renders embedded UI.
38+
* plugin.sidebarItem: optional object configuring the Environment’s left sidebar item.
39+
40+
## Embedded view URL
41+
42+
When the plugin feature is enabled, the deployment exposes a public URL dedicated to the embedded UI. The Portal uses this URL to load the embedded view inside the iframe when `embeddedView` is enabled. This URL is not set in YAML; it’s exposed by the API.
43+
44+
Population rules:
45+
46+
* Managed service → Derived from Managed Services conventions.
47+
* Non-managed service → Requires `publicAccess` to be enabled; resolves from the deployment’s public URL.
48+
49+
## Authentication and authorization
50+
51+
The embedded view inherits authentication and authorization from the Quix platform: no separate login is required, and the same user/environment permissions apply.
52+
When an embedded view loads, the Plugin system injects the Quix user token into the iframe. The UI uses this token to call the backend securely.
3353

34-
## Public Url
54+
### How the token is injected in the embedded view
3555

36-
- Managed service → derived from Managed Services internal conventions.
37-
- Non‑managed service → uses the deployment’s publicUrl.
56+
On initial load of the embedded view (and on reload), the Portal provides the user token to the iframe so the UI can authenticate calls to the backend.
57+
58+
#### Frontend token exchange (postMessage)
59+
60+
The token is passed via `window.postMessage` between the parent (Portal) and the embedded iframe.
61+
62+
**Message types**
63+
64+
* `REQUEST_AUTH_TOKEN` — sent by the iframe to ask the parent for a token
65+
* `AUTH_TOKEN` — sent by the parent with `{ token: string }`
66+
67+
**In the embedded view (iframe)**
68+
69+
```ts
70+
// Ask the parent window (Portal) for a token
71+
window.parent.postMessage({ type: 'REQUEST_AUTH_TOKEN' }, '*');
72+
73+
// Listen for the token response from the parent
74+
function messageHandler(event: MessageEvent) {
75+
const { data } = event;
76+
if (data?.type === 'AUTH_TOKEN' && data.token) {
77+
// Your app-specific setter
78+
setToken(data.token);
79+
// Optionally remove the listener if you only need the token once
80+
// window.removeEventListener('message', messageHandler);
81+
}
82+
}
83+
84+
window.addEventListener('message', messageHandler);
85+
```
3886

39-
## Authentication
87+
**In the Portal (parent window)**
4088

41-
The embedded view inherits authentication and authorization from the main platform. No separate login is required, and the same user/environment permissions apply to the emmbedded view.
89+
```ts
90+
// Listen for requests from the target iframe
91+
function messageHandler(event: MessageEvent) {
92+
const { origin, data } = event;
93+
94+
// Ensure the origin matches the iframe URL you expect
95+
if (origin !== targetUrl) return;
96+
97+
if (data?.type === 'REQUEST_AUTH_TOKEN') {
98+
// Reply with the token to the requesting iframe
99+
const iframeWindow = deploymentIframe?.contentWindow;
100+
iframeWindow?.postMessage({ type: 'AUTH_TOKEN', token }, targetUrl);
101+
}
102+
}
103+
104+
window.addEventListener('message', messageHandler);
105+
```
106+
107+
**Security notes**
108+
109+
* Always validate `event.origin` in the parent before responding.
110+
* Prefer using a specific `targetUrl` over `'*'` when posting back to the iframe.
111+
* Remove listeners when no longer needed to avoid leaks.
112+
113+
### How to handle the token in the backend
114+
115+
Install the Quix Portal helper package from the public feed:
116+
117+
```bash
118+
pip install -i https://pkgs.dev.azure.com/quix-analytics/53f7fe95-59fe-4307-b479-2473b96de6d1/_packaging/public/pypi/simple/ quixportal
119+
```
120+
121+
Then, in the backend service, validate the token and enforce authorization for each request. For example:
122+
123+
```python
124+
import os
125+
from quixportal.auth import Auth
126+
127+
# Instantiate authentication client. By default it will read
128+
# the portal API url from the environment variable Quix__Portal__Api
129+
auth = Auth()
130+
131+
# Obtain the authorization token, traditionally passed as a header
132+
# Authorization: Bearer <token>
133+
token = ...
134+
135+
# Example to obtain "Read" access to the "Workspace" resource
136+
resource_type = "Workspace"
137+
workspace_id = os.environ["Quix__Workspace__Id"]
138+
permissions = "Read"
139+
140+
# Authorize the token bearer to access the resource
141+
if auth.validate_permissions(
142+
token=token,
143+
resourceType=resource_type,
144+
resourceID=workspace_id,
145+
permissions=permissions,
146+
):
147+
print("Bearer is authorized to access the resource")
148+
else:
149+
print("Bearer is not authorized to access the resource")
150+
```

0 commit comments

Comments
 (0)