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

Add column role_name to table rights #963

Merged
merged 1 commit into from
Nov 28, 2023
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
It was already required in v1.22.2.
### 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.
#### Data migrations
### Changes
- All changes from [v1.22.1](#v1221) and [v1.22.2](#v1222).
Expand Down
5 changes: 4 additions & 1 deletion src/layman/upgrade/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from db import util as db_util
from layman.upgrade import upgrade_v1_8, upgrade_v1_9, upgrade_v1_10, upgrade_v1_12, upgrade_v1_16, upgrade_v1_17, upgrade_v1_18, \
upgrade_v1_20, upgrade_v1_21, upgrade_v1_22
upgrade_v1_20, upgrade_v1_21, upgrade_v1_22, upgrade_v1_23
from layman import settings
from . import consts

Expand Down Expand Up @@ -41,6 +41,9 @@
((1, 22, 0), [
upgrade_v1_22.create_map_layer_relation_table,
]),
((1, 23, 0), [
upgrade_v1_23.adjust_db_for_roles,
]),
],
consts.MIGRATION_TYPE_DATA: [
((1, 16, 0), [
Expand Down
26 changes: 26 additions & 0 deletions src/layman/upgrade/upgrade_v1_23.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import logging

from db import util as db_util
from layman import settings

logger = logging.getLogger(__name__)
DB_SCHEMA = settings.LAYMAN_PRIME_SCHEMA


def adjust_db_for_roles():
logger.info(f' Alter DB prime schema for roles')

statement = f'''
ALTER TABLE {DB_SCHEMA}.rights ADD COLUMN IF NOT EXISTS
role_name VARCHAR(64) COLLATE pg_catalog."default";
ALTER TABLE {DB_SCHEMA}.rights ALTER COLUMN id_user DROP NOT NULL;
ALTER TABLE {DB_SCHEMA}.rights ADD CONSTRAINT rights_role_xor_user
CHECK ((id_user IS NULL) != (role_name IS NULL));
ALTER TABLE {DB_SCHEMA}.rights DROP CONSTRAINT IF EXISTS rights_unique_key;
ALTER TABLE {DB_SCHEMA}.rights ADD CONSTRAINT rights_unique_key unique (id_user, role_name, id_publication, type);
'''

db_util.run_statement(statement)
60 changes: 60 additions & 0 deletions src/layman/upgrade/upgrade_v1_23_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import pytest

from db import util as db_util
from layman import app, settings
from test_tools import process_client
from . import upgrade_v1_23

DB_SCHEMA = settings.LAYMAN_PRIME_SCHEMA


@pytest.mark.usefixtures('ensure_layman', 'oauth2_provider_mock')
def test_adjust_db_for_roles():
username = 'test_adjust_db_for_roles_ws'
username2 = 'test_adjust_db_for_roles_ws2'
layer_name = 'test_adjust_db_for_roles_layer'

headers = process_client.get_authz_headers(username)
process_client.reserve_username(username, headers=headers)
headers2 = process_client.get_authz_headers(username2)
process_client.reserve_username(username2, headers=headers2)

process_client.publish_workspace_layer(username, layer_name, headers=headers, access_rights={
'read': f"{username},{username2}",
})

statement = f'''
ALTER TABLE {DB_SCHEMA}.rights ALTER COLUMN id_user SET NOT NULL;
ALTER TABLE {DB_SCHEMA}.rights DROP CONSTRAINT rights_role_xor_user;
ALTER TABLE {DB_SCHEMA}.rights DROP CONSTRAINT rights_unique_key;
ALTER TABLE {DB_SCHEMA}.rights ADD CONSTRAINT rights_unique_key unique (id_user, id_publication, type);
ALTER TABLE {DB_SCHEMA}.rights DROP COLUMN role_name;
'''
with app.app_context():
db_util.run_statement(statement)

query = f'''select * from {DB_SCHEMA}.rights;'''
with app.app_context():
rights_rows = db_util.run_query(query)
assert len(rights_rows[0]) == 4, f"Exactly 4 columns expected before migration"

with app.app_context():
upgrade_v1_23.adjust_db_for_roles()

query = f'''
select id, id_user, role_name, id_publication, type
from {DB_SCHEMA}.rights
where id_publication in (
select id from {DB_SCHEMA}.publications
where name='{layer_name}'
and id_workspace in (
select id from {DB_SCHEMA}.workspaces
where name='{username}'
)
)
'''
with app.app_context():
rights_rows = db_util.run_query(query)
assert len(rights_rows) == 1
assert rights_rows[0][1] is not None, f"id_user is none!"
assert rights_rows[0][2] is None, f"role_name is not none!"
2 changes: 2 additions & 0 deletions test_tools/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ def oauth2_provider_mock():
'layer_map_relation_user': None,
'wrong_input_owner': None,
'wrong_input_editor': None,
'test_adjust_db_for_roles_ws': None,
'test_adjust_db_for_roles_ws2': None,
},
},
'host': '0.0.0.0',
Expand Down
Loading