Skip to content

Commit

Permalink
Proxify GeoServer's WFS to use Layman's authentication (#98)
Browse files Browse the repository at this point in the history
Closing #65
  • Loading branch information
index-git authored Sep 8, 2020
1 parent 15ebf8e commit d6a804b
Show file tree
Hide file tree
Showing 215 changed files with 1,453 additions and 3,149 deletions.
1 change: 1 addition & 0 deletions .env.demo
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ LAYMAN_GS_PATH=/geoserver/
LAYMAN_GS_USER=layman
LAYMAN_GS_PASSWORD=laymanpwd
LAYMAN_GS_ROLE=LAYMAN_ROLE
LAYMAN_GS_AUTHN_HTTP_HEADER_ATTRIBUTE=e58e4774e3dc7d6443ad59a8202c5ee0

# Celery settings
LAYMAN_CELERY_QUEUE=production
Expand Down
3 changes: 2 additions & 1 deletion .env.dev
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ LAYMAN_GS_PATH=/geoserver/
LAYMAN_GS_USER=layman
LAYMAN_GS_PASSWORD=laymanpwd
LAYMAN_GS_ROLE=LAYMAN_ROLE
LAYMAN_GS_PROXY_BASE_URL=http://localhost:8600/geoserver/
LAYMAN_GS_PROXY_BASE_URL=http://localhost:8000/geoserver/
LAYMAN_GS_AUTHN_HTTP_HEADER_ATTRIBUTE=e58e4774e3dc7d6443ad59a8202c5ee0

# Celery settings
LAYMAN_CELERY_QUEUE=dev
Expand Down
3 changes: 2 additions & 1 deletion .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ LAYMAN_GS_PATH=/geoserver/
LAYMAN_GS_USER=layman_test
LAYMAN_GS_PASSWORD=laymanpwd
LAYMAN_GS_ROLE=LAYMAN_TEST_ROLE
LAYMAN_GS_PROXY_BASE_URL=http://localhost:8600/geoserver/
LAYMAN_GS_PROXY_BASE_URL=http://localhost:8000/geoserver/
LAYMAN_GS_AUTHN_HTTP_HEADER_ATTRIBUTE=e58e4774e3dc7d6443ad59a8202c5ee0

# Celery settings
LAYMAN_CELERY_QUEUE=test
Expand Down
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ matrix:
# command to run tests
script:
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
- flake8 --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics ./src
- flake8 --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics ./src ./test

- name: "PyCodeStyle"
language: python
Expand All @@ -128,7 +128,7 @@ matrix:
#E722 do not use bare 'except'
#W503 Line break occurred before a binary operator
#E741 ambiguous variable name 'l'
- pycodestyle --count --max-line-length=127 --statistics --ignore=E402,E501,E711,E722,W503,E741 ./src
- pycodestyle --count --max-line-length=127 --statistics --ignore=E402,E501,E711,E722,W503,E741 ./src ./test

- name: "Pylint"
language: python
Expand All @@ -148,7 +148,7 @@ matrix:

# command to run tests
script:
- pylint -f colorized -r y --fail-under 5 ./src
- pylint -f colorized -r y --fail-under 5 ./src ./test

- name: "AutoPEP8"
language: python
Expand All @@ -168,5 +168,5 @@ matrix:

# command to run tests
script:
- autopep8 --recursive --diff --aggressive --aggressive --exit-code --ignore=E402,E501,E711,E722,W503,E741,E721 ./src
- autopep8 --recursive --diff --aggressive --aggressive --exit-code --ignore=E402,E501,E711,E722,W503,E741,E721 ./src ./test

8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## v1.7.0
2020-09-??
### Upgrade requirements
- [#65](https://github.com/jirik/layman/issues/65) Set environment variable [LAYMAN_GS_AUTHN_HTTP_HEADER_ATTRIBUTE](doc/env-settings.md#LAYMAN_GS_AUTHN_HTTP_HEADER_ATTRIBUTE).
### Changes
- [#65](https://github.com/jirik/layman/issues/65) [WFS endpoint](doc/rest.md#get-layer) accepts same [authentication](doc/security.md#authentication) credentials (e.g. [OAuth2 headers](doc/oauth2/index.md#request-layman-rest-api)) as Layman REST API endpoints. It's implemented using Layman's WFS proxy. This proxy authenticates the user and send user identification to GeoServer. In combination with changes in v1.6.0, Layman's [`read-everyone-write-owner` authorization](doc/security.md#authorization) (when active) is propagated to GeoServer and user can change only hers layers.
- [#65](https://github.com/jirik/layman/issues/65) Layman automatically setup [HTTP authentication attribute](https://docs.geoserver.org/stable/en/user/security/tutorials/httpheaderproxy/index.html) and chain filter at startup. Secret value of this attribute can be changed in [LAYMAN_GS_AUTHN_HTTP_HEADER_ATTRIBUTE](doc/env-settings.md#LAYMAN_GS_AUTHN_HTTP_HEADER_ATTRIBUTE) and is used by Layman's WFS proxy.

## v1.6.1
2020-08-19
- [#97](https://github.com/jirik/layman/issues/97) Before v1.6, [reserved `username`](doc/rest.md#patch-current-user) could be the same as LAYMAN_GS_USER. Starting at 1.6, this leads to conflict of two GeoServer users with the same name. This patch release comes with detection of this conflict (Layman error code 41).
Expand Down
26 changes: 16 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@

start-demo:
docker-compose -f docker-compose.deps.demo.yml -f docker-compose.demo.yml build layman layman_client geoserver timgen
docker-compose -f docker-compose.deps.demo.yml -f docker-compose.demo.yml run --rm --no-deps -u root layman bash -c "cd src && python3 -B setup_gs_auth.py"
docker-compose -f docker-compose.deps.demo.yml -f docker-compose.demo.yml up -d --force-recreate postgresql geoserver redis layman celery_worker flower timgen layman_client nginx

start-demo-full:
docker-compose -f docker-compose.deps.demo.yml -f docker-compose.demo.yml build layman layman_client geoserver timgen
docker-compose -f docker-compose.deps.demo.yml -f docker-compose.demo.yml run --rm --no-deps -u root layman bash -c "cd src && python3 -B setup_gs_auth.py"
docker-compose -f docker-compose.deps.demo.yml -f docker-compose.demo.yml up -d --force-recreate postgresql geoserver redis layman celery_worker flower timgen layman_client micka nginx

start-demo-only:
docker-compose -f docker-compose.deps.demo.yml -f docker-compose.demo.yml build layman layman_client geoserver timgen
docker-compose -f docker-compose.deps.demo.yml -f docker-compose.demo.yml run --rm --no-deps -u root layman bash -c "cd src && python3 -B setup_gs_auth.py"
docker-compose -f docker-compose.deps.demo.yml -f docker-compose.demo.yml up -d --force-recreate --no-deps layman celery_worker flower timgen layman_client

start-demo-full-with-optional-deps:
docker-compose -f docker-compose.deps.demo.yml -f docker-compose.demo.yml build layman layman_client geoserver timgen
docker-compose -f docker-compose.deps.demo.yml -f docker-compose.demo.yml run --rm --no-deps -u root layman bash -c "cd src && python3 -B setup_gs_auth.py"
docker-compose -f docker-compose.deps.demo.yml -f docker-compose.demo.yml up -d --force-recreate

stop-demo:
Expand All @@ -30,6 +34,7 @@ deps-stop:

start-dev:
mkdir -p layman_data layman_data_test tmp
docker-compose -f docker-compose.deps.yml -f docker-compose.dev.yml run --rm --no-deps -u root layman_dev bash -c "cd src && python3 -B setup_gs_auth.py"
docker-compose -f docker-compose.deps.yml -f docker-compose.dev.yml up --force-recreate -d

stop-dev:
Expand All @@ -38,6 +43,7 @@ stop-dev:
start-dev-only:
mkdir -p layman_data layman_data_test tmp
docker-compose -f docker-compose.deps.yml -f docker-compose.dev.yml rm -fsv layman_dev celery_worker_dev flower timgen layman_client
docker-compose -f docker-compose.deps.yml -f docker-compose.dev.yml run --rm --no-deps -u root layman_dev bash -c "cd src && python3 -B setup_gs_auth.py"
docker-compose -f docker-compose.deps.yml -f docker-compose.dev.yml up -d layman_dev celery_worker_dev flower timgen layman_client

stop-dev-only:
Expand Down Expand Up @@ -138,25 +144,19 @@ celery-worker-test-bash:

test:
docker-compose -f docker-compose.deps.yml -f docker-compose.dev.yml build layman_dev
docker-compose -f docker-compose.deps.yml -f docker-compose.test.yml run --rm --name layman_test_run_1 layman_test

test-dev:
docker-compose -f docker-compose.deps.yml -f docker-compose.test.yml rm -f layman_test
docker-compose -f docker-compose.deps.yml -f docker-compose.test.yml run --rm --no-deps -u root layman_test bash -c "cd src && python3 -B setup_gs_auth.py"
docker-compose -f docker-compose.deps.yml -f docker-compose.test.yml up --force-recreate --no-deps -d celery_worker_test
docker-compose -f docker-compose.deps.yml -f docker-compose.test.yml run --rm --name layman_test_run_1 layman_test

test-bash:
docker-compose -f docker-compose.deps.yml -f docker-compose.test.yml run --rm layman_test bash

test-wait-for-deps:
docker-compose -f docker-compose.deps.yml rm -fsv
docker-compose -f docker-compose.deps.yml up --force-recreate -d
docker-compose -f docker-compose.deps.yml -f docker-compose.test.yml run --rm layman_test bash -c "python3 src/wait_for_deps.py"

lint:
docker-compose -f docker-compose.deps.yml -f docker-compose.test.yml run --rm --no-deps layman_test bash -c "flake8 --count --select=E9,F63,F7,F82 --show-source --statistics ./src && pycodestyle --count --max-line-length=127 --statistics --ignore=E402,E501,E711,E722,W503,E741 ./src"
docker-compose -f docker-compose.deps.yml -f docker-compose.test.yml run --rm --no-deps layman_test bash -c "flake8 --count --select=E9,F63,F7,F82 --show-source --statistics ./src && pycodestyle --count --max-line-length=127 --statistics --ignore=E402,E501,E711,E722,W503,E741 ./src ./test"

lint-fix:
docker-compose -f docker-compose.deps.yml -f docker-compose.test.yml run --rm --no-deps layman_test autopep8 --recursive --in-place --aggressive --aggressive --exit-code --ignore=E402,E501,E711,E722,W503,E741,E721 ./src
docker-compose -f docker-compose.deps.yml -f docker-compose.test.yml run --rm --no-deps layman_test autopep8 --recursive --in-place --aggressive --aggressive --exit-code --ignore=E402,E501,E711,E722,W503,E741,E721 ./src ./test

postgresql-psql:
docker-compose -f docker-compose.deps.yml run -e PGPASSWORD=docker --entrypoint "psql -U docker -p 5432 -h postgresql gis" --rm postgresql
Expand Down Expand Up @@ -189,6 +189,12 @@ geoserver-reset-empty-datadir:
geoserver-bash:
docker-compose -f docker-compose.deps.yml run --rm --no-deps geoserver bash

geoserver-exec:
docker-compose -f docker-compose.deps.yml exec geoserver bash

geoserver-ensure-authn:
docker-compose -f docker-compose.deps.yml -f docker-compose.dev.yml run --rm --no-deps -u root layman_dev bash -c "cd src && python3 -B setup_gs_auth.py"

liferay-introspect:
curl 'http://localhost:8082/o/oauth2/introspect' --data 'client_id=id-353ab09c-f117-f2d5-d3a3-85cfb89e6746&client_secret=secret-d31a82c8-3e73-1058-e38a-f9191f7c2014&token=...'

Expand Down
79 changes: 0 additions & 79 deletions deps/geoserver/sample/geoserver_data/README.rst

This file was deleted.

27 changes: 0 additions & 27 deletions deps/geoserver/sample/geoserver_data/csw.xml

This file was deleted.

10 changes: 10 additions & 0 deletions deps/geoserver/sample/geoserver_data/csw/MD_Metadata.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@fileIdentifier.CharacterString=if_then_else(isNull(prefixedName), name, prefixedName)
identificationInfo.AbstractMD_Identification.citation.CI_Citation.title.CharacterString=if_then_else(isNull(title), name, name)
identificationInfo.AbstractMD_Identification.descriptiveKeywords.MD_Keywords.keyword.CharacterString=keywords
identificationInfo.AbstractMD_Identification.abstract.CharacterString=abstract
$dateStamp.Date= if_then_else ( isNull("metadata.date") , 'Unknown', "metadata.date")
hierarchyLevel.MD_ScopeCode.@codeListValue='http://purl.org/dc/dcmitype/Dataset'
$contact.CI_ResponsibleParty.individualName.CharacterString='GeoServer'
distributionInfo.MD_Distribution.transferOptions.MD_DigitalTransferOptions.onLine.CI_OnlineResource%.linkage.URL=list('${url.wfs}','${url.wms}')
distributionInfo.MD_Distribution.transferOptions.MD_DigitalTransferOptions.onLine.CI_OnlineResource%.protocol.CharacterString=list('OGC:WFS','OGC:WMS')
distributionInfo.MD_Distribution.transferOptions.MD_DigitalTransferOptions.onLine.CI_OnlineResource%.name.CharacterString=name
18 changes: 18 additions & 0 deletions deps/geoserver/sample/geoserver_data/csw/Record.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@identifier.value=if_then_else(isNull(prefixedName), name, prefixedName)
title.value=if_then_else(isNull(title), name, title)
creator.value='GeoServer Catalog'
subject.value=keywords
abstract.value=abstract
description.value=description
date.value="metadata.date"
type.value='http://purl.org/dc/dcmitype/Dataset'
references.scheme='OGC:WMS'
references.value=strConcat('${url.wms}?service=WMS&request=GetMap&layers=', prefixedName)
#publisher.value=
#format.value=
#language.value=
#coverage.value=
#source.value=
#relation.value=
#rights.value=
#contributor.value=
19 changes: 0 additions & 19 deletions deps/geoserver/sample/geoserver_data/demo/WCS_describeCoverage.xml

This file was deleted.

This file was deleted.

This file was deleted.

18 changes: 0 additions & 18 deletions deps/geoserver/sample/geoserver_data/demo/WCS_getCapabilities.xml

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit d6a804b

Please sign in to comment.