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

Optimize myPrivileges #4794

Merged
merged 10 commits into from
Dec 21, 2024
Merged

Optimize myPrivileges #4794

merged 10 commits into from
Dec 21, 2024

Conversation

valentinyanakiev
Copy link
Member

@valentinyanakiev valentinyanakiev commented Dec 18, 2024

  • refactored code to be faster
  • dropped JSON conversions, converted auth policies to be JSON in mySQL

my benchmarking shows 2/3x faster execution

Summary by CodeRabbit

  • New Features

    • Enhanced authorization logic for improved validation and error handling.
    • Updated JSON structure for user data, providing clearer representation of rules.
  • Bug Fixes

    • Fixed issues with rule handling by transitioning from strings to structured arrays.
  • Documentation

    • Updated method signatures and property types to reflect changes in authorization policy structure.
  • Tests

    • Improved test coverage for authorization policy updates and space sorting functionality.
  • Chores

    • Migration added to update database schema for authorization policy rules.

Copy link
Contributor

coderabbitai bot commented Dec 18, 2024

Walkthrough

The pull request introduces significant refactoring to the authorization system, focusing on transforming how authorization policies handle rules. The changes primarily involve converting rule-related properties from string representations to structured array types across multiple files. The modifications enhance type safety, improve data handling, and simplify the authorization logic by removing unnecessary conversion methods and directly working with array-based rule structures.

Changes

File Change Summary
src/core/authorization/authorization.service.ts - Refactored validateAuthorization and isAccessGranted methods
- Simplified rule handling and removed conversion methods
- Updated method signatures with explicit return types
src/domain/common/authorization-policy/* - Updated AuthorizationPolicy entity and interface
- Changed rule properties from string to typed arrays
- Modified service methods to work with array-based rules
test/data/user.json - Converted rule fields from string to structured JSON arrays
- Updated authorization and profile sections
src/migrations/1734708463444-credentialRules.ts - Added migration to update database schema
- Converted rule columns to JSON type

Suggested Reviewers

  • valentinyanakiev

Possibly Related PRs

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request. We would love to hear your feedback on Discord.


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:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • 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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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.

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

🧹 Nitpick comments (1)
src/domain/common/authorization-policy/authorization.policy.entity.ts (1)

15-22: Consider adding data validation in service layer

Since the columns are nullable and using JSON type, consider implementing validation in the service layer to ensure data integrity:

  1. Validate array contents before saving
  2. Handle null cases appropriately
  3. Consider adding JSON schema validation
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9108ba8 and 7ba542a.

📒 Files selected for processing (5)
  • src/core/authorization/authorization.service.ts (6 hunks)
  • src/domain/common/authorization-policy/authorization.policy.entity.ts (2 hunks)
  • src/domain/common/authorization-policy/authorization.policy.interface.ts (2 hunks)
  • src/domain/common/authorization-policy/authorization.policy.service.ts (7 hunks)
  • src/migrations/1734531789437-credentialRules.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
src/migrations/1734531789437-credentialRules.ts (1)

Pattern src/**/*.{ts,js}: Review the TypeScript/JavaScript code for NestJS best practices, dependency injection, module structure, and potential bugs.

Context Files (Do Not Review):

  • docs/Design.md - Design overview of the project
  • docs/Pagination.md - Pagination design overview
  • docs/Developing.md - Development setup overview
  • docs/graphql-typeorm-usage.md - overview of GraphQL and TypeORM usage and how they are used together with NestJS in the project
  • docs/database-definitions.md - guidelines for creating TypeORM entity defnitions
  • src/core/error-handling/graphql.exception.filter.ts - GraphQL error handling
  • src/core/error-handling/http.exception.filter.ts - HTTP error handling
  • src/core/error-handling/rest.error.response.ts - REST error response
  • src/core/error-handling/unhandled.exception.filter.ts - Global exception handler

Guidelines:

  • Our project uses global exception handlers (UnhandledExceptionFilter), so avoid suggesting additional try/catch blocks unless handling specific cases.
  • Use NestJS latest documentation from https://docs.nestjs.com/ for reference on NestJS best practices.
  • Use TypeORM latest documentation from https://typeorm.io/ for reference on TypeORM best practices.
  • Refer to the design overview in the context files for better understanding.
src/core/authorization/authorization.service.ts (1)

Pattern src/**/*.{ts,js}: Review the TypeScript/JavaScript code for NestJS best practices, dependency injection, module structure, and potential bugs.

Context Files (Do Not Review):

  • docs/Design.md - Design overview of the project
  • docs/Pagination.md - Pagination design overview
  • docs/Developing.md - Development setup overview
  • docs/graphql-typeorm-usage.md - overview of GraphQL and TypeORM usage and how they are used together with NestJS in the project
  • docs/database-definitions.md - guidelines for creating TypeORM entity defnitions
  • src/core/error-handling/graphql.exception.filter.ts - GraphQL error handling
  • src/core/error-handling/http.exception.filter.ts - HTTP error handling
  • src/core/error-handling/rest.error.response.ts - REST error response
  • src/core/error-handling/unhandled.exception.filter.ts - Global exception handler

