mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-04 19:21:51 +00:00
8a1d7bcd6b
Co-authored-by: Daniel Barranquero <danielbo2001@gmail.com> Co-authored-by: Hugo P.Brito <hugopbrit@gmail.com>
103 lines
3.5 KiB
Python
103 lines
3.5 KiB
Python
from unittest.mock import MagicMock, patch
|
|
|
|
from linode_api4.errors import ApiError
|
|
|
|
from prowler.providers.linode.services.administration.administration_service import (
|
|
AdministrationService,
|
|
)
|
|
|
|
|
|
def _mock_user(username="admin", email="admin@example.com", tfa=True, restricted=False):
|
|
user = MagicMock()
|
|
user.username = username
|
|
user.email = email
|
|
user.tfa_enabled = tfa
|
|
user.restricted = restricted
|
|
return user
|
|
|
|
|
|
def _build_service(account_users_return=None, account_users_side_effect=None):
|
|
"""Build an AdministrationService with an isolated mock client."""
|
|
service = object.__new__(AdministrationService)
|
|
service.users = []
|
|
|
|
# Build isolated mock hierarchy for client.account.users()
|
|
# Must explicitly create the users callable as a fresh MagicMock
|
|
# because check tests contaminate MagicMock class with users=[...]
|
|
users_callable = MagicMock()
|
|
if account_users_side_effect:
|
|
users_callable.side_effect = account_users_side_effect
|
|
else:
|
|
users_callable.return_value = account_users_return or []
|
|
|
|
account_mock = MagicMock()
|
|
account_mock.users = users_callable
|
|
|
|
client_mock = MagicMock()
|
|
client_mock.account = account_mock
|
|
service.client = client_mock
|
|
return service
|
|
|
|
|
|
class TestLinodeAdministrationService:
|
|
def test_describe_users_parses_correctly(self):
|
|
mock_users = [
|
|
_mock_user("admin", "admin@example.com", True, False),
|
|
_mock_user("reader", "reader@example.com", False, True),
|
|
]
|
|
|
|
service = _build_service(account_users_return=mock_users)
|
|
service._describe_users()
|
|
|
|
assert len(service.users) == 2
|
|
assert service.users[0].username == "admin"
|
|
assert service.users[0].tfa_enabled is True
|
|
assert service.users[1].username == "reader"
|
|
assert service.users[1].restricted is True
|
|
|
|
def test_describe_users_handles_empty_list(self):
|
|
service = _build_service(account_users_return=[])
|
|
service._describe_users()
|
|
|
|
assert len(service.users) == 0
|
|
|
|
def test_describe_users_handles_api_error(self):
|
|
service = _build_service(account_users_side_effect=Exception("API error"))
|
|
service._describe_users()
|
|
|
|
assert len(service.users) == 0
|
|
|
|
def test_describe_users_handles_null_fields(self):
|
|
"""A user with null tfa_enabled/email must still be included with safe
|
|
defaults instead of being dropped by a ValidationError."""
|
|
user = MagicMock()
|
|
user.username = "partial"
|
|
user.email = None
|
|
user.tfa_enabled = None
|
|
user.restricted = None
|
|
|
|
service = _build_service(account_users_return=[user])
|
|
service._describe_users()
|
|
|
|
assert len(service.users) == 1
|
|
assert service.users[0].username == "partial"
|
|
assert service.users[0].email == ""
|
|
assert service.users[0].tfa_enabled is False
|
|
assert service.users[0].restricted is False
|
|
|
|
def test_describe_users_missing_scope_logs_permission_error(self):
|
|
error = ApiError(
|
|
"Your OAuth token is not authorized to use this endpoint.", status=401
|
|
)
|
|
service = _build_service(account_users_side_effect=error)
|
|
|
|
with patch(
|
|
"prowler.providers.linode.lib.service.service.logger"
|
|
) as logger_mock:
|
|
service._describe_users()
|
|
|
|
assert len(service.users) == 0
|
|
logged = " ".join(str(c) for c in logger_mock.error.call_args_list)
|
|
assert "LinodeMissingPermissionError" in logged
|
|
assert "account:read_only" in logged
|