Skip to content

#194: improving auth user match checking#195

Merged
lsulak merged 17 commits into
masterfrom
bugfix/194-making-auth-case-insensitive
Jul 20, 2026
Merged

#194: improving auth user match checking#195
lsulak merged 17 commits into
masterfrom
bugfix/194-making-auth-case-insensitive

Conversation

@lsulak

@lsulak lsulak commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Release Notes

  • Improving user authorization for posting topic messages by making user matching case-insensitive and refactoring the authorization logic.

Closes: #194

Summary by CodeRabbit

  • New Features

    • Topic posting authorization now matches usernames regardless of letter casing.
    • Authorization errors provide clearer user-related details.
  • Bug Fixes

    • Improved reporting when one or more message writers fail.
    • Added confirmation logging for successfully dispatched topic messages.
  • Tests

    • Added coverage verifying case-insensitive authorization for topic posting.
  • Chores

    • Expanded project ignore rules for development artifacts, build outputs, secrets, and temporary files.

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Topic POST authorization now accepts case differences between JWT subjects and configured usernames, while preserving existing response shapes and adding dispatch outcome logs. The repository ignore file was expanded with categorized development and infrastructure artifact patterns.

Changes

Topic authorization and dispatch

Layer / File(s) Summary
Case-insensitive authorization resolution
src/handlers/handler_topic.py, tests/unit/handlers/test_handler_topic.py
Configured usernames are matched case-insensitively, reused for permission checks, and covered by a successful POST authorization test.
Writer dispatch outcome logging
src/handlers/handler_topic.py
Writer failures and successful dispatches now emit corresponding summary logs while retaining existing responses.

Repository ignore policy

Layer / File(s) Summary
Categorized ignore patterns
.gitignore
Ignore rules now cover OS, IDE, environment, Python, test, documentation, Terraform, certificate, temporary, and log artifacts.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant JWTDecoder
  participant HandlerTopic
  participant AccessConfig
  participant Writers
  JWTDecoder->>HandlerTopic: provide token subject
  HandlerTopic->>AccessConfig: resolve configured username case-insensitively
  AccessConfig-->>HandlerTopic: return configured username
  HandlerTopic->>Writers: dispatch topic message
  Writers-->>HandlerTopic: report write results
Loading

Suggested reviewers: oto-macenauer-absa, petr-pokorny-absa, tmikula-dev

Poem

A rabbit checks the names with care,
Case by case, it lets folks share.
Writers hop and logs chime bright,
Ignore files tidy up the night.
“Success!” it thumps, then fades from sight.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The broad .gitignore overhaul is unrelated to issue #194's authorization fix. Move the .gitignore changes to a separate PR or remove them from this authorization-only change.
Description check ⚠️ Warning The description is missing the required Overview section and does not use the template’s Related section format. Add an ## Overview section, format ## Related as 'Closes #194', and keep the Release Notes section with the key changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The case-insensitive authorization change and test satisfy issue #194's acceptance criteria.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title is concise and matches the PR’s case-insensitive auth user matching change.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bugfix/194-making-auth-case-insensitive

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@lsulak lsulak linked an issue Jul 14, 2026 that may be closed by this pull request

@tmikula-dev tmikula-dev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad, that I learned the difference between .lower() and .casefold()

