Skip to content

Address PR #119 review feedback: NO_COLOR compliance, naming, and test coverage#123

Merged
abhimehro merged 9 commits intosentinel/secure-env-permissions-638384298251323176from
copilot/address-pr-comments
Jan 22, 2026
Merged

Address PR #119 review feedback: NO_COLOR compliance, naming, and test coverage#123
abhimehro merged 9 commits intosentinel/secure-env-permissions-638384298251323176from
copilot/address-pr-comments

Conversation

Copy link

Copilot AI commented Jan 22, 2026

Summary: Address PR #119 Review Comments

All review comments from PR #119 have been successfully addressed:

Code Quality & Linting Issues ✅

  • Fix naming conventions
  • Fix line-too-long issues
  • Use robust octal formatting
  • Clean up trailing whitespace
  • Move imports to module level
  • Remove all unused imports

NO_COLOR Compliance ✅

  • Move security warning to respect NO_COLOR setting
  • Security warnings use Colors.WARNING and Colors.ENDC

Test Coverage ✅

  • Tests now use pytest.mark.skipif for Windows instead of silent passes
  • Tests verify actual implementation from main.py (not duplicated logic)
  • Error handling properly tested by mocking os.stat
  • All unused imports removed
  • Helper function removed in favor of testing actual code

Validation ✅

  • All 13 tests pass (6 security + 7 existing)
  • Code review completed - no issues found
  • CodeQL security check (0 alerts)

Latest Changes

main.py:

  • Extracted check_env_permissions() function for testability
  • No behavioral changes, just better code organization

tests/test_security.py:

  • Use pytest.mark.skipif for Windows-incompatible tests
  • Import and test actual check_env_permissions() from main.py
  • Mock os.stat to properly test error handling
  • Removed helper function that duplicated logic
  • Removed all unused imports (patch, tempfile, mock_open)
Original prompt

Hi @copilot, could you please apply any changes based on the comments in the thread for this Pull Request: #119? Thank you!


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@trunk-io
Copy link

trunk-io bot commented Jan 22, 2026

🚫 This pull request was closed by Abhi Mehrotra (@abhimehro), so it was removed from the merge queue. See more details here.

Copilot AI and others added 3 commits January 22, 2026 11:21
- Moved security check after Colors class definition to respect NO_COLOR
- Fixed naming conventions: st -> file_stat, e -> error, exc_type -> exception_type
- Fixed line-too-long issues by breaking into multiple lines
- Use robust octal formatting: format(stat.S_IMODE(), '03o')
- Added comprehensive tests for security features

Co-authored-by: abhimehro <84992105+abhimehro@users.noreply.github.com>
- Extract common permission check logic into helper function
- Reduces duplication across test methods

Co-authored-by: abhimehro <84992105+abhimehro@users.noreply.github.com>
Co-authored-by: abhimehro <84992105+abhimehro@users.noreply.github.com>
Co-authored-by: abhimehro <84992105+abhimehro@users.noreply.github.com>
Copilot AI changed the title [WIP] Apply changes based on comments in PR #119 Address PR #119 review feedback: NO_COLOR compliance, naming, and test coverage Jan 22, 2026
@abhimehro abhimehro marked this pull request as ready for review January 22, 2026 11:28
Copilot AI review requested due to automatic review settings January 22, 2026 11:28
Copilot AI requested a review from abhimehro January 22, 2026 11:28
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request addresses code review feedback from PR #119 by improving NO_COLOR compliance, enhancing code quality through better naming conventions, and adding security-focused test coverage for .env file permission checks.

Changes:

  • Moved .env permission check after Colors class initialization to properly respect the NO_COLOR environment variable
  • Improved variable naming and code formatting (st → file_stat, e → error, exc_type → exception_type, multi-line strings)
  • Added comprehensive security tests in a new test file covering permission checks, error handling, and platform-specific behavior

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.

File Description
main.py Relocated security warning code to respect NO_COLOR; improved naming and octal permission formatting
tests/test_security.py New test file with 6 tests for security features in main.py and fix_env.py

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +103 to +128
def test_fix_env_sets_secure_permissions(tmp_path, monkeypatch):
"""Test that fix_env.py sets secure permissions on .env file."""
# Change to temp directory
monkeypatch.chdir(tmp_path)

# Create a .env file with insecure content
env_file = tmp_path / ".env"
env_file.write_text("TOKEN='test_token'\nPROFILE='test_profile'\n")

if os.name != 'nt': # Skip on Windows
# Set insecure permissions initially
os.chmod(env_file, 0o644)

# Run fix_env
fix_env.fix_env()

