Skip to content

Latest commit

 

History

1,714 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tableaux Build Status Coverage Status Codacy Badge

Tableaux (pronounced /ta.blo/) is a restful service for storing data in tables. These tables can have links between them.

Getting Started

Preparing the environment

To get a working setup, you need a jdd. The easiest way to work with different java versions is to use jEnv. It also works out of the box with gradle. If jEnv doesn't pick up the locally configured JDK automatically you can use the following command to set it up manually:

jenv enable-plugin gradle

To check if gradle is working, you can use the following command, which will print all the infos and versions:

gradlew -v

> ------------------------------------------------------------
> Gradle 9.6.1
> ------------------------------------------------------------
> 
> Build time:    2026-06-26 14:25:50 UTC
> Revision:      309d128bd9fe8c0b71311878fc660b9cbaa07c51
> 
> Kotlin:        2.3.21
> Groovy:        4.0.32
> Ant:           Apache Ant(TM) version 1.10.17 compiled on April 6 2026
> Launcher JVM:  17.0.20 (Homebrew 17.0.20+0)
> OS:            Mac OS X 26.5.2 aarch64

Setup

At first you need to setup your database and create a new conf.json based on ./conf-example.json. After that you can need to call POST /system/reset once to initialize system tables. If you wish you can fill in the demo data with POST /system/resetDemo.

Update DB schema (optionally)

If you upgrade from an older schema version you need to call POST /system/update before that. Schema will be upgraded automatically.

Auth

There are three different auth modes:

    1. no auth (legacy)
    1. manual auth with bearer token validation (JWT)
    1. automatic keycloak auth discovery (JWT) - preferred

Auth modes 2. and 3. of Tableaux are secured by a JWT based authentication. The JWT (signed with a private key) is verified by the public key of the auth service. In manual auth mode 2. the public key is configured in the conf file (see ./conf-example-manual-auth.jsonc), in automatic auth mode 3. the public key is discovered via the auth service also configured in the conf file (see ./conf-example.jsonc)

The auth mode 1. is a legacy mode for testing or for running the service behind a different auth service. In this mode the incoming request is not verified. The user (e.g. for history entries) must be set via cookie userName. Legacy mode is activated, if auth key in config is missing.

Behavior change since the Vert.x 4 migration

vertx-auth-oauth2 4.x validates locally-decoded access tokens more strictly than 3.x did: it now requires the token's aud claim to contain the backend's own client id (resource in the config). Vert.x 3.9.1 never checked aud at all.

If a token's aud doesn't include the backend's resource value (e.g. because the frontend client's Keycloak audience mapper only targets other clients), local validation silently fails (logged at TRACE level only) and the provider falls back to Keycloak token introspection for that request. Introspection is an authenticated call (RFC 7662) and therefore requires a client secret — without one, Keycloak rejects it with client_not_found and every request ends up 401 Unauthorized.

Consequences to be aware of:

  • In auto discovery mode (3.) the auth config now supports an optional "secret" field, used as the client secret for introspection calls. Without it, any token whose aud doesn't contain resource can no longer be authenticated at all.
  • Falling back to introspection on every request also means an extra HTTP round-trip to Keycloak per request instead of a fully offline signature check — a potential latency/load regression compared to Vert.x 3.
  • The proper long-term fix is on the Keycloak side: add an audience mapper (client scope, "Add to access token" enabled) to the frontend client(s) so their tokens include the backend's resource client id in aud. This restores fully offline validation; introspection then becomes a rare fallback again (e.g. during key rotation) instead of the default path.

Migration checklist (config changes)

When migrating an existing deployment past this change:

  1. In Keycloak, make sure the client configured as resource is a Confidential client (Client authentication enabled) and note its client secret.
  2. Add "secret": "<client-secret>" to the auth block of the deployment's config file (works for both manual and auto discovery mode).
  3. Check whether the frontend client(s) that call this backend have an audience mapper that includes resource in aud (decode a live access token and check the aud claim). If not, add one (see above) to avoid introspection running on every single request.
  4. Redeploy and verify in the Keycloak server logs that INTROSPECT_TOKEN_ERROR / client_not_found events for this client no longer occur.

Build & Test

Tableaux uses gradle to build a so called fat jar which contains all runtime dependencies. You can find it in build/libs/tableaux-fat.jar. The gradle task build needs a running PostgreSQL and the conf-test.json must be configured correct. Requests in auth tests must contain an accessToken. For simplicity this accessToken is generated within a test helper with a hardcoded key pair. For the accessToken to match the pub key, the auth configuration for testing must always be the same as configured in conf-test-example.json.

./gradlew clean build

Build without running tests:

./gradlew clean assemble

To run and debug tests from VS Code (green gutter icons / Test Explorer), install the scalameta.metals extension. After a fresh clone or after deleting .bloop/.metals, Metals needs to compile the test sources once before it reports tests to the Test Explorer and shows the gutter run icons — either by opening any test file, or via the Command Palette action Metals: Compile. Note that this only works through Metals/Bloop, not via a ./gradlew task, since Metals gets test info from the Bloop build server, not from Gradle's own compile output.