Guidelines:

  • Our project uses global exception handlers (UnhandledExceptionFilter), so avoid suggesting additional try/catch blocks unless handling specific cases.
  • Use NestJS latest documentation from https://docs.nestjs.com/ for reference on NestJS best practices.
  • Use TypeORM latest documentation from https://typeorm.io/ for reference on TypeORM best practices.
  • Refer to the design overview in the context files for better understanding.
src/domain/common/authorization-policy/authorization.policy.service.ts (1)

Pattern src/**/*.{ts,js}: Review the TypeScript/JavaScript code for NestJS best practices, dependency injection, module structure, and potential bugs.

Context Files (Do Not Review):

  • docs/Design.md - Design overview of the project
  • docs/Pagination.md - Pagination design overview
  • docs/Developing.md - Development setup overview
  • docs/graphql-typeorm-usage.md - overview of GraphQL and TypeORM usage and how they are used together with NestJS in the project
  • docs/database-definitions.md - guidelines for creating TypeORM entity defnitions
  • src/core/error-handling/graphql.exception.filter.ts - GraphQL error handling
  • src/core/error-handling/http.exception.filter.ts - HTTP error handling
  • src/core/error-handling/rest.error.response.ts - REST error response
  • src/core/error-handling/unhandled.exception.filter.ts - Global exception handler

Guidelines:

  • Our project uses global exception handlers (UnhandledExceptionFilter), so avoid suggesting additional try/catch blocks unless handling specific cases.
  • Use NestJS latest documentation from https://docs.nestjs.com/ for reference on NestJS best practices.
  • Use TypeORM latest documentation from https://typeorm.io/ for reference on TypeORM best practices.
  • Refer to the design overview in the context files for better understanding.
src/domain/common/authorization-policy/authorization.policy.interface.ts (1)

Pattern src/**/*.{ts,js}: Review the TypeScript/JavaScript code for NestJS best practices, dependency injection, module structure, and potential bugs.

Context Files (Do Not Review):

  • docs/Design.md - Design overview of the project
  • docs/Pagination.md - Pagination design overview
  • docs/Developing.md - Development setup overview
  • docs/graphql-typeorm-usage.md - overview of GraphQL and TypeORM usage and how they are used together with NestJS in the project
  • docs/database-definitions.md - guidelines for creating TypeORM entity defnitions
  • src/core/error-handling/graphql.exception.filter.ts - GraphQL error handling
  • src/core/error-handling/http.exception.filter.ts - HTTP error handling
  • src/core/error-handling/rest.error.response.ts - REST error response
  • src/core/error-handling/unhandled.exception.filter.ts - Global exception handler

Guidelines:

  • Our project uses global exception handlers (UnhandledExceptionFilter), so avoid suggesting additional try/catch blocks unless handling specific cases.
  • Use NestJS latest documentation from https://docs.nestjs.com/ for reference on NestJS best practices.
  • Use TypeORM latest documentation from https://typeorm.io/ for reference on TypeORM best practices.
  • Refer to the design overview in the context files for better understanding.
src/domain/common/authorization-policy/authorization.policy.entity.ts (1)

Pattern src/**/*.{ts,js}: Review the TypeScript/JavaScript code for NestJS best practices, dependency injection, module structure, and potential bugs.

Context Files (Do Not Review):

  • docs/Design.md - Design overview of the project
  • docs/Pagination.md - Pagination design overview
  • docs/Developing.md - Development setup overview
  • docs/graphql-typeorm-usage.md - overview of GraphQL and TypeORM usage and how they are used together with NestJS in the project
  • docs/database-definitions.md - guidelines for creating TypeORM entity defnitions
  • src/core/error-handling/graphql.exception.filter.ts - GraphQL error handling
  • src/core/error-handling/http.exception.filter.ts - HTTP error handling
  • src/core/error-handling/rest.error.response.ts - REST error response
  • src/core/error-handling/unhandled.exception.filter.ts - Global exception handler

Guidelines:

  • Our project uses global exception handlers (UnhandledExceptionFilter), so avoid suggesting additional try/catch blocks unless handling specific cases.
  • Use NestJS latest documentation from https://docs.nestjs.com/ for reference on NestJS best practices.
  • Use TypeORM latest documentation from https://typeorm.io/ for reference on TypeORM best practices.
  • Refer to the design overview in the context files for better understanding.
🔇 Additional comments (24)
src/core/authorization/authorization.service.ts (6)

89-92: Validate array format for credentialRules.
Checking if credentialRules is an array and if it's empty is consistent with the new array-based approach. This ensures proper data structure before proceeding.


126-126: Confirmed usage of authorization.credentialRules array.
This assignment correctly references the updated array-based property of credentialRules.


144-144: VerifiedCredentialRules assignment maintains consistency.
Utilizing the array property directly helps keep the code base consistent with the new data model.


166-166: PrivilegeRules usage is properly handled as an array.
Explicitly working with privilegeRules aligns with the updated interface for array-based rules.


