Skip to content

Conversation

@ymc9
Copy link
Member

@ymc9 ymc9 commented Sep 19, 2024

Fixes #1710

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 19, 2024

Walkthrough

Walkthrough

The changes introduced in this pull request enhance the functionality of the delegate proxy handler and related components by implementing methods for ensuring the selection of discriminator fields and sanitizing mutation payloads. The modifications include the addition of new methods for handling polymorphic models and improving the accuracy of field resolution in queries. Additionally, new tests have been added to validate the functionality of the @omit directive and field-level policies, ensuring that access control mechanisms are correctly enforced.

Changes

Files Change Summary
packages/runtime/src/enhancements/node/delegate.ts Added methods in DelegateProxyHandler for ensuring discriminator selection and sanitizing mutation payloads.
packages/runtime/src/enhancements/node/omit.ts Introduced a QueryUtils dependency in OmitHandler, modifying the constructor and doPostProcess method to improve field resolution accuracy.
packages/runtime/src/enhancements/node/policy/policy-utils.ts Updated doPostProcessForRead to determine the concrete model for polymorphic entities, enhancing policy application.
packages/runtime/src/enhancements/node/query-utils.ts Added getDelegateConcreteModel method to QueryUtils for determining the appropriate concrete model based on provided data, improving handling of polymorphic models.
packages/schema/src/res/stdlib.zmodel Minor correction in documentation comments for the nanoid function.
tests/integration/tests/enhancements/with-delegate/omit-interaction.test.ts New tests for the @omit directive functionality in polymorphic models, validating that omitted fields are excluded from queries.
tests/integration/tests/enhancements/with-delegate/policy-interaction.test.ts Added tests to verify field-level policies in a user and asset management schema, ensuring correct access control.
tests/integration/tests/enhancements/with-delegate/validation.test.ts New tests to validate polymorphic input in a database schema, ensuring auxiliary fields cannot be directly modified in mutations.
tests/regression/tests/issue-1710.test.ts Introduced a regression test for access control on polymorphic models, confirming that sensitive fields remain undefined based on permissions.

Assessment against linked issues

Objective Addressed Explanation
Ensure delegate relational fields are included in model metadata (1710)
Validate that omitted fields are excluded in queries (1710)
Enforce field-level policies in polymorphic models (1710)

Possibly related issues

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: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between f2a3686 and c219f6d.

Files ignored due to path filters (2)
  • packages/runtime/package.json is excluded by !**/*.json
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml, !**/*.yaml
Files selected for processing (9)
  • packages/runtime/src/enhancements/node/delegate.ts (10 hunks)
  • packages/runtime/src/enhancements/node/omit.ts (3 hunks)
  • packages/runtime/src/enhancements/node/policy/policy-utils.ts (1 hunks)
  • packages/runtime/src/enhancements/node/query-utils.ts (1 hunks)
  • packages/schema/src/res/stdlib.zmodel (1 hunks)
  • tests/integration/tests/enhancements/with-delegate/omit-interaction.test.ts (1 hunks)
  • tests/integration/tests/enhancements/with-delegate/policy-interaction.test.ts (1 hunks)
  • tests/integration/tests/enhancements/with-delegate/validation.test.ts (1 hunks)
  • tests/regression/tests/issue-1710.test.ts (1 hunks)
Files skipped from review due to trivial changes (1)
  • packages/schema/src/res/stdlib.zmodel
Additional comments not posted (28)
tests/integration/tests/enhancements/with-delegate/validation.test.ts (2)

2-26: Test suite name accurately describes its purpose.

The test suite name "Polymorphic input validation" clearly conveys the intent of the tests within it, which is to validate polymorphic input.


3-25: Test case correctly validates the rejection of auxiliary fields in mutations.

The test case sets up the schema with the Asset and Post models using the delegate pattern, creates a Post instance, and attempts to update the corresponding Asset instance by directly modifying the delegate_aux_post field. It correctly expects the update operation to fail with the specific error message "Auxiliary relation field "delegate_aux_post" cannot be set directly".

This test case is crucial for ensuring that the system maintains the integrity of the polymorphic relationship and prevents potential data corruption by rejecting direct modifications to auxiliary fields during mutations.