# Check that permissions are now secure
file_stat = os.stat(env_file)
mode = stat.S_IMODE(file_stat.st_mode)

# Verify permissions are 600 (read/write for owner only)
assert mode == 0o600, f"Expected 600, got {oct(mode)}"

# Verify no group or other permissions
assert not (file_stat.st_mode & stat.S_IRWXG), "Group has permissions"
assert not (file_stat.st_mode & stat.S_IRWXO), "Others have permissions"
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

On Windows (when os.name == 'nt'), this test does nothing and silently passes. The entire test logic is inside the if os.name != 'nt': block, so on Windows the test function runs but performs no assertions. Consider using pytest.mark.skipif decorator to explicitly skip Windows instead of having conditional test logic that makes the test silently pass without testing anything.

Copilot uses AI. Check for mistakes.
Comment on lines +13 to +30
def _check_env_permissions_and_warn(env_file_path, mock_stderr):
"""
Helper function that replicates the permission check logic from main.py.
This is used in tests to verify the behavior without importing main.py.
"""
file_stat = os.stat(env_file_path)
if file_stat.st_mode & (stat.S_IRWXG | stat.S_IRWXO):
platform_hint = (
"Please secure your .env file so it is only readable by "
"the owner."
)
if os.name != "nt":
platform_hint += " For example: 'chmod 600 .env'."
perms = format(stat.S_IMODE(file_stat.st_mode), '03o')
mock_stderr.write(
f"⚠️ Security Warning: .env file is "
f"readable by others ({perms})! {platform_hint}\n"
)
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

The helper function _check_env_permissions_and_warn doesn't match the actual implementation in main.py. The main.py code uses Colors.WARNING and Colors.ENDC for formatting (lines 111-113 in main.py), but this helper function omits those color codes. This means the tests aren't accurately verifying the actual behavior of the security warnings in main.py.

Copilot uses AI. Check for mistakes.
Comment on lines +79 to +100
def test_env_permission_check_handles_stat_error(monkeypatch):
"""Test that permission check handles stat() errors gracefully."""
# Mock sys.stderr to capture warnings
mock_stderr = MagicMock()
monkeypatch.setattr(sys, "stderr", mock_stderr)

# Simulate a permission error
try:
raise PermissionError("Cannot access file")
except Exception as error:
exception_type = type(error).__name__
sys.stderr.write(
f"⚠️ Security Warning: Could not check .env "
f"permissions ({exception_type}: {error})\n"
)

# Verify error warning was written
mock_stderr.write.assert_called()
call_args = mock_stderr.write.call_args[0][0]
assert "Security Warning" in call_args
assert "Could not check .env permissions" in call_args
assert "PermissionError" in call_args
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

This test doesn't actually test the error handling in main.py's permission check code. It simulates an error by raising and catching an exception directly, then writing to stderr. To properly test the error handling, the test should mock os.stat to raise an exception and then verify that the actual permission check code in main.py handles it correctly. Consider importing the relevant code from main.py or restructuring main.py to make the permission check logic testable.

Copilot uses AI. Check for mistakes.
Comment on lines +33 to +56
def test_env_permission_check_warns_on_insecure_permissions(monkeypatch, tmp_path):
"""Test that insecure .env permissions trigger a warning."""
# Create a temporary .env file
env_file = tmp_path / ".env"
env_file.write_text("TOKEN=test")

# Set insecure permissions (readable by others)
if os.name != 'nt': # Skip on Windows
os.chmod(env_file, 0o644)

# Mock sys.stderr to capture warnings
mock_stderr = MagicMock()
monkeypatch.setattr(sys, "stderr", mock_stderr)

# Run the permission check logic
_check_env_permissions_and_warn(env_file, mock_stderr)

# Verify warning was written
mock_stderr.write.assert_called()
call_args = mock_stderr.write.call_args[0][0]
assert "Security Warning" in call_args
assert "readable by others" in call_args
assert "644" in call_args

Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

On Windows (when os.name == 'nt'), this test does nothing and silently passes. The entire test logic is inside the if os.name != 'nt': block, so on Windows the test function runs but performs no assertions. Consider using pytest.mark.skipif decorator to explicitly skip Windows instead of having conditional test logic that makes the test silently pass without testing anything.

Copilot uses AI. Check for mistakes.
Comment on lines +58 to +76
def test_env_permission_check_no_warn_on_secure_permissions(monkeypatch, tmp_path):
"""Test that secure .env permissions do not trigger a warning."""
# Create a temporary .env file
env_file = tmp_path / ".env"
env_file.write_text("TOKEN=test")

# Set secure permissions (readable only by owner)
if os.name != 'nt': # Skip on Windows
os.chmod(env_file, 0o600)

# Mock sys.stderr to capture warnings
mock_stderr = MagicMock()
monkeypatch.setattr(sys, "stderr", mock_stderr)

# Run the permission check logic
_check_env_permissions_and_warn(env_file, mock_stderr)

# Verify no warning was written
mock_stderr.write.assert_not_called()
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

On Windows (when os.name == 'nt'), this test does nothing and silently passes. The entire test logic is inside the if os.name != 'nt': block, so on Windows the test function runs but performs no assertions. Consider using pytest.mark.skipif decorator to explicitly skip Windows instead of having conditional test logic that makes the test silently pass without testing anything.

Copilot uses AI. Check for mistakes.
abhimehro and others added 2 commits January 22, 2026 05:38
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Owner

@abhimehro abhimehro left a comment

Choose a reason for hiding this comment

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

Hi @copilot, please apply any changes based on the following suggestions:

  • Lines +77 to +98 of tests/test_security.py: “This test doesn't actually test the error handling in main.py's permission check code. It simulates an error by raising and catching an exception directly, then writing to stderr. To properly test the error handling, the test should mock os.stat to raise an exception and then verify that the actual permission check code in main.py handles it correctly. Consider importing the relevant code from main.py or restructuring main.py to make the permission check logic testable.”

  • Lines +11 to +28 of tests/test_security.py: “The helper function _check_env_permissions_and_warn doesn't match the actual implementation in main.py. The main.py code uses Colors.WARNING and Colors.ENDC for formatting (lines 111-113 in main.py), but this helper function omits those color codes. This means the tests aren't accurately verifying the actual behavior of the security warnings in main.py.”

  • Lines +31 to +54 of tests/test_security.py: “On Windows (when os.name == 'nt'), this test does nothing and silently passes. The entire test logic is inside the if os.name != 'nt': block, so on Windows the test function runs but performs no assertions. Consider using pytest.mark.skipif decorator to explicitly skip Windows instead of having conditional test logic that makes the test silently pass without testing anything.”

  • Lines +77 to +98 of tests/test_security.py: “This test doesn't actually test the error handling in main.py's permission check code. It simulates an error by raising and catching an exception directly, then writing to stderr. To properly test the error handling, the test should mock os.stat to raise an exception and then verify that the actual permission check code in main.py handles it correctly. Consider importing the relevant code from main.py or restructuring main.py to make the permission check logic testable.”

  • Lines +56 to +74 of tests/test_security.py: “On Windows (when os.name == 'nt'), this test does nothing and silently passes. The entire test logic is inside the if os.name != 'nt': block, so on Windows the test function runs but performs no assertions. Consider using pytest.mark.skipif decorator to explicitly skip Windows instead of having conditional test logic that makes the test silently pass without testing anything.”

Thank you!

Copilot AI and others added 2 commits January 22, 2026 11:55
- Extract check_env_permissions() function in main.py for testability
- Use pytest.mark.skipif for Windows-specific tests instead of conditional logic
- Test actual implementation from main.py instead of duplicating logic
- Mock os.stat to properly test error handling
- Remove unused imports (tempfile, patch, mock_open)
- Tests now accurately verify behavior with Colors.WARNING/ENDC

Co-authored-by: abhimehro <84992105+abhimehro@users.noreply.github.com>
Co-authored-by: abhimehro <84992105+abhimehro@users.noreply.github.com>
Copy link
Author

Copilot AI commented Jan 22, 2026

Hi @copilot, please apply any changes based on the following suggestions:

  • Lines +77 to +98 of tests/test_security.py: “This test doesn't actually test the error handling in main.py's permission c...

Changes applied in commit e8f3062:

  • Extracted testable function: Created check_env_permissions() in main.py for better testability
  • Fixed Windows test behavior: Added @pytest.mark.skipif decorators to Unix-specific tests instead of conditional logic that silently passed
  • Test actual implementation: Tests now import and verify the real check_env_permissions() function with proper Colors.WARNING/ENDC formatting
  • Proper error handling test: Mock os.stat to raise exceptions and verify error handling in actual code
  • Removed unused imports: Cleaned up tempfile, patch, and mock_open imports
  • Removed duplicate logic: Eliminated helper function that replicated main.py code

All 13 tests pass, CodeQL scan clean with 0 alerts.

@abhimehro abhimehro enabled auto-merge (squash) January 22, 2026 12:18
@abhimehro abhimehro merged commit 29408b7 into sentinel/secure-env-permissions-638384298251323176 Jan 22, 2026
7 checks passed
@abhimehro abhimehro deleted the copilot/address-pr-comments branch January 22, 2026 12:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants