diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bb49af82..ea1233cbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 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). + - If you encounter error 41, you can resolve the conflict by following steps: + - In GeoServer GUI, create new GeoServer user with another name to become new LAYMAN_GS_USER and give him LAYMAN_GS_ROLE and ADMIN roles + - In GeoServer GUI, remove the old LAYMAN_GS_USER user + - Change environment settings LAYMAN_GS_USER and LAYMAN_GS_PASSWORD for the new GeoServer user + - Restart Layman + ## v1.6.0 2020-08-19 ### Upgrade requirements diff --git a/src/layman/__init__.py b/src/layman/__init__.py index b99abda88..29be7f6e9 100644 --- a/src/layman/__init__.py +++ b/src/layman/__init__.py @@ -70,10 +70,11 @@ settings.LAYMAN_REDIS.set(LAYMAN_DEPS_ADJUSTED_KEY, 'done') app.logger.info(f'Ensuring users') - from .util import get_usernames, ensure_whole_user + from .util import get_usernames, ensure_whole_user, check_username with app.app_context(): for username in get_usernames(): app.logger.info(f'Ensuring user {username}') + check_username(username) ensure_whole_user(username) else: while(settings.LAYMAN_REDIS.get(LAYMAN_DEPS_ADJUSTED_KEY) != 'done'): diff --git a/src/layman/error_list.py b/src/layman/error_list.py index 01b812496..82f1f3d1f 100644 --- a/src/layman/error_list.py +++ b/src/layman/error_list.py @@ -41,4 +41,5 @@ 38: (400, 'Micka HTTP or connection error.'), 39: (404, 'Metadata record does not exists.'), 40: (404, 'Username does not exist.'), + 41: (409, 'Username is in conflict with LAYMAN_GS_USER. To resolve this conflict, you can create new GeoServer user with another name to become new LAYMAN_GS_USER, give him LAYMAN_GS_ROLE and ADMIN roles, remove the old LAYMAN_GS_USER user at GeoServer, change environment settings LAYMAN_GS_USER and LAYMAN_GS_PASSWORD, and restart Layman'), } diff --git a/src/layman/layer/geoserver/__init__.py b/src/layman/layer/geoserver/__init__.py index b6a083eff..ced41509e 100644 --- a/src/layman/layer/geoserver/__init__.py +++ b/src/layman/layer/geoserver/__init__.py @@ -40,10 +40,13 @@ def get_all_rules(auth): def check_username(username, auth=settings.LAYMAN_GS_AUTH): - rolename = common.username_to_rolename(username) + if username == settings.LAYMAN_GS_USER: + raise LaymanError(41, {'username': username}) + if username in common.RESERVED_WORKSPACE_NAMES: raise LaymanError(35, {'reserved_by': __name__, 'workspace': username}) + rolename = common.username_to_rolename(username) if rolename in common.RESERVED_ROLE_NAMES: raise LaymanError(35, {'reserved_by': __name__, 'role': rolename}) diff --git a/src/layman/layer/rest_test.py b/src/layman/layer/rest_test.py index 48323b579..a0f0b55c7 100644 --- a/src/layman/layer/rest_test.py +++ b/src/layman/layer/rest_test.py @@ -141,6 +141,36 @@ def test_wrong_value_of_user(client): assert resp_json['detail']['parameter'] == 'user' +@pytest.mark.usefixtures('app_context') +def test_layman_gs_user_conflict(client): + """Tests that Layman detects that reserved username is in conflict with LAYMAN_GS_USER. + + See https://github.com/jirik/layman/pull/97 + """ + + username = settings.LAYMAN_GS_USER + layername = 'layer1' + rest_path = url_for('rest_layers.post', username=username) + file_paths = [ + 'tmp/naturalearth/110m/cultural/ne_110m_populated_places.geojson', + ] + for fp in file_paths: + assert os.path.isfile(fp) + files = [] + try: + files = [(open(fp, 'rb'), os.path.basename(fp)) for fp in file_paths] + rv = client.post(rest_path, data={ + 'file': files, + 'name': layername + }) + resp_json = rv.get_json() + assert rv.status_code == 409 + assert resp_json['code'] == 41 + finally: + for fp in files: + fp[0].close() + + @pytest.mark.usefixtures('app_context') def test_wrong_value_of_layername(client): username = 'testuser1'