Skip to content

Commit

Permalink
Add column role_name to table rights
Browse files Browse the repository at this point in the history
  • Loading branch information
jirik committed Nov 28, 2023
1 parent 7880809 commit 0866e50
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 1 deletion.
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
30 changes: 30 additions & 0 deletions src/layman/upgrade/upgrade_v1_23.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
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(256) COLLATE pg_catalog."default";
ALTER TABLE {DB_SCHEMA}.rights ALTER COLUMN id_user DROP NOT NULL;
DO $$ BEGIN
ALTER TABLE {DB_SCHEMA}.rights ADD CONSTRAINT rights_role_xor_user
CHECK ((id_user IS NULL) != (role_name IS NULL));
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
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

0 comments on commit 0866e50

Please sign in to comment.