Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document role service #992

Merged
merged 3 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,34 @@
```
LAYMAN_CLIENT_VERSION=73a6d0b5d2138e62077d305d07b4992d020168c8
```
It was already required in v1.22.3.
- Stop using environment variable `LAYMAN_GS_ROLE_SERVICE`, it has no effect to Layman anymore. Layman now uses [role service](doc/security.md#role-service) identified by new environment variable [LAYMAN_ROLE_SERVICE_URI](doc/env-settings.md#LAYMAN_ROLE_SERVICE_URI). The service is called `layman_role_service` on GeoServer.
- Set new environment variable [LAYMAN_ROLE_SERVICE_URI](doc/env-settings.md#LAYMAN_ROLE_SERVICE_URI)
- Stop using environment variable `LAYMAN_GS_ROLE_SERVICE`, it has no effect to Layman anymore. Role service called `layman_role_service` is used now.
### Migrations and checks
#### Schema migrations
- [#165](https://github.com/LayerManager/layman/issues/165) Add column `role_name` to table `rights` in prime DB schema. Add constraint that exactly one of columns `role_name` and `id_user` is not null.
- [#164](https://github.com/LayerManager/layman/issues/165) Create internal GeoServer [JDBC Role Service](https://docs.geoserver.org/2.21.x/en/user/security/usergrouprole/roleservices.html#jdbc-role-service) DB schema `_role_service`.
- [#165](https://github.com/LayerManager/layman/issues/165) Create DB schema `_role_service` that can be used as [role service](doc/security.md#role-service).
#### Data migrations
### Changes
- [#165](https://github.com/LayerManager/layman/issues/165) POST Workspace [Layers](doc/rest.md#post-workspace-layers)/[Maps](doc/rest.md#post-workspace-maps) and PATCH Workspace [Layer](doc/rest.md#patch-workspace-layer)/[Map](doc/rest.md#patch-workspace-map) saves [role names](doc/models.md#role) mentioned in `access_rights.read` and `access_rights.write` parameters into DB.
- [#165](https://github.com/LayerManager/layman/issues/165) Many endpoints respect role access rights:
- [#165](https://github.com/LayerManager/layman/issues/165) Prior to this version, Layman enabled to use [usernames](doc/models.md#username) and pseudo-role `EVERYONE` in access rights. From now on, Layman accepts also [role names](doc/models.md#role).
- [#165](https://github.com/LayerManager/layman/issues/165) Roles (except of `EVERYONE`) are managed by [role service](doc/security.md#role-service).
- [#165](https://github.com/LayerManager/layman/issues/165) New REST endpoint [GET Roles](doc/rest.md#get-roles) with list of all roles registered in [role service](doc/security.md#role-service), that can be used in access rights.
- This new endpoint was added to Test Client into tab "Others".
- [#165](https://github.com/LayerManager/layman/issues/165) POST Workspace [Layers](doc/rest.md#post-workspace-layers)/[Maps](doc/rest.md#post-workspace-maps) and PATCH Workspace [Layer](doc/rest.md#patch-workspace-layer)/[Map](doc/rest.md#patch-workspace-map) saves [role names](doc/models.md#role) mentioned in `access_rights.read` and `access_rights.write` parameters into [prime DB schema](doc/data-storage.md#postgresql).
- [#165](https://github.com/LayerManager/layman/issues/165) Many requests respect roles in access rights:
- [GET](doc/rest.md#get-workspace-layer)/[PATCH](doc/rest.md#patch-workspace-layer)/[DELETE](doc/rest.md#delete-workspace-layer) Workspace Layer
- GET Workspace Layer [Thumbnail](doc/rest.md#get-workspace-layer-thumbnail)/[Style](doc/rest.md#get-workspace-layer-style)/[Metadata Comparison](doc/rest.md#get-workspace-layer-metadata-comparison)/[Chunk](doc/rest.md#get-workspace-layer-chunk)
- [GET](doc/rest.md#get-workspace-map)/[PATCH](doc/rest.md#patch-workspace-map)/[DELETE](doc/rest.md#delete-workspace-map) Workspace Map
- GET Workspace Map [File](doc/rest.md#get-workspace-map-file)/[Thumbnail](doc/rest.md#get-workspace-map-thumbnail)/[Metadata Comparison](doc/rest.md#get-workspace-map-metadata-comparison)
- GET Workspace [Layers](doc/rest.md#get-workspace-layers)/[Maps](doc/rest.md#get-workspace-maps)
- GET [Layers](doc/rest.md#get-layers)/[Maps](doc/rest.md#get-maps)/[Publications](doc/rest.md#get-publications)
- DELETE Workspace [Layers](doc/rest.md#delete-workspace-layers)/[Maps](doc/rest.md#delete-workspace-maps)
- POST Workspace [Layers](doc/rest.md#post-workspace-layers)/[Maps](doc/rest.md#post-workspace-maps) respects roles in [GRANT_CREATE_PUBLIC_WORKSPACE](doc/env-settings.md#grant_create_public_workspace) and [GRANT_PUBLISH_IN_PUBLIC_WORKSPACE](doc/env-settings.md#grant_publish_in_public_workspace)
- requests to [WMS](doc/endpoints.md#web-map-service) and [WFS](doc/endpoints.md#web-feature-service) endpoints
- [#165](https://github.com/LayerManager/layman/issues/165) POST Workspace [Layers](doc/rest.md#post-workspace-layers)/[Maps](doc/rest.md#post-workspace-maps) respects roles in [GRANT_CREATE_PUBLIC_WORKSPACE](doc/env-settings.md#grant_create_public_workspace) and [GRANT_PUBLISH_IN_PUBLIC_WORKSPACE](doc/env-settings.md#grant_publish_in_public_workspace)
- [#165](https://github.com/LayerManager/layman/issues/165) Many endpoints return previously associated [role names](doc/models.md#role) in `access_rights.read` and `access_rights.write` keys:
- [GET](doc/rest.md#get-workspace-layer)/[PATCH](doc/rest.md#patch-workspace-layer) Workspace Layer
- [GET](doc/rest.md#get-workspace-map)/[PATCH](doc/rest.md#patch-workspace-map) Workspace Map
- GET Workspace [Layers](doc/rest.md#get-workspace-layers)/[Maps](doc/rest.md#get-workspace-maps)
- GET [Layers](doc/rest.md#get-layers)/[Maps](doc/rest.md#get-maps)/[Publications](doc/rest.md#get-publications)
- [#165](https://github.com/LayerManager/layman/issues/165) New REST endpoint [GET Roles](doc/rest.md#get-roles) with list of all roles registered in [JDBC Role Service](https://docs.geoserver.org/2.21.x/en/user/security/usergrouprole/roleservices.html#jdbc-role-service), that can be used in access rights. This new endpoint was added to Test Client into tab "Others".
- All changes from [v1.22.1](#v1221), [v1.22.2](#v1222) and [v1.22.3](#v1223).
- [#960](https://github.com/LayerManager/layman/issues/960) Handle WMS requests with HTTP error more efficiently in timgen.
- [#962](https://github.com/LayerManager/layman/issues/962) Make values of `layman_metadata.publication_status` and `status` key(s) more consistent in responses of PATCH Workspace [Layer](doc/rest.md#patch-workspace-layer)/[Map](doc/rest.md#patch-workspace-map) and GET Workspace [Layer](doc/rest.md#get-workspace-layer)/[Map](doc/rest.md#get-workspace-map).
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,11 @@ When providing **external dependencies**, check their production-related documen

Within PostgreSQL, you need to provide one database for Layman and one database for Micka. For Layman, you also need to provide one user [LAYMAN_PG_USER](doc/env-settings.md#LAYMAN_PG_USER) who needs enough privileges to create new schemas in [LAYMAN_PG_DBNAME](doc/env-settings.md#LAYMAN_PG_DBNAME) database. The user also needs access to `public` schema where PostGIS must be installed.

If you are using other DB schema than [internal role service schema](doc/security.md#internal-role-service-schema) as [role service](doc/security.md#role-service), you need to provide all [admin records](doc/security.md#admin-role-service-records).

Within QGIS Server, you do not need to provide anything special.

Within GeoServer, you need to provide either admin password [GEOSERVER_ADMIN_PASSWORD](doc/env-settings.md#GEOSERVER_ADMIN_PASSWORD), or one Layman user [LAYMAN_GS_USER](doc/env-settings.md#LAYMAN_GS_USER) and one layman role [LAYMAN_GS_ROLE](doc/env-settings.md#LAYMAN_GS_ROLE). If admin password is provided, Layman will create the Layman user and the Layman role automatically. URL path of the GeoServer must be `/geoserver/`.
Within GeoServer, you need to provide either admin password [GEOSERVER_ADMIN_PASSWORD](doc/env-settings.md#GEOSERVER_ADMIN_PASSWORD), or one Layman user [LAYMAN_GS_USER](doc/env-settings.md#LAYMAN_GS_USER). If admin password is provided, Layman will create the Layman user automatically. URL path of the GeoServer must be `/geoserver/`.

Within Redis, you need to provide two databases, one for Layman, second for Layman Test Client. Connection strings are defined by [LAYMAN_REDIS_URL](doc/env-settings.md#LAYMAN_REDIS_URL) and [LTC_REDIS_URL](doc/env-settings.md#LTC_REDIS_URL).

Expand Down
7 changes: 4 additions & 3 deletions doc/data-storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,11 @@ Data is saved to LAYMAN_DATA_DIR directory, LAYMAN_QGIS_DATA_DIR directory, and
Filesystem is used as persistent data store, so data survives Layman restart.

### PostgreSQL
Layman uses directly **one database** specified by [LAYMAN_PG_DBNAME](env-settings.md#LAYMAN_PG_DBNAME) to store data. There are two kinds of schemas in such database:
Layman uses directly **one database** specified by [LAYMAN_PG_DBNAME](env-settings.md#LAYMAN_PG_DBNAME) to store data. There are three kinds of schemas in such database:
- [LAYMAN_PRIME_SCHEMA](env-settings.md#LAYMAN_PRIME_SCHEMA) that holds information about
- users, workspaces, and publications including access rights
- data version including migration ID
- [Internal Role Service Schema](security.md#internal-role-service-schema) with table and view structure that can be used as [role service](security.md#role-service)
- Schemas holding vector layer data.
- One **[workspace schema](https://www.postgresql.org/docs/13/ddl-schemas.html)** is created for every created [workspace](models.md#workspace). Name of workspace schema is always the same as workspace name.
- One **[table](https://www.postgresql.org/docs/13/sql-createtable.html)** is created in workspace schema for each layer published with input vector files. Name of the table is in form `layer_<UUID>` with `-` replaced with `_`, e.g. `layer_96b918c6_d88c_42d8_b999_f3992b826958`. The table contains data from vector data files.
Expand All @@ -115,7 +116,7 @@ Data changes made directly in vector data DB tables (both internal and external)
PostgreSQL is used as persistent data store, so data survives Layman restart.

### GeoServer
**[User](https://docs.geoserver.org/2.21.x/en/user/security/webadmin/ugr.html)** and **[role](https://docs.geoserver.org/2.21.x/en/user/security/webadmin/ugr.html)** are created for every [user](models.md#user) who reserved [username](models.md#username). User name on GeoServer is the same as username on Layman. Role name is composed a `USER_<upper-cased username>`.
**[User](https://docs.geoserver.org/2.21.x/en/user/security/webadmin/ugr.html)** is created for every [user](models.md#user) who reserved [username](models.md#username). Username on GeoServer is the same as username on Layman.

Two **[workspaces](https://docs.geoserver.org/2.21.x/en/user/data/webadmin/workspaces.html)** are created, each with one **[PostgreSQL datastore](https://docs.geoserver.org/2.21.x/en/user/data/app-schema/data-stores.html#postgis)**, for every [workspace](models.md#workspace) (both personal and public). First workspace is meant for [WFS](endpoints.md#web-feature-service) and has the same name as the workspace on Layman. Second workspace is meant for [WMS](endpoints.md#web-map-service) and is suffixed with `_wms`. Name of the datastore is `postgresql` for both workspaces. Every workspace-related information (including PostgreSQL datastore) is saved inside workspace.

Expand All @@ -127,6 +128,6 @@ For each vector layer with QML style, **[Feature Type](https://docs.geoserver.or

For each raster layer, **[Coverage Store](https://docs.geoserver.org/2.21.x/en/user/rest/api/coveragestores.html)**, **[Coverage](https://docs.geoserver.org/2.21.x/en/user/rest/api/coverages.html)**, and **[Style](https://docs.geoserver.org/2.21.x/en/user/styling/webadmin/index.html)** are created in WMS workspace. If layer is [timeseries](models.md#timeseries), Coverage Store is [ImageMosaic](https://docs.geoserver.org/2.21.x/en/user/data/raster/imagemosaic/index.html), otherwise it is [GeoTIFF](https://docs.geoserver.org/2.21.x/en/user/data/raster/geotiff.html). Names of Coverage and Style are the same as layername, name of Coverage Store is prefixed with `geotiff_` or `image_mosaic_` depending on its type. Coverage Store and Coverage points to appropriate normalized raster GeoTIFF file(s). Style contains visualization file.

Two **[access rules](https://docs.geoserver.org/2.21.x/en/user/security/layer.html)** are created for each layer in each GeoServer workspace (WFS and WMS), one for [read access right](security.md#publication-access-rights), one for [write access right](security.md#publication-access-rights). Every username from Layman's access right is represented by user's role name (i.e. `USER_<upper-cased username>`). Role `EVERYONE` is represented as `ROLE_ANONYMOUS` on GeoServer.
Two **[access rules](https://docs.geoserver.org/2.21.x/en/user/security/layer.html)** are created for each layer in each GeoServer workspace (WFS and WMS), one for [read access right](security.md#publication-access-rights), one for [write access right](security.md#publication-access-rights). Every username from Layman's access right is represented by user's role name (i.e. `USER_<upper-cased username>`). Role `EVERYONE` is represented as `ROLE_ANONYMOUS` and `ROLE_AUTHENTICATED` on GeoServer.

GeoServer is used as persistent data store, so data survives Layman restart.
2 changes: 1 addition & 1 deletion doc/env-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ List of [users](models.md#user) and [roles](models.md#role) giving them permissi
List of [users](models.md#user) and [roles](models.md#role) giving them permission to publish new [publication](models.md#publication) in already created [public workspace](models.md#public-workspace).

### LAYMAN_ROLE_SERVICE_URI
URL of Role Service with schema in format `postgresql://<username>:<password>@<host>:<port>/<dbname>?schema=<schema_name>`. If you want to use internal Role Service, set it to `postgresql://<LAYMAN_PG_USER>:<LAYMAN_PG_PASSWORD>@<LAYMAN_PG_HOST>:<LAYMAN_PG_PORT>/<LAYMAN_PG_DBNAME>?schema=_role_service` (replace variable names with their values). URL scheme must be `postgresql`. URL host must be mentioned explicitly, as well as DB schema in `schema` URL query parameter.
URL of [Role Service](security.md#role-service) with DB schema in format `postgresql://<username>:<password>@<host>:<port>/<dbname>?schema=<schema_name>`. URL scheme must be `postgresql`. URL host must be mentioned explicitly, as well as DB schema in `schema` URL query parameter. If you want to use [internal role service schema](security.md#internal-role-service-schema) provided by Layman, set value to `postgresql://<LAYMAN_PG_USER>:<LAYMAN_PG_PASSWORD>@<LAYMAN_PG_HOST>:<LAYMAN_PG_PORT>/<LAYMAN_PG_DBNAME>?schema=_role_service` (replace variable names with their values).

## Layman Test Client Settings

Expand Down
7 changes: 6 additions & 1 deletion doc/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,25 @@
- User is any person who communicates with Layman REST API through any client.
- User can be either authenticated, or unauthenticated (i.e. anonymous).
- User is sometimes identified by [username](#username)
- List of users with usernames can be obtained by [GET Users](rest.md#get-users).

## Username
- Username is a string identifying one [user](#user), so it is unique among all users.
- The string is lower-case (in contrast with [role name](#role)).
- Each user is represented by max. one username.
- Username is also used to identify user's [personal workspace](#personal-workspace) when communicating with [Layman REST API](rest.md).
- Username can be reserved by [PATCH Current User](rest.md#patch-current-user).
- Usernames can be used for assigning access rights.
- Anonymous user has no username.

## Role
- Role is any group of users. One user can be assigned to multiple roles.
- Each role is identified by name that is unique among all roles.
- The name is upper-case (in contrast with [username](#username)), maximum length is 64 characters.
- Roles can be used for assigning access rights.
- Role names can be used for assigning access rights.
- Existing roles can be obtained by [GET Roles](rest.md#get-roles).
- There is always listed special pseudo-role `EVERYONE` that represents every user including anonymous (unauthenticated).
- Roles (except of `EVERYONE`) are managed by [role service](security.md#role-service).

## Workspace
- Workspace is folder for [publications](#publication).
Expand Down
2 changes: 1 addition & 1 deletion doc/rest.md
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,7 @@ HTTP status code 200 if credentials were deleted.
`/rest/roles`

### GET Roles
Get list of roles.
Get list of [roles](models.md#role) available in [role service](security.md#role-service) in table `roles` except of [admin records](security.md#admin-role-service-records). Pseudo-role `EVERYONE` appear in the list too.

#### Request.
No action parameters.
Expand Down
Loading