Commit Graph
39 Commits
Author SHA1 Message Date
Yannick SchausandGitHub 6e83d3f8de "Cacheability" option for critical REST resources (#3335)
* Closes #3329.

This implements a new optional `cacheable` parameter for these REST endpoints:
- `/rest/items`
- `/rest/things`
- `/rest/rules`

When this parameter is set, a flat list of all elements excluding
non-cacheable fields (e.g. "state", "transformedState", "stateDescription",
"commandDescription" for items, "statusInfo", "firmwareStatus",
"properties" for things, "status" for rules) will be retrieved along with
a `Last-Modified` HTTP response header. When unknown, the Last-Modified
header will be set to the date of the request.

Also only when this parameter is set, and a `If-Modified-Since` header is
found in the request, that header will be compared to the last known
modified date for the corresponding cacheable list. The last modified date
will be reset when any change is made on the elements of the underlying
registry. If the `If-Modified-Since` date is equal or more recent than the
last modified date, then a 304 Not Modified response with no content will
be served instead of the usual 200 OK, informing the client that its
cache is still valid at the provided date.

All other request parameters will be ignored except for "metadata" in the
`/rest/items` endpoint. When a metadata selector is set, the resulting
item list will be considered like a completely different resource, i.e.
it will have its own last modified date. Regarding metadata, the approach
to invalidating last modified dates is very conservative: when any metadata
is changed, all cacheable lists of items will have their last modified date
reset even if the change was in a metadata namespace that wasn't requested.

This also implements the abovedescribed behavior for the
`/rest/ui/components/{namespace}` endpoint, but no `cacheable` parameter
is necessary. The last modified date is tracked by namespace.

Signed-off-by: Yannick Schaus <github@schaus.net>
2023-06-15 20:16:14 +02:00
Yannick SchausandGitHub 96e8d3648b Force English locale to parse marketplace UI components timestamp (#2663)
Related to https://community.openhab.org/t/error-installing-widgets-from-community-in-user-interfaces/128729/16

When the locale is not English the timestamp might fail to be deserialized into a Date:

```
2022-01-02 21:01:42.260 [ERROR] [munity.CommunityUIWidgetAddonHandler] - Unable to parse YAML: Cannot deserialize value of type `java.util.Date` from String "Oct 2, 2021, 9:24:59 PM": not a valid representation (error: Failed to parse Date value 'Oct 2, 2021, 9:24:59 PM': Unparseable date: "Oct 2, 2021, 9:24:59 PM")

 at [Source: (StringReader); line: 36, column: 12] (through reference chain: org.openhab.core.ui.components.RootUIComponent["timestamp"])

2022-01-02 21:01:42.261 [ERROR] [munity.CommunityUIWidgetAddonHandler] - Widget from marketplace is invalid: Unable to parse YAML
```

Signed-off-by: Yannick Schaus <github@schaus.net>
2022-01-04 12:25:15 +01:00
Yannick SchausandGitHub fa682c551e Improve logic to choose a script engine preferred MIME type (#2629)
As discussed in https://github.com/openhab/openhab-addons/issues/11818.
This should select `application/x-python` for Jython (instead of `application/python` currently)
and allow other script engines to advertise their MIME type:
- JRuby: `application/x-ruby`
- Groovy: `application/x-groovy`

Signed-off-by: Yannick Schaus <github@schaus.net>
2021-12-19 20:01:48 +01:00
Yannick SchausandGitHub 198e2eb405 Change the syntax for references in automation modules configuration (#2606)
Fixes #2510.

This changes the placeholder syntax used by the reference resolver notably
used in rule templates from `${reference}` to `{{reference}}`.

The former syntax is also used by other languages, notably JavaScript's
template strings, and therefore writing rule templates including JavaScript
code with template strings wouldn't behave as expected.

This also fixes a bug identified in #2510 where you couldn't have a
single closing brace before the start of the first placeholder - which
could more easily happen than having two closing braces.

Signed-off-by: Yannick Schaus <github@schaus.net>
2021-12-12 19:20:19 +01:00
Yannick SchausandGitHub f641d1d6ec [marketplace] Add add-on handler for block libraries (#2598)
Related to https://github.com/openhab/openhab-webui/pull/1225.

This add-on handler supports installing block libraries in the
UIComponentRegistry, `ui:blocks` namespace.

It is very similar to the CommunityUIWidgetAddonHandler, as the format
is the same, so are the features and implementation, the only
differences being:

- Supported content type: `application/vnd.openhab.uicomponent;type=blocks`
  (vs. `application/vnd.openhab.uicomponent;type=widget`)
- Discourse category nb.: 76 (vs. 75)
- Inferred Add-on type: "automation" (vs. "ui")

Signed-off-by: Yannick Schaus <github@schaus.net>
2021-12-10 23:35:25 +01:00
Yannick SchausandGitHub d4f62ed024 Add compilation errors & SAT GitHub annotations (#2543)
Signed-off-by: Yannick Schaus <github@schaus.net>
2021-11-13 22:13:28 +01:00
Yannick SchausandGitHub 9d9dc70d89 Add image_link field to community marketplace invididual add-ons (#2521)
When I ported over the code from the HABPanel gallery which was also
based on Discourse topics, the image_link field that was present on
topic lists wasn't replicated on single topic entries, but now it is:

See
https://meta.discourse.org/t/single-topic-api-endpoint-should-contain-image-url/131020
https://github.com/discourse/discourse/commit/3201613f138bf574577d77631f8214098e22b7e3

I have confirmed the field is present on community.openhab.org.
So this should help moving the "primary image" to the place where
the logo should be in the UI.

We can prevent the same image from being displayed twice with some
measures on the Discourse posts themselves
(like have it between <details></details>).

Signed-off-by: Yannick Schaus <github@schaus.net>
2021-10-15 17:47:54 +02:00
Yannick SchausandGitHub 0ef477e81f [Marketplace] Add option to include unpublished entries (#2488)
Add a config parameter to bypass the filtering of Dicourse topics
to include those which don't have the "published" tag.

Set the API key parameter as advanced (irrelevant to most users).

Signed-off-by: Yannick Schaus <github@schaus.net>
2021-09-16 08:02:30 +02:00
Yannick SchausandGitHub 2663a3fc7e Community Marketplace Add-on Service - initial contribution (#2405)
Signed-off-by: Yannick Schaus <github@schaus.net>
2021-09-14 09:04:04 +02:00
Yannick SchausandGitHub ff2f90684f Rework system:restauth config parameters (#2477)
Following the discussion in #2476, I believe the order and "advanced" status of config parameters in API Security (`system:restauth`) should be changed.
This promotes "Implicit User Role" to a non-advanced option (even if it can break some clients, it is clearly stated in the description), and demotes "Allow Basic Authentication" to an advanced option (API Tokens can be used to authenticate to the API as a better alternative to Basic).

Signed-off-by: Yannick Schaus <github@schaus.net>
2021-09-06 08:34:33 +02:00
Yannick SchausandGitHub 66149659ca [automation] Remove readOnly flag on script type parameter (#2373)
Not sure if there's a good rationale behind it being read-only (maybe because it's not supposed to change after having been set) but removing it will fix https://github.com/openhab/openhab-webui/issues/1061.

Signed-off-by: Yannick Schaus <github@schaus.net>
2021-05-20 20:39:32 +02:00
Yannick SchausandGitHub fcaf251bd0 Fix parsing integer & booleans parameters in UI component based sitemaps (#2072)
* Fix parsing integer & booleans parameters in UI component based sitemaps

Also catch remaining exceptions and log a warning/ignore the parameter
instead of making the whole sitemap building process fail.

Fix wrong feature ID for the video widget URL.

Fixes #2047.
Fixes #1987.
Fixes #1898.
Fixes #1875.
Fixes https://github.com/openhab/openhab-webui/issues/745.

Signed-off-by: Yannick Schaus <github@schaus.net>
2021-01-05 22:42:31 +01:00
Yannick SchausandGitHub 150ced7012 [auth] Don't allow creating API tokens with no name (#1969)
Fixes https://github.com/openhab/openhab-webui/issues/674.

Remove unnecessary checks and fix exception message.
Add Norwegian messages for auth pages.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-12-20 12:48:46 +01:00
Yannick SchausandGitHub cc7edadd96 Auth messages translations (RC2) (#1957)
This contains an update to the messages for the login,
change password, create API token pages from Crowdin
in ISO-8859 format.

Contains a completed German translation update, and
the following new completed languages:
- Czech
- Finnish
- Hungarian
- Portuguese (Brazil)
- Swedish
- Ukrainian

Dutch, French, Italian are unchanged from RC1.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-12-17 20:37:15 +01:00
Yannick SchausandGitHub 128e7bb3c8 Add firmwareStatus to things in summary mode (#1932)
The "summary" mode for `/rest/things` introduced in https://github.com/openhab/openhab-core/pull/1827
leads to these warnings in the console:
```
Field 'firmwareStatus' could not be eliminated: Can not set final org.openhab.core.thing.firmware.dto.FirmwareStatusDTO field org.openhab.core.io.rest.core.thing.EnrichedThingDTO.firmwareStatus to null value
```
The easiest solution to remove those warnings is to add it again to the list of fields included in the summaries.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-12-15 08:07:11 +01:00
Yannick SchausandGitHub eb176e14d2 Translated messages for auth pages (#1930)
This is the PR with the messages.properties files in
Dutch, German (partial) and Italian extracted from
#1929 and converted to the proper ISO-8859 encoding.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-12-13 21:09:13 +01:00
Yannick SchausandGitHub 67bdfa3ad6 Auth pages i18n (#1913)
This implements localized messages for the authorize, change
password and create API token pages using a resource bundle.

Messages in English & French are included.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-12-12 22:42:56 +01:00
Yannick SchausandGitHub 6ff65df7d2 [REST Auth] Remove user access to things (#1807)
I can't think of a good reason why listing things or querying their status should be allowed for users.
The things layer should only be of concern to admins IMHO.
As noted here: https://community.openhab.org/t/oh3-will-list-all-your-things-even-if-you-are-not-logged-in/108006/3
passwords and other sensible information in configuration could end up being exposed without auth required.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-11-26 08:31:10 +01:00
Yannick SchausandGitHub 065177b730 [rest] Add summary option to rules, things, UI components resources (#1827)
The /things, /rules, /ui/components endpoints retrieve all objects
in their entirety, which can become very big, i.e. channels, config
parameters, script rule modules or trees of UI components can
quickly add up to the size.

When the UI simply displays a list of those objects it retrieves all
this extra information but does nothing with it.

This introduces an optional ?summary=true query parameter for the
above resources to limit the output to pre-defined fields which are
deemed most relevant for displaying these lists, omitting the rest.

When the option is not set, the behavior remains unchanged so this
change is not API breaking. The API version has therefore not been
incremented. The client is responsible for adding the option to
retrieve summarized collections instead of the entire objects.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-11-21 18:40:48 +01:00
Yannick SchausandGitHub 4e045204ac [automation] Create Nashorn script engines with the proper class loader (#1799)
This should fix the issue reported here:
https://community.openhab.org/t/openhab-3-0-milestone-2-discussion/107564/8

where the Nashorn script engine would be created with the
current thread's class loader, causing JS code like this:
```
var Log = Java.type("org.openhab.core.model.script.actions.Log");
Log.logError("Experiments", "This is an OH error log");
Log.logWarn("Experiments", "This is an OH warn log");
Log.logInfo("Experiments", "This is an OH info log");
Log.logDebug("Experiments", "This is an OH debug log");
```
to run fine when the rule was triggered but fail to find the Log
class when run from the REST API's `/rest/rules/{ruleUID}/runnow`,
because in that case the generic createScriptEngine implementation
would return script engines using the JAX-RS class loader as the
"app" class loader.

Note:
We also have an opportunity to restrict which classes are exposed
to the script with a ClassFilter to a specific set:
https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/jdk/nashorn/api/scripting/NashornScriptEngineFactory.html#getScriptEngine-java.lang.String:A-java.lang.ClassLoader-jdk.nashorn.api.scripting.ClassFilter-
This could prove useful to mitigate code execution vulnerabilities,
as the script code is modifiable remotely.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-11-14 15:17:33 +01:00
Yannick SchausandGitHub 3df4403268 [REST Auth] Clear session cookie only when deleting own session (#1758)
Fix https://github.com/openhab/openhab-webui/issues/441

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-10-25 19:52:12 +01:00
Yannick SchausandGitHub 8b52cab5ef [REST Auth] API tokens & openhab:users console command (#1735)
This adds API tokens as a new credential type. Their format is:
`oh.<name>.<random chars>`

The "oh." prefix is used to tell them apart from a JWT access token,
because they're both used as a Bearer authorization scheme, but there
is no semantic value attached to any of the other parts.

They are stored hashed in the user's profile, and can be listed, added
or removed managed with the new `openhab:users` console command.

Currently the scopes are still not checked, but ultimately they could
be, for instance a scope of e.g. `user admin.items` would mean that the
API token can be used to perform user operations like retrieving info
or sending a command, _and_ managing the items, but nothing else -
even if the user has more permissions because of their role (which
will of course still be checked).

Tokens are normally passed in the Authorization header with the Bearer
scheme, or the X-OPENHAB-TOKEN header, like access tokens.
As a special exception, API tokens can also be used with the Basic
authorization scheme, **even if the allowBasicAuth** option is not
enabled in the "API Security" service, because there's no additional
security risk in allowing that. In that case, the token should be
passed as the username and the password MUST be empty.

In short, this means that all these curl commands will work:
- `curl -H 'Authorization: Bearer <token>' http://localhost:8080/rest/inbox`
- `curl -H 'X-OPENHAB-TOKEN: <token>' http://localhost:8080/rest/inbox`
- `curl -u '<token>[:]' http://localhost:8080/rest/inbox`
- `curl http://<token>@localhost:8080/rest/inbox`

2 REST API operations were adding to the AuthResource, to allow
authenticated users to list their tokens or remove (revoke) one.
Self-service for creating a token or changing the password is more
sensitive so these should be handled with a servlet and pages devoid
of any JavaScript instead of REST API calls, therefore for now they'll
have to be done with the console.

This also fixes regressions introduced with #1713 - the operations
annotated with @RolesAllowed({ Role.USER }) only were not authorized
for administrators anymore.

* Generate a unique salt for each token

Reusing the password salt is bad practice, and changing the
password changes the salt as well which makes all tokens
invalid.

Put the salt in the same field as the hash (concatenated
with a separator) to avoid modifying the JSON DB schema.

* Fix API token authentication, make scope available to security context

The X-OPENHAB-TOKEN header now has priority over the Authorization
header to credentials, if both are set.

* Add self-service pages to change password & create new API token

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-10-25 12:04:40 +01:00
Yannick SchausandGitHub d262b6f5bc Add missing roles checks (#1739)
(I included these fixes in #1735 but extracted them in a stanalone
PR because it's easier to review and a little more urgent.)

As a result of the refactoring in #1713, the operations annotated with
`@RolesAllowed` containing `Role.USER` are not anymore automatically
considered accessible to all users, regardless of their actual roles.

4 operations are therefore now denied to admins if they only have the
`Role.ADMIN` role, as the first admininistrator is created only with
that role the UI encounters unexpected access denied errors and breaks.
(See https://github.com/openhab/openhab-webui/issues/422).

Closes https://github.com/openhab/openhab-webui/issues/422.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-10-20 08:20:39 +02:00
Yannick SchausandGitHub e26c49b9bf Allow basic authentication to authorize API access (#1713)
* Allow basic authentication to authorize API access

Closes #1699.

Note, this opens a minor security issue that allows an attacker
to brute force passwords by making calls to the API - contrary to
the authorization page, the credentials parsing for the REST API
is stateless & doesn't have a lock mechanism to lock user accounts
after too many failed login attempts.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-10-18 20:59:51 +02:00
Yannick SchausandGitHub b7a764f358 Remove actions from available add-on types (#1690)
Since there are no more action add-ons in the distribution, I'd suggest to remove these from the `KarafAddonService` so they won't appear in the UI menus.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-10-04 22:38:42 +02:00
Yannick SchausandGitHub 426bd112b7 [REST/Auth] Always accept tokens in the alt header (#1631)
Currently the AuthFilter will try to find a token in the
X-OPENHAB-TOKEN HTTP header - only when it finds a cookie
named X-OPENHAB-AUTH-HEADER. It can cause problems because
browsers or proxies might block the cookie from being sent
for various reasons (for instance if there's a path set
for it).

There is no downside IMHO to always try to fallback to
checking the X-OPENHAB-TOKEN header for a token, if and
only if it's not already provided in the Authorization
header. It is the responsibility of the client to decide
how it wants to authorize the request among the available
options - by checking a cookie, or something else entirely.

Also removed the '?api_key=' option because Swagger UI
doesn't provide tokens that way anymore.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-09-09 20:48:10 +02:00
Yannick SchausandGitHub e1771c3b74 Add dark mode support in authorize page (#1600)
Closes https://github.com/openhab/openhab-webui/issues/309.
This only honors the scheme as reported by the `prefers-color-scheme` CSS media feature, i.e. local overrides for the main UI are not taken into account.
Tweak submit button styles to mimic the main UI's desktop theme.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-08-21 11:13:49 +02:00
Yannick SchausandGitHub 0d635ce970 REST: add runtime info to root resource response (#1570)
This adds basic information about the runtime in the response
to the root `/rest` API resource, mostly for display purposes
by UIs: the version, build string and the location of the
configuration and user data folders.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-07-25 18:18:07 +02:00
Yannick SchausandGitHub aac4ca2f79 Swagger: support injection of ReaderListener, add OAuth2 annotations (#1496)
Signed-off-by: Yannick Schaus <github@schaus.net>
2020-07-24 22:30:06 +02:00
Yannick SchausandGitHub bd976cf937 REST API: Re-enable auth (#1482)
* Add JAX-RS annotations to auth-related filter & dynamic feature.
* Remove unnecessary Activator.
* Remove BND file.
* Build error responses explicity instead of throwing exceptions in TokenResource to avoid logging.

Fixes #1477

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-05-20 21:54:45 +02:00
Yannick SchausandGitHub 15b3b07614 Add the Karaf jaas feature as runtime prerequisite (#1398)
* Add the Karaf jaas feature as runtime prerequisite
* Remove LoginModule reference from ManagedUserRealm

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-03-25 12:40:59 +01:00
Yannick SchausandGitHub d8fce0b8b3 Add auth feature to runtime base (#1396)
Signed-off-by: Yannick Schaus <github@schaus.net>
2020-03-24 08:49:52 +01:00
Yannick SchausandGitHub fe4e276b68 Implementation of a JWT-based OAuth2 flow for the admin API (#1389)
* Initial implementation of a JWT-based OAuth2 flow for the admin API

Implements #1388.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-03-23 22:36:11 +01:00
Yannick SchausandGitHub 3f48088f94 Fix NPE with uninitialized state trackers (#1378)
This fixes a NPE which occurs when a ItemStateChangedEvent
is broadcasted by the ItemStatesSseBroadcaster while some
SseStateEventOutputs haven't initialized their list of
tracked items.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-02-26 19:18:43 +01:00
Yannick SchausandGitHub 4b772cb6b3 Simple dynamic item state updates SSE endpoint & API. (#1364)
* Simple dynamic item state updates SSE endpoint & API.

Implements #1363.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-02-24 18:36:39 +01:00
Yannick SchausandGitHub 60e040c529 Metadata-based state & command description providers (#1362)
* Metadata-based state & command description providers

Implements #1185.

These providers will look into item metadata, which
can be managed by UIs with the API, to set or override
the item's state description (pattern, options, read
only...) or command description.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-02-15 18:08:42 +01:00
Yannick SchausandGitHub eea31e536d UI component registries initial implementation (#1356)
* UI component registries initial implementation

This is an initial implementation of #1355.
It was simple enough to make to be proposed as
a PR already without waiting for remarks on the RFC.

The SitemapProvider for the `system:sitemap`
namespace as described in #1355 is not part of
this PR.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-02-13 21:36:54 +01:00
Yannick SchausandKai Kreuzer d4b0ecb122 Add filters to some REST getAll endpoints (#1340)
These filters help reduce payloads for UIs which
retrieve ad-hoc information rather than maintaining
a global state.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-01-24 19:25:25 +01:00
Yannick SchausandKai Kreuzer cc702266fe Refactor dashboard tiles into core (#1329)
* Refactor dashboard tiles into core

Move the tile concept from the dashboard UI to the
org.openhab.core.ui bundle, and add a REST resource
(/rest/ui/tiles) to retrieve the list of tiles i.e.
registered UIs.

Signed-off-by: Yannick Schaus <github@schaus.net>
2020-01-17 15:28:05 +01:00