185-216: Streamlined calculation of granted privileges.
• Using a Set to collect privileges is an efficient way to avoid duplicates.
• Checking anonymousReadAccess first ensures a simple short-circuit for read privileges.
• The array-based iteration aligns with the new credentialRules and verifiedCredentialRules data structure.
Overall, this method is well-structured and clear.


229-234: Effective array-based criteria matching in isCredentialMatch.
• The usage of “some” for satisfying any matching criteria is straightforward.
• Throwing an AuthorizationInvalidPolicyException if no criteria exist is appropriate guard logic.

src/domain/common/authorization-policy/authorization.policy.service.ts (10)

163-165: Initialize with empty arrays in reset.
Converting to arrays avoids confusion that could arise from empty strings. This ensures consistency across the codebase.


Line range hint 244-254: Appending new credential rule directly to array.
• The logic consistently updates and reassigns auth.credentialRules after modifying them.
• This approach is more efficient than string concatenation and avoids unnecessary conversions.


264-269: Batch appending credential rules.
Collecting all additional rules in existingRules and then reassigning ensures a cohesive approach for large sets of new rules.


278-282: Appending privilege rules.
Following the same pattern as credential rules, making the code consistent and predictable.


292-297: Appending verified credential rules.
Maintaining the same array-based pattern is consistent with the broader shift from string-based to array-based rule storage.


331-339: Inherit credential rules from parent.
• Resetting child policy and then selectively cascading inherited rules is logical.
• Ensures only cascading rules are carried over.


342-348: Inherit verified credential rules.
Similarly retains and cascades parent VC rules where relevant. This preserves continuity in policy definitions.


356-356: Retrieving credential rules.
Returning rules as an array is consistent with the new data structure.


363-363: Retrieving verified credential rules.
This direct retrieval approach fits the updated format for rule management.


370-370: Returning privilege rules with null coalescing.
Using “?? []” ensures we safely handle any unset fields.

src/domain/common/authorization-policy/authorization.policy.interface.ts (2)

2-4: Imported interfaces match the shift to typed arrays.
Including these definitions aligns each rule type with its dedicated interface and fosters maintainable, type-safe code.


14-16: Converted fields to array types for credential, verifiedCredential, and privilege rules.
• Improves clarity by eliminating string-based representations.
• Ensures type safety and straightforward array operations across the codebase.

src/migrations/1734531789437-credentialRules.ts (2)

6-26: Migration-up ensures JSON consistency.
• Converting columns to JSON and enforcing empty arrays where null or empty strings were present ensures fully populated and correct data structures.
• This approach prevents data loss while transitioning to typed arrays.


28-39: Migration-down reverts columns.
• Safely restoring columns to text maintains rollback integrity should we need to revert the changes.

src/domain/common/authorization-policy/authorization.policy.entity.ts (4)

6-8: LGTM! Clean import organization

The new imports for rule types align with the transition to typed rules and follow proper module organization.


42-44: LGTM! Proper initialization of rule arrays

The constructor correctly initializes all rule arrays as empty arrays, preventing potential null reference issues.


Line range hint 1-47: Verify GraphQL schema compatibility

Since this is an entity class that likely has GraphQL types generated from it, we should verify the schema changes:

  1. Check if GraphQL types are properly updated
  2. Verify if this is a breaking change for API clients
✅ Verification successful

GraphQL schema is properly maintained with resolver fields

The verification shows that the GraphQL schema is properly maintained:

  • Found AuthorizationPolicyResolverFields class that handles GraphQL field resolution for the entity
  • The resolver properly exposes the entity fields through @ResolveField decorators
  • No breaking changes detected as the entity fields align with the resolver fields

This is not a breaking change for API clients as:

  • The entity fields are properly exposed through GraphQL resolvers
  • All fields in the entity have corresponding resolver fields
  • The nullable and type definitions are preserved
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Look for related GraphQL type definitions
rg -A 5 "type AuthorizationPolicy" --type graphql

# Check for GraphQL resolvers using this entity
ast-grep --pattern 'class $_ {
  $$$
  @ResolveField()
  $$$
}'

Length of output: 149


Script:

#!/bin/bash
# Look for GraphQL type definitions with different file extensions
rg -A 5 "type AuthorizationPolicy" --type ts

# Look for GraphQL schema definitions
fd "\.graphql$|\.gql$" --exec cat {}

# Check for GraphQL decorators and type definitions
rg "@ObjectType\(\)" -A 5

# Look specifically for authorization policy related resolvers
rg "class.*AuthorizationPolicy.*Resolver" -A 5

Length of output: 20008


15-22: Verify data migration for existing records

The column type changes from string to json look good and align with the optimization goals. However, we should ensure existing data is properly migrated.

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

🧹 Nitpick comments (1)
test/data/user.json (1)

23-58: Consider consolidating duplicate credential rules.

The credential rules in the profile authorization contain redundant entries for global admin privileges. Rules "1" and "2" grant almost identical privileges, which could lead to maintenance issues.

Consider consolidating the rules:

