Skip to content

Commit 30d57d9

Browse files
committed
fix: responding to John's pr review and creating script to add read-only user
1 parent 33d942d commit 30d57d9

2 files changed

Lines changed: 90 additions & 9 deletions

File tree

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
"""Script to add READ_ONLY role if it doesn't already exist.
2+
3+
This script should be run after the database is initialized and migrations are applied.
4+
It adds the READ_ONLY role with GET-only permissions.
5+
6+
Usage:
7+
ENV=local python data_tools/src/import_static_data/add_read_only_role.py
8+
"""
9+
10+
import logging
11+
import sys
12+
13+
import click
14+
from sqlalchemy import text
15+
from sqlalchemy.orm import Session, scoped_session, sessionmaker
16+
17+
from data_tools.src.common.db import init_db_from_config
18+
from data_tools.src.common.utils import get_config
19+
20+
logging.basicConfig(level=logging.INFO)
21+
logger = logging.getLogger(__name__)
22+
23+
24+
def add_read_only_role(session: Session) -> None:
25+
"""Add READ_ONLY role if it doesn't already exist."""
26+
27+
# List of permissions for READ_ONLY role (from user_data.json5)
28+
read_only_permissions = [
29+
"GET_AGREEMENT",
30+
"GET_BUDGET_LINE_ITEM",
31+
"GET_SERVICES_COMPONENT",
32+
"GET_BLI_PACKAGE",
33+
"GET_CAN",
34+
"GET_DIVISION",
35+
"GET_NOTIFICATION",
36+
"GET_PORTFOLIO",
37+
"GET_RESEARCH_PROJECT",
38+
"GET_USER",
39+
"GET_HISTORY",
40+
"GET_WORKFLOW",
41+
"GET_CHANGE_REQUEST",
42+
"GET_CHANGE_REQUEST_REVIEW",
43+
"GET_UPLOAD_DOCUMENT",
44+
]
45+
46+
# Insert READ_ONLY role with permissions
47+
logger.info("Adding READ_ONLY role with %d permissions...", len(read_only_permissions))
48+
session.execute(
49+
text("INSERT INTO role (name, permissions) VALUES (:name, :permissions)"),
50+
{"name": "READ_ONLY", "permissions": read_only_permissions},
51+
)
52+
session.commit()
53+
54+
# Get the assigned ID
55+
result = session.execute(text("SELECT id FROM role WHERE name = 'READ_ONLY'")).fetchone()
56+
57+
logger.info("Successfully added READ_ONLY role with ID %s", result[0])
58+
59+
60+
@click.command()
61+
@click.option("--env", required=True, help="The environment to use (dev, local, azure).")
62+
def main(env: str) -> None:
63+
"""Main function to add READ_ONLY role."""
64+
config = get_config(env)
65+
logger.info(str(config.db_connection_string))
66+
engine, _ = init_db_from_config(config)
67+
if engine is None:
68+
logger.error("Failed to initialize the database engine.")
69+
sys.exit(1)
70+
71+
with engine.connect() as conn:
72+
conn.execute(text("SELECT 1"))
73+
logger.info("Successfully connected to the database.")
74+
75+
session_factory = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
76+
77+
with session_factory() as session:
78+
add_read_only_role(session)
79+
80+
logger.info("Procurement tracker backfill complete.")
81+
82+
83+
if __name__ == "__main__":
84+
main()

backend/ops_api/ops/services/users.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,25 +83,22 @@ def get_users(session: Session, **kwargs) -> list[User]:
8383
"""
8484
stmt = select(User)
8585

86+
exclude_read_only = kwargs.pop("exclude_read_only", False)
87+
8688
for key, value in kwargs.items():
8789
if key == "roles":
8890
stmt = stmt.where(User.roles.any(Role.name.in_(value)))
89-
elif key == "exclude_read_only":
90-
exclude_read_only = value
9191
else:
9292
stmt = stmt.where(cast(ColumnElement[bool], getattr(User, key)) == value)
9393

94+
if exclude_read_only:
95+
stmt = stmt.where(~User.roles.any(Role.name == "READ_ONLY"))
96+
9497
stmt = stmt.order_by(User.id)
9598

9699
users = session.execute(stmt).scalars().all()
97100

98-
if exclude_read_only:
99-
# Filter out users with READ_ONLY role
100-
filtered_users = [user for user in users if not any(role.name == "READ_ONLY" for role in user.roles)]
101-
102-
return filtered_users
103-
else:
104-
return users
101+
return users
105102

106103

107104
def create_user(session: Session, **kwargs) -> User:

0 commit comments

Comments
 (0)