Comment thread src/handlers/handler_topic.py
Base automatically changed from copilot/add-docs-endpoint to master July 20, 2026 13:30

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/unit/handlers/test_handler_topic.py`:
- Around line 260-277: Update test_post_authorized_user_case_insensitive to use
the mocker fixture with mocker.patch.object for decode_jwt and each writer.write
instead of a patch context manager; rewrite assertions consistently as expected
== actual, including the success assertion, while preserving the test behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 880963d3-e614-4126-abf9-60a6beb0c8df

📥 Commits

Reviewing files that changed from the base of the PR and between 27c3166 and 916fc3f.

📒 Files selected for processing (3)
  • .gitignore
  • src/handlers/handler_topic.py
  • tests/unit/handlers/test_handler_topic.py

Comment on lines +260 to +277
def test_post_authorized_user_case_insensitive(event_gate_module, make_event, valid_payload):
with patch.object(event_gate_module.handler_token, "decode_jwt", return_value={"sub": "testuser"}):
for writer in event_gate_module.handler_topic.writers.values():
writer.write = MagicMock(return_value=None)

event = make_event(
"/topics/{topic_name}",
method="POST",
topic="public.cps.za.test",
body=valid_payload,
headers={"Authorization": "Bearer token"},
)
resp = event_gate_module.lambda_handler(event)
assert 202 == resp["statusCode"]
body = json.loads(resp["body"])
assert body["success"]


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Use mocker.patch.object and follow the assertion format.

As per coding guidelines, use the mocker fixture instead of unittest.mock.patch context managers, and write assertions strictly in the expected == actual format. Additionally, using mocker.patch.object on the writers ensures that the mocks are safely cleaned up after the test completes, preventing potential side effects on other tests.

♻️ Proposed refactor
-def test_post_authorized_user_case_insensitive(event_gate_module, make_event, valid_payload):
-    with patch.object(event_gate_module.handler_token, "decode_jwt", return_value={"sub": "testuser"}):
-        for writer in event_gate_module.handler_topic.writers.values():
-            writer.write = MagicMock(return_value=None)
-
-        event = make_event(
-            "/topics/{topic_name}",
-            method="POST",
-            topic="public.cps.za.test",
-            body=valid_payload,
-            headers={"Authorization": "Bearer token"},
-        )
-        resp = event_gate_module.lambda_handler(event)
-        assert 202 == resp["statusCode"]
-        body = json.loads(resp["body"])
-        assert body["success"]
+def test_post_authorized_user_case_insensitive(event_gate_module, make_event, valid_payload, mocker):
+    mocker.patch.object(event_gate_module.handler_token, "decode_jwt", return_value={"sub": "testuser"})
+    for writer in event_gate_module.handler_topic.writers.values():
+        mocker.patch.object(writer, "write", return_value=None)
+
+    event = make_event(
+        "/topics/{topic_name}",
+        method="POST",
+        topic="public.cps.za.test",
+        body=valid_payload,
+        headers={"Authorization": "Bearer token"},
+    )
+    resp = event_gate_module.lambda_handler(event)
+    assert 202 == resp["statusCode"]
+    body = json.loads(resp["body"])
+    assert True == body["success"]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def test_post_authorized_user_case_insensitive(event_gate_module, make_event, valid_payload):
with patch.object(event_gate_module.handler_token, "decode_jwt", return_value={"sub": "testuser"}):
for writer in event_gate_module.handler_topic.writers.values():
writer.write = MagicMock(return_value=None)
event = make_event(
"/topics/{topic_name}",
method="POST",
topic="public.cps.za.test",
body=valid_payload,
headers={"Authorization": "Bearer token"},
)
resp = event_gate_module.lambda_handler(event)
assert 202 == resp["statusCode"]
body = json.loads(resp["body"])
assert body["success"]
def test_post_authorized_user_case_insensitive(event_gate_module, make_event, valid_payload, mocker):
mocker.patch.object(event_gate_module.handler_token, "decode_jwt", return_value={"sub": "testuser"})
for writer in event_gate_module.handler_topic.writers.values():
mocker.patch.object(writer, "write", return_value=None)
event = make_event(
"/topics/{topic_name}",
method="POST",
topic="public.cps.za.test",
body=valid_payload,
headers={"Authorization": "Bearer token"},
)
resp = event_gate_module.lambda_handler(event)
assert 202 == resp["statusCode"]
body = json.loads(resp["body"])
assert True == body["success"]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/handlers/test_handler_topic.py` around lines 260 - 277, Update
test_post_authorized_user_case_insensitive to use the mocker fixture with
mocker.patch.object for decode_jwt and each writer.write instead of a patch
context manager; rewrite assertions consistently as expected == actual,
including the success assertion, while preserving the test behavior.

Source: Coding guidelines

@lsulak
lsulak merged commit f5c6f57 into master Jul 20, 2026
11 of 12 checks passed
@lsulak
lsulak deleted the bugfix/194-making-auth-case-insensitive branch July 20, 2026 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Authorization should be case insensitive

3 participants