Skip to content

Fix Civil ID S3 handling and env-based S3 credentials#77

Open
sureshchouksey8 wants to merge 2 commits into
BAWES-Universe:masterfrom
sureshchouksey8:codex/studenthub-s3-civil-hardening
Open

Fix Civil ID S3 handling and env-based S3 credentials#77
sureshchouksey8 wants to merge 2 commits into
BAWES-Universe:masterfrom
sureshchouksey8:codex/studenthub-s3-civil-hardening

Conversation

@sureshchouksey8
Copy link
Copy Markdown

@sureshchouksey8 sureshchouksey8 commented May 15, 2026

/claim #55

Summary

  • Patch Civil ID remove/update flows to return operation:error instead of raw 500s, mark Civil ID verification needed after removals, and validate Civil ID plus expiry date input.
  • Fix Civil ID permanent object prefix from candidate-civil-id/ to photos/, delete old objects best-effort only when present, and avoid adding Civil ID delete errors to candidate_resume.
  • Copy new Civil ID uploads before deleting old ones and verify the destination object with S3 headObject.
  • Move temp and permanent S3 access keys in the patched configs to environment variables.
  • Add a static regression guard for the S3/Civil ID hardening contract.

Acceptance Criteria Covered

  • Civil ID front/back removal tolerates missing S3 objects and avoids 500s.
  • Civil ID expiry/date update validates inputs and catches save failures.
  • Civil ID deletes use photos/ instead of candidate-civil-id/.
  • Civil ID delete failures do not pollute candidate_resume errors.
  • Civil ID upload copies/verifies the new object before deleting the old object.
  • S3ResourceManager::fileExists() uses S3 headObject for bucket keys.
  • Temp/permanent S3 keys are read from env vars in the touched configs.

Verification

  • sh tests/check-s3-civil-id-hardening.sh
  • git diff --check

PHP is not installed in this local environment, so I could not run php -l locally.

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced validation for civil ID expiry dates.
  • Bug Fixes

    • Improved error handling and messaging for civil photo upload and removal operations.
    • Enhanced file operation reliability for document storage.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

Warning

Rate limit exceeded

@sureshchouksey8 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 12 minutes and 12 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b11c9745-4c0f-42c2-a332-3a91a64441fb

📥 Commits

Reviewing files that changed from the base of the PR and between da3107b and 06858e2.

📒 Files selected for processing (4)
  • candidate/modules/v1/controllers/AccountController.php
  • common/config/main.php
  • environments/prod-railway/common/config/main-local.php
  • tests/check-s3-civil-id-hardening.sh
📝 Walkthrough

Walkthrough

This PR hardens civil ID photo handling in S3 by externalizing AWS credentials to environment variables, improving S3 file operations with better existence checks, reorganizing civil photo storage from civil-id/ to photos/ folder, and adding robust error handling and validation to account controller actions.

Changes

S3 Civil ID Photo Hardening

Layer / File(s) Summary
AWS credential externalization
common/config/main.php, environments/prod-railway/common/config/main-local.php, tests/check-s3-civil-id-hardening.sh
Temporary and permanent S3 bucket configurations migrate from hardcoded keys to environment variables (AWS_TEMP_BUCKET_*, AWS_PERMANENT_S3_*) with fallback defaults; new verification script confirms hardcoded credentials are removed and expected env vars are referenced.
S3 client robustness improvements
common/components/S3ResourceManager.php
delete() method defaults return value to true when DeleteMarker is absent; fileExists() method uses headObject() for non-URL inputs and returns false on AwsException, maintaining backward-compatible Guzzle HEAD flow for URLs.
Civil ID photo model storage refactor
common/models/Candidate.php
FILE_ATTRIBUTES maps civil photos to photos/ folder instead of civil-id/; deleteFile() targets new paths with existence checks and warning logs; updateCivilId() defers old-file cleanup until after verifying the new copy exists in S3.
Civil photo action handler hardening
candidate/modules/v1/controllers/AccountController.php
Remove actions now wrap delete operations in try/catch, log exceptions, and return translated error messages; update actions validate candidate existence and throw 404; expiry-date action adds strtotime validation and exception handling.
Code formatting and docblock updates
candidate/modules/v1/controllers/AccountController.php
Whitespace, docblock alignment, and method signature spacing normalized across AccountController action methods without behavioral changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • #55: This PR directly implements the backend S3 civil-ID hardening fixes including photo path reorganization, headObject existence validation, env var credential externalization, and improved error handling in controller actions.

Poem

🐇 A rabbit hops through photo folders,
Moving civil IDs to photos/ with care,
AWS secrets now in ENV, no more holders—
Error handling wrapped, hardened everywhere! 🔐

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main objectives of the pull request, which are fixing Civil ID S3 handling and migrating S3 credentials to environment variables.
Docstring Coverage ✅ Passed Docstring coverage is 97.22% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
tests/check-s3-civil-id-hardening.sh (1)

17-21: ⚡ Quick win

Harden regression checks against false pass/fail conditions.

The exact-line DeleteMarker grep is brittle, and grep -q 'try {' is too broad to prove civil-photo remove hardening.

Suggested tightening
-grep -q "return isset(\$result\\['DeleteMarker'\\]) ? \$result\\['DeleteMarker'\\] : true;" "$s3_manager"
+grep -Eq "DeleteMarker" "$s3_manager"

