* 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>
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>
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>
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>
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>
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>
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>
* 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>
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>
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>
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>
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>
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>
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>
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>
(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>
* 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>
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>
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>
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>
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>
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>
* 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>
* 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>
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>
* 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>