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: Fallback to using list auth if details auth fails, remove double cache #1274

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

elsand
Copy link
Collaborator

@elsand elsand commented Oct 11, 2024

Description

This implements a fall back to using list authorization if the details authorization returns without access to the main resource. This might happen if

  • The XACML policy doesn't define a "read" rule
  • There are no GUI/API actions in the dialog referring to XACML actions the user is granted access to

This ensures that dialogs that is visible in the list, also can be viewed in details view, even if the user has isn't authorized for any actions. He/she might still have access to transmissions using authorization attributes (depending on if the authorization attribute refers a subresource or external resource; either having "transmissionread" in the ServiceResource policy, or having "read" on the external resource policy)

Also, this removes a redundant double caching of list authorization. This was a leftover after the non-scalable PDP-based authorization.

Related Issue(s)

This adresses the principal problem raised in #1247, which is the discrepancy between perceived list and details authorization. We still need to consider if GetAltinnActions should be policy-based, as that will allow us to implement action-property validation in Create/Update commands. This will also let us include all authorized actions in dialog tokens in the a (actions) claim, not just the actions referred to in the dialog.

Verification

  • Your code builds clean without any errors or warnings
  • Manual testing done (required)
  • Relevant automated test added (if you find this hard, leave it and we'll help out)

Documentation

  • Documentation is updated (either in docs-directory, Altinnpedia or a separate linked PR in altinn-studio-docs., if applicable)

Summary by CodeRabbit

  • New Features

    • Introduced a new method to check list authorization for dialogs, enhancing user access control.
    • Added additional authorization checks for dialogs, allowing users with list access to retrieve dialogs even without main resource access.
  • Bug Fixes

    • Improved error handling and validation in dialog creation tests, ensuring robust and localized feedback.
  • Chores

    • Updated caching strategy for search authorization results to improve performance.

@elsand elsand requested a review from a team as a code owner October 11, 2024 13:16
Copy link
Contributor

coderabbitai bot commented Oct 11, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

This pull request implements several changes to enhance authorization handling within the Dialogporten application. Key modifications include the addition of a method for checking list authorization in the IAltinnAuthorization interface and related classes, as well as optimizations in the GetAuthorizedActions method of the DialogTokenGenerator class. The GetDialogQueryHandler class has been updated to incorporate these new authorization checks. Additionally, integration tests for dialog creation have been improved to ensure robust validation.

Changes

File Change Summary
src/Digdir.Domain.Dialogporten.Application/Common/IDialogTokenGenerator.cs Modified GetAuthorizedActions to return an empty string if AuthorizedAltinnActions is empty.
src/Digdir.Domain.Dialogporten.Application/Externals/AltinnAuthorization/IAltinnAuthorization.cs Added method Task<bool> HasListAuthorizationForDialog(DialogEntity dialog, CancellationToken cancellationToken).
src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Get/GetDialogQuery.cs Updated GetDialogQueryHandler.Handle to include additional checks for list authorization.
src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/AltinnAuthorizationClient.cs Removed caching from GetAuthorizedResourcesForSearch and added HasListAuthorizationForDialog.
src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/LocalDevelopmentAltinnAuthorization.cs Added HasListAuthorizationForDialog and modified GetAuthorizedParties method signature.
tests/Digdir.Domain.Dialogporten.Application.Integration.Tests/Features/V1/ServiceOwner/Dialogs/Commands/CreateDialogTests.cs Enhanced validation logic in CreateDialogTests for dialog creation commands.

Possibly related issues

Possibly related PRs

Suggested reviewers

  • knuhau
  • MagnusSandgren

📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 264a454 and 7db5bfe.

📒 Files selected for processing (1)
  • src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Get/GetDialogQuery.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Get/GetDialogQuery.cs

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

🧹 Outside diff range and nitpick comments (7)
src/Digdir.Domain.Dialogporten.Application/Externals/AltinnAuthorization/IAltinnAuthorization.cs (1)

20-20: Approve the addition with a minor suggestion.

The new HasListAuthorizationForDialog method is a valuable addition that aligns well with the PR objectives. It provides a clear way to check for list authorization, which is crucial for implementing the fallback mechanism described in the PR summary.

The method signature is consistent with other methods in the interface, following the async pattern and including a CancellationToken.

Consider making the CancellationToken parameter optional by providing a default value:

- Task<bool> HasListAuthorizationForDialog(DialogEntity dialog, CancellationToken cancellationToken);
+ Task<bool> HasListAuthorizationForDialog(DialogEntity dialog, CancellationToken cancellationToken = default);

This change would make it consistent with the GetDialogDetailsAuthorization method and provide more flexibility when calling the method.

src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/LocalDevelopmentAltinnAuthorization.cs (3)

59-59: LGTM with a minor suggestion.

The changes to the GetAuthorizedParties method look good. The new syntax for initializing AuthorizedPartiesResult is more concise and readable.

Consider adding a comment explaining the purpose of the unused bool _ parameter, or use the discard pattern _ instead of naming it if it's intentionally unused:

-public async Task<AuthorizedPartiesResult> GetAuthorizedParties(IPartyIdentifier authenticatedParty, bool _ = false, CancellationToken __ = default)
+public async Task<AuthorizedPartiesResult> GetAuthorizedParties(IPartyIdentifier authenticatedParty, bool _, CancellationToken __ = default)

60-60: LGTM with a suggestion for improved documentation.

The addition of the HasListAuthorizationForDialog method is appropriate for this local development implementation.

Consider adding a comment to explain that this method always returns true for local development purposes:

-    public Task<bool> HasListAuthorizationForDialog(DialogEntity dialog, CancellationToken cancellationToken) => Task.FromResult(true);
+    // Always allow list authorization in local development
+    public Task<bool> HasListAuthorizationForDialog(DialogEntity dialog, CancellationToken cancellationToken) => Task.FromResult(true);

59-60: Changes align well with PR objectives.

The modifications to GetAuthorizedParties and the addition of HasListAuthorizationForDialog are consistent with the PR's goal of implementing a fallback mechanism for authorization. These changes in the local development implementation provide a good foundation for testing the new authorization flow without restrictions.

Ensure that the production implementation of IAltinnAuthorization properly handles the fallback logic as described in the PR objectives, particularly when details authorization fails.

src/Digdir.Domain.Dialogporten.Application/Common/IDialogTokenGenerator.cs (1)

77-81: Approve changes with a minor optimization suggestion.

The addition of an early return for empty AuthorizedAltinnActions is a good optimization. It aligns with the PR objectives by handling cases where a user might not have any authorized actions, which could occur when falling back to list authorization.

To further optimize, consider using string.Empty instead of "":

 if (authorizationResult.AuthorizedAltinnActions.Count == 0)
 {
-    return "";
+    return string.Empty;
 }

This change is minor but adheres to C# best practices for using string.Empty instead of empty string literals.

src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/AltinnAuthorizationClient.cs (2)

76-78: LGTM! Consider clarifying the comment slightly.

The removal of caching at this level is appropriate and aligns with the PR objective of removing double caching. The direct call to PerformDialogSearchAuthorization is correct.

Consider slightly rewording the comment for clarity:

- // We don't cache at this level, as the principal information is received from GetAuthorizedParties,
- // which is already cached
+ // We don't cache at this level because the principal information comes from GetAuthorizedParties,
+ // which is already cached

91-100: LGTM! Consider a minor optimization.

The new HasListAuthorizationForDialog method is well-implemented and aligns perfectly with the PR objective. It correctly checks for list authorization using the GetAuthorizedResourcesForSearch method and covers all possible cases of authorization.

Consider a minor optimization to short-circuit the evaluation:

 public async Task<bool> HasListAuthorizationForDialog(DialogEntity dialog, CancellationToken cancellationToken)
 {
     var authorizedResourcesForSearch = await GetAuthorizedResourcesForSearch(
         [dialog.Party], [dialog.ServiceResource], cancellationToken);

-    return authorizedResourcesForSearch.ResourcesByParties.Count > 0
-           || authorizedResourcesForSearch.SubjectsByParties.Count > 0
-           || authorizedResourcesForSearch.DialogIds.Contains(dialog.Id);
+    return authorizedResourcesForSearch.ResourcesByParties.Count > 0
+           || authorizedResourcesForSearch.SubjectsByParties.Count > 0
+           || (authorizedResourcesForSearch.DialogIds?.Contains(dialog.Id) ?? false);
 }

This change ensures that DialogIds is not null before calling Contains, which could prevent a potential NullReferenceException.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between dd4b019 and 264a454.

📒 Files selected for processing (6)
  • src/Digdir.Domain.Dialogporten.Application/Common/IDialogTokenGenerator.cs (1 hunks)
  • src/Digdir.Domain.Dialogporten.Application/Externals/AltinnAuthorization/IAltinnAuthorization.cs (1 hunks)
  • src/Digdir.Domain.Dialogporten.Application/Features/V1/EndUser/Dialogs/Queries/Get/GetDialogQuery.cs (1 hunks)
  • src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/AltinnAuthorizationClient.cs (2 hunks)
  • src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/LocalDevelopmentAltinnAuthorization.cs (1 hunks)
  • tests/Digdir.Domain.Dialogporten.Application.Integration.Tests/Features/V1/ServiceOwner/Dialogs/Commands/CreateDialogTests.cs (1 hunks)
🧰 Additional context used
📓 Learnings (1)
tests/Digdir.Domain.Dialogporten.Application.Integration.Tests/Features/V1/ServiceOwner/Dialogs/Commands/CreateDialogTests.cs (2)
Learnt from: oskogstad
PR: digdir/dialogporten#1210
File: tests/Digdir.Domain.Dialogporten.Application.Integration.Tests/Features/V1/ServiceOwner/Dialogs/Commands/CreateDialogTests.cs:282-282
Timestamp: 2024-10-08T15:39:24.789Z
Learning: Using square brackets `[]` for collection initialization is acceptable in the codebase's C# code.
Learnt from: oskogstad
PR: digdir/dialogporten#1210
File: tests/Digdir.Domain.Dialogporten.Application.Integration.Tests/Features/V1/ServiceOwner/Dialogs/Commands/CreateDialogTests.cs:282-282
Timestamp: 2024-10-01T17:03:49.291Z
Learning: Using square brackets `[]` for collection initialization is acceptable in the codebase's C# code.
🔇 Additional comments (1)
src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/AltinnAuthorizationClient.cs (1)

Line range hint 1-100: Summary: Changes align well with PR objectives

The modifications in this file successfully implement the fallback mechanism using list authorization and remove double caching as intended. The new HasListAuthorizationForDialog method provides the necessary functionality for the fallback mechanism, ensuring that dialogs visible in the list can be accessed in the details view, even if the user lacks authorization for specific actions.

These changes directly address the issues raised in the related issue (#1247) regarding the inconsistency between list and details authorization. The implementation is correct, comprehensive, and aligns perfectly with the PR objectives.

@elsand elsand changed the title Fallback to using list auth if details auth fails, remove double cache fix: Fallback to using list auth if details auth fails, remove double cache Oct 11, 2024
elsand and others added 3 commits October 11, 2024 15:29
…/Dialogs/Queries/Get/GetDialogQuery.cs

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link

sonarcloud bot commented Oct 14, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

2 participants