Tests (with custom config)

Tests use their own separate config, default configuration file is conf-test.json. Specific config can be passed via arguments.

Run tests:

./gradlew test -Pconf='custom.json'

To run a single test use the following command:

# full package and test name or wildcard with *, e.g.:
./gradlew test --rerun-tasks --tests="*deleteTable_validRole*" --info"

Run as fat jar

To execute the fat jar call it like this from project root:

java -jar ./build/libs/grud-backend-0.1.0-fat.jar -conf ../../conf.json
# with custom logging properties
java -jar -Djava.util.logging.config.file=./local_logging.properties ./build/libs/grud-backend-0.1.0-fat.jar -conf ./conf.json

Run in development

./gradlew run

or with automatic redeploy on code changes

./gradlew runRedeploy

Run with different conf file

./gradlew run -Pconf='other.json'

Authentication and permission handling

TODO add documentation for authentication and permission handling. Currently the docs are filed in confluence and hackmd.io.

Feature Flags

Feature flags are used to enable or disable certain features. They have to be configured in the configuration file. Feature flags are:

  • isRowPermissionCheckEnabled: Enable or disable row permission checks (default: false)
  • isPublicFileServerEnabled: Enable or disable the public file server. If enabled, files are accessible without authentication (default: false)

Highlevel Features

  • Content Creation System
  • Content Translation System
  • Digital Asset Management
  • Editing Publishing Workflow
  • Workspaces & Custom Projections

Thumbnails

Thumbnails configuration

Thumbnails for uploaded files can be generated/updated on server start. Configuration for thumbnails and cache retention can be configured in the configuration file:

"thumbnails": {
    // Resize filter used in thumbnail generation (value between 1 and 15) (default: 3 -> FILTER_TRIANGLE)
    "resizeFilter": 3,
    // Generate thumbnails at server start (default: false)
    "enableCacheWarmup": true,
    // Target widths for automatic thumbnail generation (default: [])
    "cacheWarmupWidths": [200, 400],
    // Chunks of thumbnails generated in parallel (default: 100)
    "cacheWarmupChunkSize": 100,
    // Maximum age of thumbnail in seconds before it is deleted (default: 2592000 -> 30 days)
    "cacheMaxAge": 2592000,
    // Polling interval in milliseconds for max age check (default: 21600000 -> 6 hours)
    "cacheClearPollingInterval": 21600000
}

Thumbnails filter overview

Int Constant Name Description Typical Use Cases & Performance
1 FILTER_POINT Nearest-neighbor interpolation – extremely fast but blocky and low quality. Best for real-time previews, thumbnails, or pixel art where sharp edges matter.
2 FILTER_BOX Box filter – averages nearby pixels; simple and efficient but can blur. Good for quick downscaling with integer factors.
3 FILTER_TRIANGLE (default) Linear (bilinear) interpolation – smooths edges, moderate quality and speed. Default for many simple scaling tasks; good balance for most UIs.
4 FILTER_HERMITE Hermite interpolation – smooth, continuous filter; slightly sharper than linear. Sometimes used for resizing smooth graphics or textures.
5 FILTER_HANNING Hanning window filter – smooth windowed filter; suppresses ringing. Used in scientific or high-fidelity image processing; slower than simple filters.
6 FILTER_HAMMING Hamming window filter – similar to Hanning with slightly different weighting. Also used in high-fidelity image resampling or signal applications.
7 FILTER_BLACKMAN Blackman window filter – smooth filter with good frequency response and low aliasing. Ideal when reducing high-detail images; slower but very clean output.
8 FILTER_GAUSSIAN Gaussian blur filter – softens transitions, reduces aliasing. Used when a smooth, natural look is preferred (e.g. photographic images).
9 FILTER_QUADRATIC Quadratic interpolation – smoother than bilinear, not as sharp as cubic. Useful for moderate-quality resampling where performance matters.
10 FILTER_CUBIC Cubic interpolation – classic “bicubic” resampling with good sharpness. Commonly used in photo editors; a good quality default.
11 FILTER_CATROM Catmull-Rom spline – sharp cubic filter preserving edges well. Good for natural images where edge detail matters.
12 FILTER_MITCHELL Mitchell–Netravali cubic filter – balanced between sharpness and smoothness. Often used as a high-quality general-purpose resampler.
13 FILTER_LANCZOS Lanczos (windowed sinc) – excellent quality, minimal aliasing. Best for downscaling photographs or detailed textures; slowest but sharpest.
14 FILTER_BLACKMAN_BESSEL Blackman–Bessel – very high-order smooth filter, minimal ringing. Scientific or print applications where color fidelity is critical.
15 FILTER_BLACKMAN_SINC Blackman–Sinc – Blackman window with Sinc kernel, extremely high quality. Top-tier downscaling, archival or professional image processing; very slow.

License

Copyright 2016-present Campudus GmbH.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

About

A restful service for storing data in tables.

Topics

Resources

Stars

8 stars

Watchers

5 watching

Forks

Releases

Packages

Used by

Contributors

Languages