-grep -q 'try {' "$account_controller"
+grep -q 'actionRemoveCivilPhotoBack' "$account_controller"
+grep -q 'actionRemoveCivilPhotoFront' "$account_controller"
+grep -q 'Unable to remove civil photo back.' "$account_controller"
+grep -q 'Unable to remove civil photo front.' "$account_controller"
🤖 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/check-s3-civil-id-hardening.sh` around lines 17 - 21, The current
checks are brittle: replace the exact-line grep for DeleteMarker with a more
robust pattern that just ensures DeleteMarker is referenced in the result
handling (e.g., grep -q "isset(\\\$result\\['DeleteMarker'\\])" or grep -q
"DeleteMarker" against the s3 manager to avoid exact formatting dependence), and
tighten the broad grep for 'try {' so it only matches the try block that hardens
civil-photo removal by scoping the search to the civil-photo removal routine
(e.g., use a PCRE/ multiline search that looks for a function or method name
containing "civil" or "remove" followed soon after by "try {"), while keeping
the existing greps for candidate_civil_need_verification and 'Invalid civil ID
or expiry date' intact. Ensure you reference the same symbols (DeleteMarker,
candidate_civil_need_verification, 'Invalid civil ID or expiry date', and the
'try {' try-block) when updating the three grep checks.
🤖 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 `@candidate/modules/v1/controllers/AccountController.php`:
- Line 1322: The call to updateCivilId('back') (and the similar call at the
other location) currently ignores its return value; change the code to check the
boolean/falsey result from updateCivilId before proceeding, and if it indicates
failure, abort further processing (do not call save()) and return or throw an
appropriate error response from the controller; specifically, after calling
updateCivilId(...) in AccountController, inspect its result, handle error by
returning a failure response (or throwing an exception) with a clear message,
and only call save() when updateCivilId() succeeds.
- Around line 384-404: In actionRemoveCivilPhotoBack and
actionRemoveCivilPhotoFront, guard against a null $model returned by
Candidate::findOne(Yii::$app->user->getId()) by throwing a NotFoundHttpException
if $model is null, then proceed to check and clear
$model->candidate_civil_photo_back / $model->candidate_civil_photo_front, call
$model->deleteFile('civil-id','back'|'front') and set the scenario
('updateCivilPhotoBack' / corresponding front scenario) before save; also change
the error handler to catch \Throwable instead of \Exception so Errors/TypeErrors
are caught and logged with Yii::error.

In `@common/config/main.php`:
- Around line 11-12: The config currently sets 'key' =>
getenv('AWS_TEMP_BUCKET_KEY') ?: '' and 'secret' =>
getenv('AWS_TEMP_BUCKET_SECRET') ?: '', which masks missing env vars by
returning empty strings and prevents S3ResourceManager::init() from catching
nulls; change these to return null when the env var is unset (i.e., remove the
empty-string fallback) so the values are null if not provided, or explicitly
validate and throw a clear configuration error during bootstrap; update the
entries for 'key' and 'secret' (the getenv calls) accordingly so
S3ResourceManager::init() sees null for missing credentials.

In `@environments/prod-railway/common/config/main-local.php`:
- Around line 157-158: The config currently sets 'key' and 'secret' to empty
strings when getenv returns nothing; update the entries for 'key' and 'secret'
in the config array (the AWS_PERMANENT_S3_ACCESS_KEY_ID and
AWS_PERMANENT_S3_SECRET_ACCESS_KEY getenv calls) to use null as the fallback
instead of '' so missing permanent S3 credentials are represented as null;
ensure the consuming S3 initialization/validation logic that reads these config
keys ('key' and 'secret') treats null as "not provided" and fails fast or throws
a clear error.

---

Nitpick comments:
In `@tests/check-s3-civil-id-hardening.sh`:
- Around line 17-21: The current checks are brittle: replace the exact-line grep
for DeleteMarker with a more robust pattern that just ensures DeleteMarker is
referenced in the result handling (e.g., grep -q
"isset(\\\$result\\['DeleteMarker'\\])" or grep -q "DeleteMarker" against the s3
manager to avoid exact formatting dependence), and tighten the broad grep for
'try {' so it only matches the try block that hardens civil-photo removal by
scoping the search to the civil-photo removal routine (e.g., use a PCRE/
multiline search that looks for a function or method name containing "civil" or
"remove" followed soon after by "try {"), while keeping the existing greps for
candidate_civil_need_verification and 'Invalid civil ID or expiry date' intact.
Ensure you reference the same symbols (DeleteMarker,
candidate_civil_need_verification, 'Invalid civil ID or expiry date', and the
'try {' try-block) when updating the three grep checks.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: af91ee6d-3c5e-4120-928d-fea2ccab241f

📥 Commits

Reviewing files that changed from the base of the PR and between 7b023ff and da3107b.

📒 Files selected for processing (6)
  • candidate/modules/v1/controllers/AccountController.php
  • common/components/S3ResourceManager.php
  • common/config/main.php
  • common/models/Candidate.php
  • environments/prod-railway/common/config/main-local.php
  • tests/check-s3-civil-id-hardening.sh

Comment thread candidate/modules/v1/controllers/AccountController.php
Comment thread candidate/modules/v1/controllers/AccountController.php Outdated
Comment thread common/config/main.php Outdated
Comment thread environments/prod-railway/common/config/main-local.php Outdated
@sureshchouksey8
Copy link
Copy Markdown
Author

Maintainer-facing update: the CodeRabbit S3/Civil ID findings are addressed on the branch. The current code now fails fast when Civil ID copy/verification fails, returns null for missing S3 credential env vars instead of empty strings, and keeps the regression guard covering the Civil ID upload/remove and S3 credential paths. Validation run locally: sh tests/check-s3-civil-id-hardening.sh && git diff --check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant