Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(policy): allow auth(). calls in filter functions #1771

Merged
merged 3 commits into from
Oct 10, 2024
Merged

Conversation

ymc9
Copy link
Member

@ymc9 ymc9 commented Oct 10, 2024

Fixes #1745

Copy link
Contributor

coderabbitai bot commented Oct 10, 2024

📝 Walkthrough

Walkthrough

The pull request introduces several modifications to the validation logic within the schema language server. Key changes include the refactoring of the ExpressionValidator and FunctionInvocationValidator classes to utilize an imported function, isAuthOrAuthMemberAccess, enhancing code maintainability. Additionally, new tests have been added to cover various validation scenarios, including attribute validation and regression testing for a specific issue. The changes do not alter existing validation rules or error handling mechanisms.

Changes

File Path Change Summary
packages/schema/src/language-server/validator/expression-validator.ts Removed private method isAuthOrAuthMemberAccess, added import for the same function, updated isNotModelFieldExpr.
packages/schema/src/language-server/validator/function-invocation-validator.ts Added import for isAuthOrAuthMemberAccess, updated validation logic for second argument in validate method.
packages/schema/src/language-server/validator/utils.ts Added isAuthOrAuthMemberAccess function and imported isAuthInvocation.
packages/schema/tests/schema/validation/attribute-validation.test.ts Added tests for various model attributes and behaviors.
tests/integration/tests/e2e/filter-function-coverage.test.ts Added test case for contains function with auth().
tests/regression/tests/issue-1745.test.ts Introduced regression test for issue 1745, ensuring schema loads correctly into PostgreSQL.

Assessment against linked issues

Objective Addressed Explanation
Implement permission control for users with polymorphic roles (#1745)
Replace hardcoded values with dynamic field references (#1745) The changes do not include dynamic field replacement.
Ensure access control based on user roles and attributes (#1745)

Possibly related PRs


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@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: 2

🧹 Outside diff range and nitpick comments (6)
tests/regression/tests/issue-1745.test.ts (1)

1-4: Consider using a more descriptive test name

The current test name 'regression' is quite generic. To improve clarity and maintainability, consider using a more descriptive name that reflects the specific issue being tested, such as 'allows auth() calls in filter functions'.

- it('regression', async () => {
+ it('allows auth() calls in filter functions', async () => {
packages/schema/src/language-server/validator/utils.ts (3)

17-17: Approve new import, but consider removing unused import.

The import of isAuthInvocation is correctly added and used in the new function. However, the resolved import doesn't appear to be used in the visible changes of this file.

Consider removing the unused import:

-import { isAuthInvocation, resolved } from '@zenstackhq/sdk';
+import { isAuthInvocation } from '@zenstackhq/sdk';

186-188: Approve new function, suggest adding documentation.

The isAuthOrAuthMemberAccess function correctly implements the logic to allow auth(). calls in filter functions, as per the PR objectives. It handles both direct auth invocations and nested member access expressions, which is crucial for implementing dynamic permission controls based on user roles and types.

Consider adding a brief documentation comment to explain the function's purpose and behavior:

+/**
+ * Checks if the given expression is an auth invocation or a member access to an auth invocation.
+ * This function allows for nested member access expressions, supporting complex auth checks.
+ * @param expr The expression to check
+ * @returns True if the expression is an auth invocation or a member access to an auth invocation
+ */
export function isAuthOrAuthMemberAccess(expr: Expression): boolean {
    return isAuthInvocation(expr) || (isMemberAccessExpr(expr) && isAuthOrAuthMemberAccess(expr.operand));
}

Line range hint 1-188: Summary: Changes successfully implement PR objectives

The modifications to this file effectively address the PR objectives by introducing the isAuthOrAuthMemberAccess function. This addition allows for more flexible and dynamic permission controls based on user roles and types, specifically enabling auth(). calls in filter functions.

The changes are minimal, focused, and don't affect existing functionality, ensuring backward compatibility. The implementation is correct and aligns well with the requirements outlined in the linked issue #1745.

As the codebase evolves, consider the following to maintain and improve the authorization system:

  1. Document the new authorization capabilities in the project's documentation to help developers understand and utilize these features correctly.
  2. Consider creating unit tests specifically for the isAuthOrAuthMemberAccess function to ensure its behavior remains correct as the codebase evolves.
  3. Monitor the usage of this new feature in real-world scenarios to identify any potential performance impacts or edge cases that may need further optimization or handling.
packages/schema/src/language-server/validator/expression-validator.ts (1)

299-299: LGTM: Consistent handling of auth(). calls

The use of the imported isAuthOrAuthMemberAccess function maintains the existing functionality while allowing for consistent handling of auth(). calls across the codebase. This change supports the PR objectives of enabling auth(). calls in filter functions.

Consider updating the comment to reflect the more general nature of the check:

-            // `auth()` access
+            // `auth()` or `auth().` member access
             isAuthOrAuthMemberAccess(expr) ||
packages/schema/src/language-server/validator/function-invocation-validator.ts (1)

123-129: Consider Adding Unit Tests for the New Validation Logic

To ensure the extended validation logic functions correctly with auth() expressions, please consider adding unit tests that cover scenarios involving auth(). expressions in both singular and array forms.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 374e962 and 7d1a525.

📒 Files selected for processing (6)
  • packages/schema/src/language-server/validator/expression-validator.ts (2 hunks)
  • packages/schema/src/language-server/validator/function-invocation-validator.ts (2 hunks)
  • packages/schema/src/language-server/validator/utils.ts (2 hunks)
  • packages/schema/tests/schema/validation/attribute-validation.test.ts (4 hunks)
  • tests/integration/tests/e2e/filter-function-coverage.test.ts (1 hunks)
  • tests/regression/tests/issue-1745.test.ts (1 hunks)
🧰 Additional context used
🔇 Additional comments (15)
tests/regression/tests/issue-1745.test.ts (4)

5-7: LGTM: Proper database setup and teardown

The creation and cleanup of the test database are handled correctly. The use of a try-finally block ensures that the database is always dropped, even if the test fails, which is a good practice for test isolation and resource management.

Also applies to: 94-97


10-90: LGTM: Implemented auth(). calls in access control rules

The schema successfully implements auth(). calls in the access control rules, particularly in the Ad model. This aligns with the PR objective of allowing auth(). calls in filter functions and enables more dynamic permission controls based on user roles and types.


8-93: LGTM: Appropriate schema loading for testing

The schema loading process is well-implemented for a test environment. Using the loadSchema function with pushDb: false ensures that the schema can be validated without making actual changes to the database, which is ideal for testing purposes.


1-98: Overall implementation successfully addresses PR objectives

This regression test file effectively addresses the main objectives of the PR:

  1. It implements auth(). calls in filter functions, particularly in the access control rules.
  2. It provides a framework for testing polymorphic roles and dynamic permission controls.

The test structure, database handling, and schema definition are well-implemented. Minor suggestions for improvement have been made, including:

  1. Using a more descriptive test name.
  2. Considering the addition of an optional buyerType field in the Company model for increased flexibility.

These changes would further enhance the test's clarity and the schema's ability to handle polymorphic roles as requested in issue #1745.

tests/integration/tests/e2e/filter-function-coverage.test.ts (2)

39-59: Excellent addition of the 'contains with auth()' test case.

This new test case effectively demonstrates the use of auth(). calls in filter functions, which directly aligns with the PR objectives. It covers both positive and negative scenarios, ensuring that the policy works as expected when the string field contains the authenticated user's name.

The test structure is consistent with other tests in the file, and the assertions logically cover the expected behavior. This addition significantly contributes to the overall coverage of filter functions and validates the new feature.


Line range hint 1-60: Overall, the changes to this file are well-implemented and valuable.

The addition of the 'contains with auth()' test case complements the existing tests for other filter functions. It maintains the file's consistent structure and testing approach while enhancing the overall test coverage. This change effectively supports the PR's objective of allowing auth(). calls in filter functions.

packages/schema/src/language-server/validator/expression-validator.ts (2)

27-27: LGTM: Improved code organization

The import of isAuthOrAuthMemberAccess from a separate utility file enhances code organization and reusability. This change aligns well with the PR objectives of allowing auth(). calls in filter functions.


Line range hint 1-303: Summary: Successful implementation of auth(). call support

The changes in this file effectively support the PR objectives of allowing auth(). calls in filter functions. The modifications improve code organization by moving the isAuthOrAuthMemberAccess function to a utility file and using it consistently within the ExpressionValidator class. These changes maintain the existing validation logic while enhancing the flexibility of authorization checks in filter functions.

To fully validate the impact of these changes:

Run the following script to check for any unintended side effects or usage of the old implementation:

This script will help ensure that the changes have been consistently applied across the codebase and that there are no remaining issues related to auth() calls in filter functions.

packages/schema/src/language-server/validator/function-invocation-validator.ts (3)

29-29: Importing isAuthOrAuthMemberAccess Correctly

The import statement for isAuthOrAuthMemberAccess from './utils' is correctly added, allowing the validation logic to utilize this function.


112-113: Extending Validation to Include auth() Expressions

The addition of !isAuthOrAuthMemberAccess(secondArg) in the validation logic appropriately extends the criteria to accept expressions starting with auth() as valid second arguments. This aligns with the PR objective to allow auth(). calls in filter functions.


123-129: Updating Error Message to Reflect New Validation Rules

The error message now accurately informs users that the second argument must be a literal, an enum, an expression starting with auth()., or an array of them. This provides clearer guidance and improves developer experience when addressing validation errors.

packages/schema/tests/schema/validation/attribute-validation.test.ts (4)

819-822: Appropriate addition of e field in User model

The inclusion of the e field of enum type E in the User model is necessary for testing policy expressions involving auth().e.


848-848: Correct use of auth().e in the has function

Using auth().e within the has(es, auth().e) function accurately tests the new functionality that allows auth(). calls in filter functions.


899-901: Updated error message reflects auth(). expressions

The error message now includes auth(). expressions as acceptable second arguments, aligning with the enhanced validation logic.


1033-1035: Consistent error message update to include auth(). expressions

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.

1 participant