-          {
-            "name": "1",
-            "criterias": [],
-            "type": "global-admin",
-            "resourceID": "",
-            "grantedPrivileges": [
-              "create",
-              "grant",
-              "read",
-              "update",
-              "delete"
-            ],
-            "cascade": true
-          },
-          {
-            "name": "2",
-            "criterias": [],
-            "type": "global-admin-community",
-            "resourceID": "",
-            "grantedPrivileges": [
-              "create",
-              "read",
-              "update",
-              "delete",
-              "grant"
-            ],
-            "cascade": true
-          },
+          {
+            "name": "global-admin",
+            "criterias": [],
+            "type": "global-admin",
+            "resourceID": "",
+            "grantedPrivileges": ["create", "read", "update", "delete", "grant"],
+            "cascade": true
+          },
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7ba542a and 1204874.

📒 Files selected for processing (2)
  • src/domain/space/space/space.service.spec.ts (1 hunks)
  • test/data/user.json (3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/domain/space/space/space.service.spec.ts (2)

Pattern src/**/*.{ts,js}: Review the TypeScript/JavaScript code for NestJS best practices, dependency injection, module structure, and potential bugs.

Context Files (Do Not Review):

  • docs/Design.md - Design overview of the project
  • docs/Pagination.md - Pagination design overview
  • docs/Developing.md - Development setup overview
  • docs/graphql-typeorm-usage.md - overview of GraphQL and TypeORM usage and how they are used together with NestJS in the project
  • docs/database-definitions.md - guidelines for creating TypeORM entity defnitions
  • src/core/error-handling/graphql.exception.filter.ts - GraphQL error handling
  • src/core/error-handling/http.exception.filter.ts - HTTP error handling
  • src/core/error-handling/rest.error.response.ts - REST error response
  • src/core/error-handling/unhandled.exception.filter.ts - Global exception handler

Guidelines:

  • Our project uses global exception handlers (UnhandledExceptionFilter), so avoid suggesting additional try/catch blocks unless handling specific cases.
  • Use NestJS latest documentation from https://docs.nestjs.com/ for reference on NestJS best practices.
  • Use TypeORM latest documentation from https://typeorm.io/ for reference on TypeORM best practices.
  • Refer to the design overview in the context files for better understanding.

Pattern src/**/*.spec.ts: Review the unit tests, ensuring proper NestJS testing techniques (using TestingModule, mocks, etc.). Check for completeness and coverage.

🔇 Additional comments (2)
test/data/user.json (1)

74-109: Verify consistency of authorization rules across profile and agent objects.

The credential rules are duplicated across profile, agent, and user authorization sections. This could lead to inconsistencies if rules are updated in one place but not others.

Consider implementing a shared configuration for these rules to maintain consistency and ease updates.

Also applies to: 135-160

✅ Verification successful

Let me gather more information to see the complete credential rules and their structure across different sections.


Credential rules are indeed duplicated but consistent across sections

The analysis shows that the credential rules are duplicated three times in the user.json file, but they maintain consistency in their structure and permissions:

  • All sections contain the same global-admin and global-admin-community rules with identical privileges
  • The user-self rule maintains the same structure and privileges (create, read, update) across sections
  • The only minor difference is the addition of "name": "3" in one instance of user-self rule
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for inconsistencies in credential rules across different sections

# Search for credential rule definitions to compare their structure
rg -A 10 '"credentialRules": \['

Length of output: 1577


Script:

#!/bin/bash
# Get the complete content of user.json to analyze credential rules
cat test/data/user.json | jq -r '.. | .credentialRules? | select(. != null)'

Length of output: 2090

src/domain/space/space/space.service.spec.ts (1)

248-251: LGTM! Mock aligns with the new authorization policy structure.

The empty arrays correctly reflect the new type structure for credential rules, privilege rules, and verified credential rules.

test/data/user.json Show resolved Hide resolved
Copy link
Collaborator

@hero101 hero101 left a comment

Choose a reason for hiding this comment

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

I suggest:

  • the 3 fields NOT to be nullable in the db - the migration already adds value for all previously null values.
  • the fields to be not null in all layers of the service

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

🧹 Nitpick comments (2)
src/domain/common/authorization-policy/authorization.policy.service.ts (2)

264-269: **Avoid repeated .push loops (optional DRY suggestion) **
You may consider merging loops or using array spread to avoid repeated patterns. For example:

-for (const additionalRule of additionalRules) {
-  existingRules.push(additionalRule);
-}
+existingRules.push(...additionalRules);

This can slightly reduce verbosity and improve workflow.


331-339: **Consider filtering/transforming inherited rules more flexibly **
Currently, you filter inherited rules only by cascade. If you foresee applying more criteria, you might unify inheritance checks in a helper function for clarity.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1204874 and 3cc451a.

📒 Files selected for processing (2)
  • src/core/authorization/authorization.service.ts (6 hunks)
  • src/domain/common/authorization-policy/authorization.policy.service.ts (7 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
src/domain/common/authorization-policy/authorization.policy.service.ts (1)

Pattern src/**/*.{ts,js}: Review the TypeScript/JavaScript code for NestJS best practices, dependency injection, module structure, and potential bugs.

Context Files (Do Not Review):

  • docs/Design.md - Design overview of the project
  • docs/Pagination.md - Pagination design overview
  • docs/Developing.md - Development setup overview
  • docs/graphql-typeorm-usage.md - overview of GraphQL and TypeORM usage and how they are used together with NestJS in the project
  • docs/database-definitions.md - guidelines for creating TypeORM entity defnitions
  • src/core/error-handling/graphql.exception.filter.ts - GraphQL error handling
  • src/core/error-handling/http.exception.filter.ts - HTTP error handling
  • src/core/error-handling/rest.error.response.ts - REST error response
  • src/core/error-handling/unhandled.exception.filter.ts - Global exception handler

Guidelines:

  • Our project uses global exception handlers (UnhandledExceptionFilter), so avoid suggesting additional try/catch blocks unless handling specific cases.
  • Use NestJS latest documentation from https://docs.nestjs.com/ for reference on NestJS best practices.
  • Use TypeORM latest documentation from https://typeorm.io/ for reference on TypeORM best practices.
  • Refer to the design overview in the context files for better understanding.
src/core/authorization/authorization.service.ts (1)

Pattern src/**/*.{ts,js}: Review the TypeScript/JavaScript code for NestJS best practices, dependency injection, module structure, and potential bugs.

Context Files (Do Not Review):

  • docs/Design.md - Design overview of the project
  • docs/Pagination.md - Pagination design overview
  • docs/Developing.md - Development setup overview
  • docs/graphql-typeorm-usage.md - overview of GraphQL and TypeORM usage and how they are used together with NestJS in the project
  • docs/database-definitions.md - guidelines for creating TypeORM entity defnitions
  • src/core/error-handling/graphql.exception.filter.ts - GraphQL error handling
  • src/core/error-handling/http.exception.filter.ts - HTTP error handling
  • src/core/error-handling/rest.error.response.ts - REST error response
  • src/core/error-handling/unhandled.exception.filter.ts - Global exception handler

Guidelines:

  • Our project uses global exception handlers (UnhandledExceptionFilter), so avoid suggesting additional try/catch blocks unless handling specific cases.
  • Use NestJS latest documentation from https://docs.nestjs.com/ for reference on NestJS best practices.
  • Use TypeORM latest documentation from https://typeorm.io/ for reference on TypeORM best practices.
  • Refer to the design overview in the context files for better understanding.
🔇 Additional comments (14)
src/domain/common/authorization-policy/authorization.policy.service.ts (8)

163-165: **Use arrays for better clarity **
Initializing as empty arrays is a clear and direct approach to handle the rules, removing ambiguity that could arise from string-based data. This change improves maintainability.


Line range hint 244-254: **Appending rules logic is correct **
Appending the new rule directly to the existing array is straightforward and helps preserve the policy’s existing data while adding new entries.


278-282: **Consistent approach on privilege rules **
Logic for appending privilege rules aligns well with credential rules. Code is consistent.


292-297: **Verified credential appending logic consistent **
No issues found. Matches the pattern used for other rule types.


342-348: **Direct inheritance logic is straightforward **
Verified credential rules are simply cloned; usage is consistent.


356-356: **Direct property getter is fine **
Returning the credentialRules array directly is concise and consistent with your array approach.


362-362: **Method naming consistent **
Returning verifiedCredentialRules directly matches the naming convention for your policy objects.


368-368: **Nullish coalescing assures array return **
Using ?? [] ensures the method never returns undefined, a good safeguard if privilegeRules is not set.

src/core/authorization/authorization.service.ts (6)

89-89: **Ensure at least one base rule **
Throwing an exception when no credential rules are present enforces that every policy must define at least one rule. Double-check that this won’t prevent legitimate empty-policy scenarios if they exist.
Would you like a quick script to find empty policies in the codebase?


123-123: **Credential rules iteration is efficient **
Looping through credential rules directly avoids the overhead of previously performed conversions, aligning with the new array-based structure.


141-141: **Verified credential rules logic matches pattern **
The structure for verified credential checks mirrors the approach used for basic credentials, promoting consistency.


163-163: **Chaining privileges logic is sound **
Leveraging grantedPrivileges.includes(rule.sourcePrivilege) ensures any earlier rules feed into subsequent privilege checks.


182-213: **Efficient privilege aggregation via sets **
Using a Set for aggregating granted privileges prevents duplicates and simplifies the logic. Converting to an array at the end is standard practice. No major issues found here.


226-231: **isCredentialMatch logic is clean **
The .some usage and resourceID check policy are concise and correct. Throwing an exception for empty criterias is a good safety measure.

techsmyth
techsmyth previously approved these changes Dec 21, 2024
Copy link
Member

@techsmyth techsmyth left a comment

Choose a reason for hiding this comment

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

Nice improvement, both cleaner + faster :) For a very core bit of server code...

Also brought in the suggestions from Svetlo re not nullable fields. Migration generation is failing for me so raised another issue to check that the code + db are in sync + not block this one coming in.

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 comments (2)
src/core/authorization/authorization.service.ts (2)

Line range hint 244-259: Add error handling for JSON parsing

The JSON.parse operation could throw an error if claimRuleStr is malformed. Consider adding try-catch and type validation.

-      const claimRule: { name: string; value: string } =
-        JSON.parse(claimRuleStr);
+      let claimRule: { name: string; value: string };
+      try {
+        const parsed = JSON.parse(claimRuleStr);
+        if (typeof parsed.name === 'string' && typeof parsed.value === 'string') {
+          claimRule = parsed;
+        } else {
+          this.logger.error(
+            `Invalid claim rule format: ${claimRuleStr}`,
+            LogContext.AUTH
+          );
+          return false;
+        }
+      } catch (error) {
+        this.logger.error(
+          `Failed to parse claim rule: ${claimRuleStr}`,
+          LogContext.AUTH
+        );
+        return false;
+      }

Line range hint 48-60: Review sensitive data logging

The logCredentialCheckFailDetails method logs credential details which might contain sensitive information. Consider redacting sensitive fields before logging.

-      agentInfo.credentials,
+      this.redactSensitiveInfo(agentInfo.credentials),

Add this helper method:

private redactSensitiveInfo(credentials: ICredential[]): any[] {
  return credentials.map(cred => ({
    ...cred,
    resourceID: '[REDACTED]',
    // Add other sensitive fields to redact
  }));
}
🧹 Nitpick comments (2)
src/domain/common/authorization-policy/authorization.policy.entity.ts (1)

15-22: Consider adding JSON schema validation

While the type system provides compile-time safety, consider adding runtime validation using a JSON schema to ensure data integrity.

import { IsJSON, ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';

@Entity()
export class AuthorizationPolicy {
  @Column({ type: 'json', nullable: false })
  @IsJSON()
  @ValidateNested({ each: true })
  @Type(() => AuthorizationPolicyRuleCredential)
  credentialRules: AuthorizationPolicyRuleCredential[];
  
  // Apply similar decorators to other JSON columns
}
src/core/authorization/authorization.service.ts (1)

182-224: Consider consistent iteration pattern

While the refactoring improves efficiency using Set and null coalescing, the code mixes forEach and for...of loops. Consider using one consistent pattern throughout.

-    privilegeRules.forEach(rule => {
-      if (initialGrantedPrivileges.includes(rule.sourcePrivilege)) {
-        for (const privilege of rule.grantedPrivileges) {
-          grantedPrivileges.add(privilege);
-        }
-      }
-    });
+    privilegeRules.forEach(rule => {
+      if (initialGrantedPrivileges.includes(rule.sourcePrivilege)) {
+        rule.grantedPrivileges.forEach(privilege => 
+          grantedPrivileges.add(privilege)
+        );
+      }
+    });
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3cc451a and 543f00f.

📒 Files selected for processing (6)
  • src/core/authorization/authorization.service.ts (6 hunks)
  • src/domain/common/authorization-policy/authorization.policy.entity.ts (2 hunks)
  • src/domain/common/authorization-policy/authorization.policy.resolver.fields.ts (4 hunks)
  • src/domain/community/community/community.entity.ts (1 hunks)
  • src/domain/space/space/space.service.spec.ts (1 hunks)
  • src/migrations/1734708463444-credentialRules.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/domain/community/community/community.entity.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/domain/space/space/space.service.spec.ts
🧰 Additional context used
📓 Path-based instructions (4)
src/migrations/1734708463444-credentialRules.ts (1)

Pattern src/**/*.{ts,js}: Review the TypeScript/JavaScript code for NestJS best practices, dependency injection, module structure, and potential bugs.

Context Files (Do Not Review):

  • docs/Design.md - Design overview of the project
  • docs/Pagination.md - Pagination design overview
  • docs/Developing.md - Development setup overview
  • docs/graphql-typeorm-usage.md - overview of GraphQL and TypeORM usage and how they are used together with NestJS in the project
  • docs/database-definitions.md - guidelines for creating TypeORM entity defnitions
  • src/core/error-handling/graphql.exception.filter.ts - GraphQL error handling
  • src/core/error-handling/http.exception.filter.ts - HTTP error handling
  • src/core/error-handling/rest.error.response.ts - REST error response
  • src/core/error-handling/unhandled.exception.filter.ts - Global exception handler

Guidelines:

  • Our project uses global exception handlers (UnhandledExceptionFilter), so avoid suggesting additional try/catch blocks unless handling specific cases.
  • Use NestJS latest documentation from https://docs.nestjs.com/ for reference on NestJS best practices.
  • Use TypeORM latest documentation from https://typeorm.io/ for reference on TypeORM best practices.
  • Refer to the design overview in the context files for better understanding.
src/domain/common/authorization-policy/authorization.policy.entity.ts (1)

Pattern src/**/*.{ts,js}: Review the TypeScript/JavaScript code for NestJS best practices, dependency injection, module structure, and potential bugs.

Context Files (Do Not Review):

  • docs/Design.md - Design overview of the project
  • docs/Pagination.md - Pagination design overview
  • docs/Developing.md - Development setup overview
  • docs/graphql-typeorm-usage.md - overview of GraphQL and TypeORM usage and how they are used together with NestJS in the project
  • docs/database-definitions.md - guidelines for creating TypeORM entity defnitions
  • src/core/error-handling/graphql.exception.filter.ts - GraphQL error handling
  • src/core/error-handling/http.exception.filter.ts - HTTP error handling
  • src/core/error-handling/rest.error.response.ts - REST error response
  • src/core/error-handling/unhandled.exception.filter.ts - Global exception handler

Guidelines:

  • Our project uses global exception handlers (UnhandledExceptionFilter), so avoid suggesting additional try/catch blocks unless handling specific cases.
  • Use NestJS latest documentation from https://docs.nestjs.com/ for reference on NestJS best practices.
  • Use TypeORM latest documentation from https://typeorm.io/ for reference on TypeORM best practices.
  • Refer to the design overview in the context files for better understanding.
src/domain/common/authorization-policy/authorization.policy.resolver.fields.ts (1)

Pattern src/**/*.{ts,js}: Review the TypeScript/JavaScript code for NestJS best practices, dependency injection, module structure, and potential bugs.

Context Files (Do Not Review):

  • docs/Design.md - Design overview of the project
  • docs/Pagination.md - Pagination design overview
  • docs/Developing.md - Development setup overview
  • docs/graphql-typeorm-usage.md - overview of GraphQL and TypeORM usage and how they are used together with NestJS in the project
  • docs/database-definitions.md - guidelines for creating TypeORM entity defnitions
  • src/core/error-handling/graphql.exception.filter.ts - GraphQL error handling
  • src/core/error-handling/http.exception.filter.ts - HTTP error handling
  • src/core/error-handling/rest.error.response.ts - REST error response
  • src/core/error-handling/unhandled.exception.filter.ts - Global exception handler

Guidelines:

  • Our project uses global exception handlers (UnhandledExceptionFilter), so avoid suggesting additional try/catch blocks unless handling specific cases.
  • Use NestJS latest documentation from https://docs.nestjs.com/ for reference on NestJS best practices.
  • Use TypeORM latest documentation from https://typeorm.io/ for reference on TypeORM best practices.
  • Refer to the design overview in the context files for better understanding.
src/core/authorization/authorization.service.ts (1)

Pattern src/**/*.{ts,js}: Review the TypeScript/JavaScript code for NestJS best practices, dependency injection, module structure, and potential bugs.

Context Files (Do Not Review):

  • docs/Design.md - Design overview of the project
  • docs/Pagination.md - Pagination design overview
  • docs/Developing.md - Development setup overview
  • docs/graphql-typeorm-usage.md - overview of GraphQL and TypeORM usage and how they are used together with NestJS in the project
  • docs/database-definitions.md - guidelines for creating TypeORM entity defnitions
  • src/core/error-handling/graphql.exception.filter.ts - GraphQL error handling
  • src/core/error-handling/http.exception.filter.ts - HTTP error handling
  • src/core/error-handling/rest.error.response.ts - REST error response
  • src/core/error-handling/unhandled.exception.filter.ts - Global exception handler

Guidelines:

  • Our project uses global exception handlers (UnhandledExceptionFilter), so avoid suggesting additional try/catch blocks unless handling specific cases.
  • Use NestJS latest documentation from https://docs.nestjs.com/ for reference on NestJS best practices.
  • Use TypeORM latest documentation from https://typeorm.io/ for reference on TypeORM best practices.
  • Refer to the design overview in the context files for better understanding.
🔇 Additional comments (8)
src/migrations/1734708463444-credentialRules.ts (1)

8-16: Consider handling invalid JSON data during cleanup

While the migration handles NULL and empty values, it should also validate and handle any potential invalid JSON data in existing rows to prevent migration failures.

src/domain/common/authorization-policy/authorization.policy.entity.ts (1)

43-45: LGTM! Proper array initialization

The constructor correctly initializes the arrays, ensuring type safety and preventing null reference issues.

src/domain/common/authorization-policy/authorization.policy.resolver.fields.ts (2)

Line range hint 23-28: LGTM! Type-safe resolver implementations

The resolver methods are properly typed and aligned with the entity changes, maintaining type safety throughout the GraphQL layer.

Also applies to: 38-44, 53-58, 67-73


18-18: Verify client compatibility with non-nullable fields

The change from nullable to non-nullable fields is a breaking change for GraphQL clients. Ensure all clients are updated to handle array responses instead of potential null values.

Also applies to: 33-33, 48-48, 61-61

✅ Verification successful

Non-nullable fields change appears safe to proceed

The resolver fields are part of a GraphQL parent-child relationship where the parent (AuthorizationPolicy) always provides these arrays, as evidenced by the service implementation returning arrays directly. The change to non-nullable is actually making the schema more accurate by reflecting the true behavior of the resolver methods, which always return arrays and never null.

  • The credentialRules, verifiedCredentialRules, privilegeRules, and myPrivileges fields are populated by direct service method calls that return arrays
  • The resolver is server-side code and the lack of client-side query matches suggests this might be an internal API or newly added functionality
  • The type safety is improved by making the schema match the actual implementation
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for GraphQL queries/mutations using these fields
echo "Searching for GraphQL queries/mutations using authorization policy fields..."
rg -A 5 "credentialRules|verifiedCredentialRules|privilegeRules|myPrivileges" --type ts --type tsx --type graphql

Length of output: 306


Script:

#!/bin/bash
# Search for GraphQL queries/mutations using these fields with correct file types
echo "Searching for GraphQL queries/mutations using authorization policy fields..."
rg -A 5 "credentialRules|verifiedCredentialRules|privilegeRules|myPrivileges" --type ts --type graphql

# Also search for GraphQL operations in .gql or .graphql files
echo "Searching in GraphQL files..."
fd -e gql -e graphql -x cat {}

# Check the resolver file for context
echo "Checking resolver context..."
cat src/domain/common/authorization-policy/authorization.policy.resolver.fields.ts

Length of output: 3471


Script:

#!/bin/bash
# Search for GraphQL schema definitions to understand the previous nullable state
echo "Checking GraphQL schema definitions..."
rg -B 2 -A 2 "type AuthorizationPolicy" --type ts

# Search for any client-side code that might be affected
echo "Searching for client-side usage..."
rg --type ts "AuthorizationPolicy.*\{[^}]*\b(credentialRules|verifiedCredentialRules|privilegeRules|myPrivileges)\b"

# Check the interface definition
echo "Checking interface definition..."
fd -e ts -e js -x rg -l "interface IAuthorizationPolicy"

Length of output: 470

src/core/authorization/authorization.service.ts (4)

Line range hint 89-94: LGTM: Improved validation logic

The validation now correctly checks for empty credential rules using array length, which is more appropriate for the new data structure.


Line range hint 123-141: LGTM: Performance optimization achieved

Direct usage of credential rules array eliminates unnecessary JSON conversions, contributing to the reported 2-3x performance improvement.


237-242: LGTM: Improved matching logic

The refactored credential matching logic is more efficient using Array.some() and provides better readability with clear conditions.


Line range hint 1-259: Verify performance improvement claims

The code changes support the claimed 2-3x performance improvement through:

  1. Removal of JSON conversions
  2. Use of Set for unique privileges
  3. Optimized array operations

Consider adding performance benchmarks to verify these improvements.

Comment on lines +17 to +25
await queryRunner.query(
'ALTER TABLE `authorization_policy` MODIFY COLUMN `credentialRules` json null'
);
await queryRunner.query(
'ALTER TABLE `authorization_policy` MODIFY COLUMN `verifiedCredentialRules` json null'
);
await queryRunner.query(
'ALTER TABLE `authorization_policy` MODIFY COLUMN `privilegeRules` json null'
);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding NOT NULL constraint

Since the entity defines these columns as nullable: false, consider adding NOT NULL constraint in the migration to maintain consistency between the entity and database schema.

-      'ALTER TABLE `authorization_policy` MODIFY COLUMN `credentialRules` json null'
+      'ALTER TABLE `authorization_policy` MODIFY COLUMN `credentialRules` json NOT NULL'

-      'ALTER TABLE `authorization_policy` MODIFY COLUMN `verifiedCredentialRules` json null'
+      'ALTER TABLE `authorization_policy` MODIFY COLUMN `verifiedCredentialRules` json NOT NULL'

-      'ALTER TABLE `authorization_policy` MODIFY COLUMN `privilegeRules` json null'
+      'ALTER TABLE `authorization_policy` MODIFY COLUMN `privilegeRules` json NOT NULL'

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +28 to +38
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
'ALTER TABLE `authorization_policy` MODIFY COLUMN `credentialRules` text'
);
await queryRunner.query(
'ALTER TABLE `authorization_policy` MODIFY COLUMN `verifiedCredentialRules` text'
);
await queryRunner.query(
'ALTER TABLE `authorization_policy` MODIFY COLUMN `privilegeRules` text'
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add data cleanup in down migration

The down migration should handle converting JSON arrays back to string format to maintain data consistency when rolling back.

 public async down(queryRunner: QueryRunner): Promise<void> {
+    // Convert JSON arrays to string format
+    await queryRunner.query(
+      "UPDATE `authorization_policy` SET `credentialRules` = CAST(`credentialRules` AS CHAR) WHERE `credentialRules` IS NOT NULL"
+    );
+    await queryRunner.query(
+      "UPDATE `authorization_policy` SET `verifiedCredentialRules` = CAST(`verifiedCredentialRules` AS CHAR) WHERE `verifiedCredentialRules` IS NOT NULL"
+    );
+    await queryRunner.query(
+      "UPDATE `authorization_policy` SET `privilegeRules` = CAST(`privilegeRules` AS CHAR) WHERE `privilegeRules` IS NOT NULL"
+    );
+
     await queryRunner.query(
       'ALTER TABLE `authorization_policy` MODIFY COLUMN `credentialRules` text'
     );

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Member

@techsmyth techsmyth left a comment

Choose a reason for hiding this comment

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

Fixed issue with privilege rules on myPrivileges

@techsmyth techsmyth merged commit 5cfd421 into develop Dec 21, 2024
3 checks passed
@techsmyth techsmyth deleted the optimize-auth branch December 21, 2024 07:35
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.

3 participants