tests/regression/tests/issue-1710.test.ts (5)

4-25: Schema definition looks good!

The schema definition aligns with the PR objectives and follows best practices:

  • The Profile model serves as a base with common fields and annotations.
  • The User model extends Profile and adds fields with appropriate access control directives.
  • The Organization model extends Profile without adding any fields.
  • The @@delegate(type) and @@allow('read,create', true) annotations are used correctly.

The schema structure is clear and well-defined, enabling testing of access control mechanisms for polymorphic sub-models.


27-32: User creation and field access assertions are correct!

The test case correctly creates a new user with sensitive fields and asserts that the email and password fields are undefined in the created user object. This aligns with the PR objectives of ensuring that the @deny('read', true) and @omit directives are enforced during user creation.

The test case follows best practices for creating test data and making assertions.


34-36: User retrieval and field access assertions are correct!

The test case correctly retrieves the user by their profile ID and asserts that the email and password fields are undefined in the retrieved user object. This aligns with the PR objectives of ensuring that the @deny('read', true) and @omit directives are enforced during user retrieval.

The test case follows best practices for querying data and making assertions.


38-51: User update attempt and error expectation are correct!

The test case correctly attempts to update the user's role using db.profile.update with the delegate_aux_user field and the update operation. This aligns with the PR objectives of ensuring that the @deny('read,update', true) directive prevents updating the role field.

The expect statement correctly verifies that the expected error with the message 'Auxiliary relation field' is thrown, indicating that the access control mechanism is functioning as intended.

The test case follows best practices for attempting updates and expecting errors.


2-53: The test case is well-written and aligns with the PR objectives!

The test case in issue-1710.test.ts thoroughly covers the essential aspects of the PR objectives:

  • It verifies the enforcement of @omit and @deny directives during user creation, retrieval, and update.
  • The schema definition, test data creation, assertions, and error expectations are all correct and follow best practices.
  • The test case provides adequate coverage for the access control mechanisms related to polymorphic sub-models.
  • It ensures that sensitive fields are not exposed and that unauthorized updates are prevented.

The test case is well-structured, maintainable, and extensible. It serves as a solid regression test for the issues addressed in this PR.

Great job on writing a comprehensive test case!

packages/runtime/src/enhancements/node/omit.ts (5)

8-8: LGTM!

The import statement for QueryUtils is correctly added.


25-26: LGTM!

The queryUtils property is correctly declared in the OmitHandler class.


29-29: LGTM!

The queryUtils property is correctly initialized in the constructor.


74-75: LGTM!

The getDelegateConcreteModel method is correctly used to retrieve the concrete model associated with the entity data.


77-77: LGTM!

The resolveField function is correctly used to retrieve the field information based on the model metadata and the concrete model.

tests/integration/tests/enhancements/with-delegate/omit-interaction.test.ts (4)

29-40: LGTM!

The test case correctly validates the behavior of the @omit directive when querying a concrete model (Post). It ensures that the foo and bar fields, which are marked with @omit, are undefined in the query results.


42-54: LGTM!

The test case correctly validates the behavior of the @omit directive when querying a base model (Asset). It ensures that the foo and bar fields, which are marked with @omit, are undefined in the query results, while the title field remains accessible.


56-73: LGTM!

The test case correctly validates the behavior of the @omit directive when the discriminator is not selected in the query. It ensures that the foo and bar fields, which are marked with @omit, are undefined in the query results even when the discriminator field is not explicitly selected.


75-90: LGTM!

The test case correctly validates the behavior of the @omit directive when querying in a nested context. It ensures that the foo and bar fields, which are marked with @omit, are undefined in the query results when fetching the related assets (polymorphic Asset records) through the User model, while the title field remains accessible.

packages/runtime/src/enhancements/node/query-utils.ts (1)

218-234: LGTM!

The new getDelegateConcreteModel function is a valuable addition to the QueryUtils class. It correctly determines the concrete model name based on the provided model string and associated data, handling polymorphic models effectively.

The function follows a clear logic:

  1. It checks if the data parameter is valid and of type object. If not, it returns the original model name.
  2. If the data is valid, it retrieves model information using getModelInfo, looking for a discriminator property.
  3. If a discriminator is present and the corresponding concrete model name is found in the data, that name is returned.
  4. If no concrete model is identified, it defaults to returning the original model name.

This ensures that the appropriate concrete model is selected based on the discriminator field in the data, while gracefully handling cases where the data is invalid or the discriminator is not found.

Overall, this enhancement improves the handling of polymorphic models in the QueryUtils class.

tests/integration/tests/enhancements/with-delegate/policy-interaction.test.ts (1)

272-311: Excellent test case for validating field-level policy enforcement!

This test case effectively validates the enforcement of field-level policies based on the user's ID. It covers the following scenarios:

  1. User with ID 1 can access both the foo and bar fields of the Post model.
  2. User with ID 2 can create a post, but the foo and bar fields are restricted and return undefined when accessed.

The test case ensures that the access control mechanisms are functioning as intended, with users having the appropriate permissions being able to access the restricted fields, while users without permissions receive undefined values.

Great job in covering the different scenarios and asserting the expected behavior!

packages/runtime/src/enhancements/node/policy/policy-utils.ts (1)

1384-1387: The changes look good! Here's some additional context:

The updated implementation introduces a step to determine the concrete model when the data is a polymorphic entity. This is achieved by calling getDelegateConcreteModel, which retrieves the appropriate model based on the provided data.

Consequently, doPostProcessForRead is now called with the concrete model instead of the original one. This change enhances the flexibility and accuracy of the policy application, ensuring that the correct model is utilized during the read operation, particularly in scenarios involving polymorphism.

packages/runtime/src/enhancements/node/delegate.ts (9)

5-5: Import 'traverse' Module

You've added the import statement for the 'traverse' module. Ensure that 'traverse' is properly added to your project's dependencies to avoid runtime errors.


81-83: Include Discriminator Field in Find Operations

By adding this.ensureDiscriminatorSelection(model, args); in the doFind method, you're ensuring that the discriminator field is included in selection arguments. This is crucial for correctly determining the concrete model type during post-processing.


362-363: Sanitize Mutation Payload in 'create' Method

Adding this.sanitizeMutationPayload(args.data); ensures that auxiliary relation fields prefixed with DELEGATE_AUX_RELATION_PREFIX cannot be set directly during creation. This is important for maintaining data integrity and preventing unauthorized mutations.


379-396: Ensure Proper Handling in 'sanitizeMutationPayload' Method

The sanitizeMutationPayload method traverses the mutation payload to detect any attempt to set auxiliary relation fields directly. This prevents unintended data manipulation. Ensure that this method efficiently handles large or deeply nested payloads to avoid performance bottlenecks.


409-410: Sanitize Mutation Payload in 'createMany' Method

Including this.sanitizeMutationPayload(args.data); in the createMany method ensures that batch creations do not allow direct setting of auxiliary relation fields. This reinforces data integrity across bulk operations.


450-451: Sanitize Mutation Payload in 'createManyAndReturn' Method

By adding this.sanitizeMutationPayload(args.data);, you ensure that auxiliary relation fields are not improperly set during createManyAndReturn operations, maintaining consistent data validation.


638-639: Sanitize Mutation Payload in 'update' Method

Incorporating this.sanitizeMutationPayload(args.data); into the update method prevents direct manipulation of auxiliary relation fields during updates, safeguarding against potential data corruption.


659-660: Sanitize Mutation Payload in 'updateMany' Method

Adding this.sanitizeMutationPayload(args.data); to the updateMany method ensures that bulk updates adhere to data integrity rules by disallowing direct setting of auxiliary relation fields.


688-690: Sanitize Mutation Payloads in 'upsert' Method

By sanitizing both args.update and args.create using this.sanitizeMutationPayload, you ensure that upsert operations cannot bypass validation checks on auxiliary relation fields, upholding data integrity.

@ymc9 ymc9 merged commit 57652a1 into dev Sep 19, 2024
13 checks passed
@ymc9 ymc9 deleted the fix/issue-1710 branch September 19, 2024 23:48
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.

2 participants