Skip to content
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
49 changes: 30 additions & 19 deletions src/authentication/rh_identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,45 +54,53 @@ def _validate_structure(self) -> None:
"identity" not in self.identity_data
or self.identity_data["identity"] is None
):
raise HTTPException(status_code=400, detail="Missing 'identity' field")
logger.warning("Identity validation failed: missing 'identity' field")
raise HTTPException(status_code=400, detail="Invalid identity data")

identity = self.identity_data["identity"]
if "type" not in identity:
raise HTTPException(status_code=400, detail="Missing identity 'type' field")
logger.warning("Identity validation failed: missing 'type' field")
raise HTTPException(status_code=400, detail="Invalid identity data")

identity_type = identity["type"]
if identity_type == "User":
if "user" not in identity:
raise HTTPException(
status_code=400, detail="Missing 'user' field for User type"
logger.warning(
"Identity validation failed: missing 'user' field for User type"
)
raise HTTPException(status_code=400, detail="Invalid identity data")
user = identity["user"]
if "user_id" not in user:
raise HTTPException(
status_code=400, detail="Missing 'user_id' in user data"
logger.warning(
"Identity validation failed: missing 'user_id' in user data"
)
raise HTTPException(status_code=400, detail="Invalid identity data")
if "username" not in user:
raise HTTPException(
status_code=400, detail="Missing 'username' in user data"
logger.warning(
"Identity validation failed: missing 'username' in user data"
)
raise HTTPException(status_code=400, detail="Invalid identity data")
elif identity_type == "System":
if "system" not in identity:
raise HTTPException(
status_code=400, detail="Missing 'system' field for System type"
logger.warning(
"Identity validation failed: missing 'system' field for System type"
)
raise HTTPException(status_code=400, detail="Invalid identity data")
system = identity["system"]
if "cn" not in system:
raise HTTPException(
status_code=400, detail="Missing 'cn' in system data"
logger.warning(
"Identity validation failed: missing 'cn' in system data"
)
raise HTTPException(status_code=400, detail="Invalid identity data")
if "account_number" not in identity:
raise HTTPException(
status_code=400, detail="Missing 'account_number' for System type"
logger.warning(
"Identity validation failed: "
"missing 'account_number' for System type"
)
raise HTTPException(status_code=400, detail="Invalid identity data")
else:
raise HTTPException(
status_code=400, detail=f"Unsupported identity type: {identity_type}"
)
logger.warning("Identity validation failed: unsupported identity type")
raise HTTPException(status_code=400, detail="Invalid identity data")

def _get_identity_type(self) -> str:
"""Get the identity type (User or System).
Expand Down Expand Up @@ -169,10 +177,13 @@ def validate_entitlements(self) -> None:

missing = [s for s in self.required_entitlements if not self.has_entitlement(s)]
if missing:
entitlement_word = "entitlement" if len(missing) == 1 else "entitlements"
logger.warning(
"Entitlement validation failed: missing required entitlements: %s",
", ".join(missing),
)
raise HTTPException(
status_code=403,
detail=f"Missing required {entitlement_word}: {', '.join(missing)}",
detail="Insufficient entitlements",
)


Expand Down
12 changes: 6 additions & 6 deletions tests/e2e/features/authorized_rh_identity.feature
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Feature: Authorized endpoint API tests for the rh-identity authentication module
{"placeholder":"abc"}
"""
Then The status code of the response is 400
And The body of the response contains Missing 'identity' field
And The body of the response contains Invalid identity data

Scenario: Request succeeds with valid User identity and required entitlements
Given The system is in default state
Expand Down Expand Up @@ -79,7 +79,7 @@ Feature: Authorized endpoint API tests for the rh-identity authentication module
{"placeholder":"abc"}
"""
Then The status code of the response is 403
And The body of the response contains Missing required entitlement
And The body of the response contains Insufficient entitlements

Scenario: Request fails when entitlement exists but is_entitled is false
Given The system is in default state
Expand All @@ -99,7 +99,7 @@ Feature: Authorized endpoint API tests for the rh-identity authentication module
{"placeholder":"abc"}
"""
Then The status code of the response is 403
And The body of the response contains Missing required entitlement
And The body of the response contains Insufficient entitlements

Scenario: Request fails when User identity is missing user_id
Given The system is in default state
Expand All @@ -119,7 +119,7 @@ Feature: Authorized endpoint API tests for the rh-identity authentication module
{"placeholder":"abc"}
"""
Then The status code of the response is 400
And The body of the response contains Missing 'user_id' in user data
And The body of the response contains Invalid identity data

Scenario: Request fails when User identity is missing username
Given The system is in default state
Expand All @@ -139,7 +139,7 @@ Feature: Authorized endpoint API tests for the rh-identity authentication module
{"placeholder":"abc"}
"""
Then The status code of the response is 400
And The body of the response contains Missing 'username' in user data
And The body of the response contains Invalid identity data

Scenario: Request fails when System identity is missing cn
Given The system is in default state
Expand All @@ -160,4 +160,4 @@ Feature: Authorized endpoint API tests for the rh-identity authentication module
{"placeholder":"abc"}
"""
Then The status code of the response is 400
And The body of the response contains Missing 'cn' in system data
And The body of the response contains Invalid identity data
40 changes: 25 additions & 15 deletions tests/unit/authentication/test_rh_identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,12 @@ def test_has_entitlements(
(
["openshift"],
True,
"Missing required entitlement: openshift",
"Insufficient entitlements",
), # Single missing
(
["rhel", "ansible", "openshift"],
True,
"Missing required entitlement: openshift",
"Insufficient entitlements",
), # Multiple with one missing
],
)
Expand Down Expand Up @@ -236,11 +236,11 @@ def test_validate_entitlements(
@pytest.mark.parametrize(
"missing_field,expected_error",
[
({"identity": None}, "Missing 'identity' field"),
({"identity": {"org_id": "123"}}, "Missing identity 'type' field"),
({"identity": None}, "Invalid identity data"),
({"identity": {"org_id": "123"}}, "Invalid identity data"),
(
{"identity": {"type": "User", "org_id": "123"}},
"Missing 'user' field for User type",
"Invalid identity data",
),
(
{
Expand All @@ -250,7 +250,7 @@ def test_validate_entitlements(
"user": {"username": "test"},
}
},
"Missing 'user_id' in user data",
"Invalid identity data",
),
(
{
Expand All @@ -260,15 +260,15 @@ def test_validate_entitlements(
"user": {"user_id": "123"},
}
},
"Missing 'username' in user data",
"Invalid identity data",
),
(
{"identity": {"type": "System", "org_id": "123"}},
"Missing 'system' field for System type",
"Invalid identity data",
),
(
{"identity": {"type": "System", "org_id": "123", "system": {}}},
"Missing 'cn' in system data",
"Invalid identity data",
),
(
{
Expand All @@ -278,29 +278,39 @@ def test_validate_entitlements(
"system": {"cn": "test"},
}
},
"Missing 'account_number' for System type",
"Invalid identity data",
),
],
)
def test_validation_failures(
self, missing_field: dict, expected_error: str
self,
missing_field: dict,
expected_error: str,
mocker: MockerFixture,
) -> None:
"""Test validation failures for various missing fields."""
mock_warning = mocker.patch("authentication.rh_identity.logger.warning")

with pytest.raises(HTTPException) as exc_info:
RHIdentityData(missing_field)

assert exc_info.value.status_code == 400
assert expected_error in str(exc_info.value.detail)
mock_warning.assert_called_once()
assert "Identity validation failed" in mock_warning.call_args[0][0]

def test_unsupported_identity_type(self) -> None:
def test_unsupported_identity_type(self, mocker: MockerFixture) -> None:
"""Test validation fails with unsupported identity type."""
mock_warning = mocker.patch("authentication.rh_identity.logger.warning")
invalid_data = {"identity": {"type": "Unknown", "org_id": "123"}}

with pytest.raises(HTTPException) as exc_info:
RHIdentityData(invalid_data)

assert exc_info.value.status_code == 400
assert "Unsupported identity type: Unknown" in str(exc_info.value.detail)
assert "Invalid identity data" in str(exc_info.value.detail)
mock_warning.assert_called_once()
assert "Identity validation failed" in mock_warning.call_args[0][0]


class TestRHIdentityAuthDependency:
Expand Down Expand Up @@ -406,12 +416,12 @@ async def test_invalid_json(self) -> None:
(
["openshift"],
True,
"Missing required entitlement: openshift",
"Insufficient entitlements",
), # Single missing
(
["rhel", "ansible", "openshift"],
True,
"Missing required entitlement: openshift",
"Insufficient entitlements",
), # Multiple with one missing
],
)
Expand Down
Loading