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

Patch user rule #4163

Merged
merged 3 commits into from
Jan 28, 2025
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
5 changes: 3 additions & 2 deletions cg/services/orders/validation/rules/order/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
UserNotAssociatedWithCustomerError,
)
from cg.services.orders.validation.models.order import Order
from cg.store.models import User
from cg.store.store import Store


Expand All @@ -22,13 +23,13 @@ def validate_customer_exists(
def validate_user_belongs_to_customer(
order: Order, store: Store, **kwargs
) -> list[UserNotAssociatedWithCustomerError]:
user: User = store.get_user_by_entry_id(order._user_id)
has_access: bool = store.is_user_associated_with_customer(
user_id=order._user_id,
customer_internal_id=order.customer,
)

errors: list[UserNotAssociatedWithCustomerError] = []
if not has_access:
if not (user.is_admin or has_access):
islean marked this conversation as resolved.
Show resolved Hide resolved
error = UserNotAssociatedWithCustomerError()
errors.append(error)
return errors
Expand Down
8 changes: 8 additions & 0 deletions cg/store/crud/read.py
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,14 @@ def get_user_by_email(self, email: str) -> User | None:
filter_functions=[UserFilter.BY_EMAIL],
).first()

def get_user_by_entry_id(self, id: int) -> User | None:
"""Return a user by its entry id."""
return apply_user_filter(
users=self._get_query(table=User),
user_id=id,
filter_functions=[UserFilter.BY_ID],
).first()

def is_user_associated_with_customer(self, user_id: int, customer_internal_id: str) -> bool:
user: User | None = apply_user_filter(
users=self._get_query(table=User),
Expand Down
21 changes: 20 additions & 1 deletion tests/services/orders/validation_service/test_order_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from cg.services.orders.validation.workflows.tomte.models.order import TomteOrder
from cg.store.models import Customer
from cg.store.store import Store
from tests.store_helpers import StoreHelpers


def test_validate_customer_can_skip_reception_control(base_store: Store, valid_order: TomteOrder):
Expand Down Expand Up @@ -47,9 +48,12 @@ def test_validate_customer_does_not_exist(base_store: Store, valid_order: TomteO
assert isinstance(errors[0], CustomerDoesNotExistError)


def test_validate_user_belongs_to_customer(base_store: Store, valid_order: TomteOrder):
def test_validate_user_belongs_to_customer(
base_store: Store, valid_order: TomteOrder, helpers: StoreHelpers
):
# GIVEN an order for a customer which the logged-in user does not have access to
customer: Customer = base_store.get_customer_by_internal_id(valid_order.customer)
helpers.ensure_user(store=base_store, customer=customer)
customer.users = []

# WHEN validating that the user belongs to the customer account
Expand All @@ -62,3 +66,18 @@ def test_validate_user_belongs_to_customer(base_store: Store, valid_order: Tomte

# THEN the error should concern the user not belonging to the customer
assert isinstance(errors[0], UserNotAssociatedWithCustomerError)


def test_validate_admin_bypass(base_store: Store, valid_order: TomteOrder, helpers: StoreHelpers):
# GIVEN an order for a customer which the logged-in _admin_ user does not have access to
customer: Customer = base_store.get_customer_by_internal_id(valid_order.customer)
helpers.ensure_user(store=base_store, customer=customer, is_admin=True)
customer.users = []

# WHEN validating that the user belongs to the customer account
errors: list[UserNotAssociatedWithCustomerError] = validate_user_belongs_to_customer(
order=valid_order, store=base_store
)

# THEN no error should be raised
assert not errors
Loading