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

Add logic for downloading attachment for A2 GUI #421

Merged
merged 15 commits into from
Nov 6, 2024

Conversation

CelineTrammi
Copy link
Collaborator

@CelineTrammi CelineTrammi commented Nov 1, 2024

Description

Add initial logic for downloading attachment for correspondence in A2 GUI.

This is missing authorization, but will be implemented in a future PR.

Related Issue(s)

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)
  • All tests run green

Documentation

  • User documentation is updated with a separate linked PR in altinn-studio-docs. (if applicable)

Summary by CodeRabbit

  • New Features

    • Introduced a new method to download attachments linked to correspondence.
    • Added a helper method to retrieve the party ID from user claims.
  • Bug Fixes

    • Enhanced error handling for attachment downloads, ensuring proper feedback for invalid requests.
  • Chores

    • Cleaned up code by removing unused dependencies in the controller.
    • Updated service registrations to include new handlers for correspondence management.

@CelineTrammi CelineTrammi marked this pull request as ready for review November 1, 2024 12:55
Copy link
Contributor

coderabbitai bot commented Nov 1, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

This pull request introduces enhancements to the LegacyCorrespondenceController by adding a method for downloading correspondence attachments. It also updates the dependency injection configuration to include new handlers for processing these download requests. Additionally, a new handler class is created to manage the download logic, and a utility method for retrieving party IDs from user claims is added. Unused import statements are removed for code optimization.

Changes

File Change Summary
src/Altinn.Correspondence.API/Controllers/LegacyCorrespondenceController.cs Added method DownloadCorrespondenceAttachment for downloading attachments; removed unused using statements.
src/Altinn.Correspondence.Application/DependencyInjection.cs Added service registrations for MigrateCorrespondenceHandler and LegacyDownloadCorrespondenceAttachmentHandler.
src/Altinn.Correspondence.Application/DownloadCorrespondenceAttachment/LegacyDownloadCorrespondenceAttachmentHandler.cs Added class LegacyDownloadCorrespondenceAttachmentHandler with method Process for handling download requests.
src/Altinn.Correspondence.Application/Helpers/UserClaimsHelper.cs Added private constant _partyIdClaim and public method GetPartyId() for retrieving party ID from claims.

Possibly related PRs

Suggested labels

kind/feature-request

Suggested reviewers

  • Andreass2

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 96238b6 and af96661.

📒 Files selected for processing (1)
  • src/Altinn.Correspondence.Application/DownloadCorrespondenceAttachment/LegacyDownloadCorrespondenceAttachmentHandler.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Altinn.Correspondence.Application/DownloadCorrespondenceAttachment/LegacyDownloadCorrespondenceAttachmentHandler.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.

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

🧹 Outside diff range and nitpick comments (2)
src/Altinn.Correspondence.API/Controllers/LegacyCorrespondenceController.cs (2)

112-114: Enhance method documentation with response types.

The XML documentation should include possible response types and status codes for better API documentation.

 /// <summary>
 /// Download an attachment from a Correspondence
 /// </summary>
+/// <response code="200">Returns the attachment file stream</response>
+/// <response code="404">If the correspondence or attachment is not found</response>
+/// <response code="403">If the user is not authorized to access this attachment</response>

124-129: Consider validating input parameters.

The method directly uses the input parameters without validation. While the handler might handle validation, consider adding basic checks at the controller level.

+            if (correspondenceId == Guid.Empty || attachmentId == Guid.Empty)
+            {
+                return BadRequest("Invalid correspondence or attachment ID");
+            }
+
             var commandResult = await handler.Process(new DownloadCorrespondenceAttachmentRequest()
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between ce0e822 and ffff88e.

📒 Files selected for processing (3)
  • src/Altinn.Correspondence.API/Controllers/LegacyCorrespondenceController.cs (2 hunks)
  • src/Altinn.Correspondence.Application/DependencyInjection.cs (1 hunks)
  • src/Altinn.Correspondence.Application/DownloadCorrespondenceAttachment/LegacyDownloadCorrespondenceAttachmentHandler.cs (1 hunks)
🧰 Additional context used
📓 Learnings (1)
src/Altinn.Correspondence.Application/DependencyInjection.cs (1)
Learnt from: CelineTrammi
PR: Altinn/altinn-correspondence#413
File: src/Altinn.Correspondence.Application/DependencyInjection.cs:0-0
Timestamp: 2024-10-29T13:40:14.651Z
Learning: In Altinn.Correspondence.Application, handlers with similar names—such as UploadAttachmentHandler, GetAttachmentDetailsHandler, GetAttachmentOverviewHandler, and PurgeAttachmentHandler—may have multiple distinct implementations and are intentionally registered separately in DependencyInjection.cs.
🔇 Additional comments (6)
src/Altinn.Correspondence.Application/DependencyInjection.cs (2)

60-60: LGTM! Handler registration follows established patterns.

The registration of LegacyDownloadCorrespondenceAttachmentHandler as a scoped service is consistent with other handlers and correctly placed in the "Legacy" section.


60-60: Verify the handler implementation exists.

Let's verify that the referenced handler class exists in the codebase.

✅ Verification successful

Let me analyze the output and generate additional verification scripts to get more context about the handler implementation.


Handler implementation exists and is properly structured

The LegacyDownloadCorrespondenceAttachmentHandler class exists and is correctly implemented:

  • Implements IHandler<DownloadCorrespondenceAttachmentRequest, DownloadCorrespondenceAttachmentResponse>
  • Has proper dependency injection through constructor
  • Contains required repository and service dependencies
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the LegacyDownloadCorrespondenceAttachmentHandler class exists
# and verify its basic structure

# Test 1: Search for the handler class definition
echo "Searching for handler class definition..."
ast-grep --pattern 'class LegacyDownloadCorrespondenceAttachmentHandler'

# Test 2: Verify it implements IHandler interface
echo "Verifying interface implementation..."
ast-grep --pattern 'class LegacyDownloadCorrespondenceAttachmentHandler : IHandler'

Length of output: 42097


Script:

#!/bin/bash
# Search for the specific handler implementation to verify its structure
echo "Searching for LegacyDownloadCorrespondenceAttachmentHandler implementation..."
rg -A 10 "class LegacyDownloadCorrespondenceAttachmentHandler" --type cs

Length of output: 2444

src/Altinn.Correspondence.Application/DownloadCorrespondenceAttachment/LegacyDownloadCorrespondenceAttachmentHandler.cs (2)

1-27: LGTM! Well-structured class with appropriate dependencies.

The class follows SOLID principles with clear separation of concerns and proper dependency injection.


51-51: Verify stream disposal.

Ensure the attachment stream is properly disposed if an error occurs after downloading.

✅ Verification successful

Based on the implementation shown, I can now provide the final response:

Stream disposal is properly handled by the Azure SDK

The stream returned by blobClient.DownloadContentAsync() and transformed via ToStream() is managed by the Azure SDK's BinaryData class. The SDK handles proper resource cleanup, and there's no need for explicit disposal in this case. The stream is automatically disposed when the HTTP response is completed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other implementations of DownloadAttachment to verify stream handling
ast-grep --pattern 'await $_storageRepository.DownloadAttachment($$$)'

Length of output: 72


Script:

#!/bin/bash
# Let's search for the file content to understand the stream handling
rg -l "DownloadCorrespondenceAttachmentHandler" 

# Also search for any using statements or dispose patterns in the file
rg -A 5 "DownloadAttachment" 

# Search for interface or implementation of storage repository
rg "IStorageRepository|StorageRepository" -A 5

Length of output: 31206


Script:

#!/bin/bash
# Let's look at the implementation of DownloadAttachment in StorageRepository to understand stream handling
rg -A 10 "public async Task<Stream> DownloadAttachment"

# Also search for any using statements in the file to see if it implements IDisposable
rg "using" src/Altinn.Correspondence.Persistence/Repositories/StorageRepository.cs

Length of output: 1914

src/Altinn.Correspondence.API/Controllers/LegacyCorrespondenceController.cs (2)

1-11: LGTM! Clean import statements.

The imports have been streamlined to include only the necessary dependencies, improving code maintainability.


115-118: Verify authorization requirements for attachment downloads.

While the PR description mentions that authorization will be handled in a future PR, it's important to note that the current class-level [Authorize(Policy = AuthorizationConstants.Legacy)] might not provide sufficient granular control for attachment access.

✅ Verification successful

Authorization requirements for attachment downloads are properly configured

The codebase shows that attachment downloads in the legacy controller are protected by:

  1. Class-level authorization with [Authorize(Policy = AuthorizationConstants.Legacy)]
  2. Implementation-level checks in LegacyDownloadCorrespondenceAttachmentHandler that verify:
    • User is a recipient
    • Correspondence is in a state available for recipient access

This matches the pattern used in the main CorrespondenceController which uses [Authorize(Policy = AuthorizationConstants.DownloadAttachmentPolicy)] with additional authentication schemes.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any existing authorization patterns in attachment handling
rg -l 'attachment.*download.*auth' 

# Look for similar endpoints to understand authorization patterns
ast-grep --pattern 'Route.*download.*attachment'

Length of output: 87


Script:

#!/bin/bash
# Look for authorization patterns in the controller and related files
rg -A 5 -B 5 "\[Authorize" src/

# Check for any existing attachment download implementations
rg -A 10 "download.*attachment|attachment.*download" src/

# Look for authorization constants and policies
rg -A 3 "AuthorizationConstants|AuthorizationPolicy" src/

Length of output: 63680

CelineTrammi and others added 5 commits November 5, 2024 14:07
…irmed (#427)

* fix: validate correspondence has been fetched before it can be read and confirmed

* update tests

* typo fix

* Handle potential null value for IsConfirmationNeeded

* reuse factory for client initialization

* rename testname

* add Fetched to statuses available for Recipient
* Initial functionality for legacy correspondenceOverview

* improvements

* better naming

* better text for api route

* add auth for legacy overview

* better error message

* fix variable names

* improve minAuthLevel function

* Better naming

---------

Co-authored-by: Hammerbeck <[email protected]>
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: 12

🧹 Outside diff range and nitpick comments (20)
src/Altinn.Correspondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewResponse.cs (2)

6-7: Add XML documentation for the class.

Consider adding XML documentation to explain the purpose of this legacy response class and its relationship with the base class. This will help future maintainers understand when to use this specific implementation versus the base class.

+/// <summary>
+/// Legacy response model for correspondence overview that includes additional authorization and archival properties.
+/// This class extends the base GetCorrespondenceOverviewResponse to maintain backward compatibility.
+/// </summary>
 public class LegacyGetCorrespondenceOverviewResponse : GetCorrespondenceOverviewResponse

12-12: Consider using an enum for MinimumAuthenticationLevel.

Instead of using an integer for authentication levels, consider using an enum to ensure type safety and valid values.

-    public int MinimumAuthenticationLevel { get; set; }
+    public AuthenticationLevel MinimumAuthenticationLevel { get; set; }

This would require:

  1. Using an appropriate enum from your authentication framework
  2. Updating any code that sets or reads this property
src/Altinn.Correspondence.Core/Repositories/IAltinnAuthorizationService.cs (1)

8-8: Add XML documentation for the new method.

The method signature looks good, but please add XML documentation to describe:

  • The purpose of the method
  • The expected return values (including when null is returned)
  • Parameter descriptions
  • Any exceptions that might be thrown

Example:

+    /// <summary>
+    /// Checks if the user has access to the specified resource and returns the minimum authentication level required.
+    /// </summary>
+    /// <param name="resourceId">The ID of the resource to check access for</param>
+    /// <param name="rights">List of access levels to check</param>
+    /// <param name="cancellationToken">Optional cancellation token</param>
+    /// <param name="recipientOrgNo">Optional organization number of the recipient</param>
+    /// <returns>The minimum authentication level required if access is granted, null if access is denied</returns>
     Task<int?> CheckUserAccessAndGetMinimumAuthLevel(string resourceId, List<ResourceAccessLevel> rights, CancellationToken cancellationToken = default, string? recipientOrgNo = null);
src/Altinn.Correspondence.Integrations/Altinn/Authorization/AltinnAuthorizationDevService.cs (2)

18-21: Document the significance of authentication level 3.

While this is a development service implementation, it would be helpful to document why level 3 was chosen as the default authentication level. This helps other developers understand the implications during testing.

         public Task<int?> CheckUserAccessAndGetMinimumAuthLevel(string resourceId, List<ResourceAccessLevel> rights, CancellationToken cancellationToken = default, string? recipientOrgNo = null)
         {
+            // Default to authentication level 3 for development/testing purposes
+            // This represents a medium-high security level typically used for [describe typical use case]
             return Task.FromResult((int?)3);
         }

18-21: Consider making the authentication level configurable.

Since this is a development service, it would be beneficial to make the authentication level configurable. This would allow testing different scenarios and authentication levels without code changes.

     public class AltinnAuthorizationDevService : IAltinnAuthorizationService
     {
+        private readonly int _defaultAuthLevel;
+
+        public AltinnAuthorizationDevService(int defaultAuthLevel = 3)
+        {
+            _defaultAuthLevel = defaultAuthLevel;
+        }
+
         // ... other methods ...

         public Task<int?> CheckUserAccessAndGetMinimumAuthLevel(string resourceId, List<ResourceAccessLevel> rights, CancellationToken cancellationToken = default, string? recipientOrgNo = null)
         {
-            return Task.FromResult((int?)3);
+            return Task.FromResult((int?)_defaultAuthLevel);
         }
src/Altinn.Correspondence.API/Models/LegacyCorrespondenceItemExt.cs (1)

41-41: Fix typo in XML documentation.

The word "minimum" is misspelled in the documentation comment.

-        /// The minumum authentication level required to view this correspondence
+        /// The minimum authentication level required to view this correspondence
src/Altinn.Correspondence.API/Models/LegacyCorrespondenceOverviewExt.cs (1)

21-22: Document default values for boolean properties.

The non-nullable boolean properties AuthorizedForSign and AllowDelete will default to false. Please document these default values in the XML comments to make the behavior explicit, especially since they control access permissions.

        /// <summary>
        /// Indicates if the user is authorized to sign the correspondence
+       /// Default value is false.
        /// </summary>
        [JsonPropertyName("authorizedForSign")]
        public bool AuthorizedForSign { get; set; }

        /// <summary>
        /// Indicates if the correspondence can be deleted
+       /// Default value is false.
        /// </summary>
        [JsonPropertyName("allowDelete")]
        public bool AllowDelete { get; set; }

Also applies to: 33-34

src/Altinn.Correspondence.Application/Helpers/CorrespondenceExtensions.cs (1)

34-37: Consider documenting status transition rules.

The valid statuses list would benefit from documentation explaining the allowed state transitions and the significance of each status, particularly how the Fetched status interacts with other states.

Add XML documentation explaining the status flow:

    public static bool IsAvailableForRecipient(this CorrespondenceStatus correspondenceStatus)
    {
+       // Valid status progression:
+       // Published -> Fetched -> Read/Replied/Confirmed -> Archived
+       // Reserved status is a special case that...
        List<CorrespondenceStatus> validStatuses =
        [
            CorrespondenceStatus.Published, CorrespondenceStatus.Fetched, CorrespondenceStatus.Read, CorrespondenceStatus.Replied,
            CorrespondenceStatus.Confirmed, CorrespondenceStatus.Archived, CorrespondenceStatus.Reserved
        ];
src/Altinn.Correspondence.API/Mappers/LegacyCorrespondenceOverviewMapper.cs (3)

11-11: Follow C# naming conventions.

Local variables should start with a lowercase letter.

-        var Correspondence = new LegacyCorrespondenceOverviewExt
+        var correspondence = new LegacyCorrespondenceOverviewExt

Also applies to: 40-40


26-26: Use invariant format for string conversion.

Specify the string format for ResourceId to ensure consistent output across different cultures.

-            ResourceId = correspondenceOverview.ResourceId.ToString(),
+            ResourceId = correspondenceOverview.ResourceId.ToString(System.Globalization.CultureInfo.InvariantCulture),

9-41: Consider breaking down the mapping method.

The method is quite long and handles multiple concerns. Consider breaking it down into smaller, focused methods for better maintainability.

Example structure:

private static void MapBasicProperties(LegacyCorrespondenceOverviewExt target, LegacyGetCorrespondenceOverviewResponse source)
{
    target.CorrespondenceId = source.CorrespondenceId;
    target.Status = (CorrespondenceStatusExt)source.Status;
    // ... other basic properties
}

private static void MapComplexProperties(LegacyCorrespondenceOverviewExt target, LegacyGetCorrespondenceOverviewResponse source)
{
    target.Content = source.Content != null 
        ? CorrespondenceContentMapper.MapToExternal(source.Content)
        : null;
    // ... other complex properties
}
Test/Altinn.Correspondence.Tests/NotificationTests.cs (1)

69-69: Fix double semicolon typo.

There's a double semicolon at the end of the line.

-var correspondenceId = JsonSerializer.Deserialize<InitializeCorrespondencesResponseExt>(responseContent, _responseSerializerOptions).Correspondences.First().CorrespondenceId;;
+var correspondenceId = JsonSerializer.Deserialize<InitializeCorrespondencesResponseExt>(responseContent, _responseSerializerOptions).Correspondences.First().CorrespondenceId;
.github/workflows/ci-cd.yaml (2)

Line range hint 46-138: Consider workflow optimization opportunities.

The current workflow structure has several areas for potential improvement:

  1. Consider creating a reusable workflow for deployment steps to reduce duplication across environments.
  2. Look into using environment files or composite actions to centralize common configuration.
  3. Consider adding deployment verification steps and explicit failure notifications.

Would you like assistance in creating a reusable workflow template?

🧰 Tools
🪛 yamllint

[error] 131-131: trailing spaces

(trailing-spaces)


[error] 135-135: trailing spaces

(trailing-spaces)


47-47: Remove trailing spaces.

There are trailing spaces on several lines that should be removed for consistency.

Affected lines: 47, 49, 131, 135

Also applies to: 49-49, 131-131, 135-135

🧰 Tools
🪛 yamllint

[error] 47-47: trailing spaces

(trailing-spaces)

src/Altinn.Correspondence.Integrations/Idporten/IdPortenXacmlMapper.cs (1)

131-157: LGTM! Consider adding documentation.

The implementation is clean and handles edge cases well. However, XML documentation would be beneficial for clarity on usage.

Add XML documentation to clarify the method's purpose and return value semantics:

+        /// <summary>
+        /// Extracts the minimum authentication level required from a XACML response.
+        /// </summary>
+        /// <param name="response">The XACML response containing authorization decisions</param>
+        /// <param name="user">The claims principal representing the authenticated user</param>
+        /// <returns>The minimum required authentication level if found; null if no level specified or decision is not Permit</returns>
         public static int? GetMinimumAuthLevel(XacmlJsonResponse response, ClaimsPrincipal user)
src/Altinn.Correspondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewHandler.cs (1)

50-54: Add logging when access is denied due to insufficient authentication level

When minimumAuthLevel is null, the method returns Errors.LegacyNoAccessToCorrespondence without logging the denial. Adding a log entry can aid in monitoring and troubleshooting access issues.

Apply this diff to include logging:

if (minimumAuthLevel == null)
{
+     _logger.LogWarning("Access denied: User does not meet the minimum authentication level for ResourceId {ResourceId}", correspondence.ResourceId);
      return Errors.LegacyNoAccessToCorrespondence;
}
src/Altinn.Correspondence.Integrations/Altinn/Authorization/AltinnAuthorizationService.cs (3)

48-55: Simplify null check and casting in validation

In the CheckUserAccess method, the null check and casting of validation can be simplified for better readability.

Consider using the HasValue and Value properties of nullable types:

var validation = await ValidateCheckUserAccess(user, resourceId, cancellationToken);
-if (validation != null) return (bool)validation;
+if (validation.HasValue) return validation.Value;

Line range hint 89-109: Add null check for user to prevent exceptions

The ValidateCheckUserAccess method uses user without null checks, which could lead to a NullReferenceException if user is null.

Add a null check for user before accessing its properties:

+if (user is null)
+{
+    _logger.LogError("User is null when checking access to resource");
+    return false;
+}

110-125: Log unsuccessful authorization requests for better debugging

When the authorization request fails in AuthorizeRequest, the method returns null without logging the failure, which can hinder troubleshooting.

Consider logging unsuccessful responses to aid in debugging:

if (!response.IsSuccessStatusCode)
{
+    _logger.LogError("Authorization request failed with status code {StatusCode}", response.StatusCode);
     return null;
}
Test/Altinn.Correspondence.Tests/CorrespondenceControllerTests.cs (1)

1070-1073: Rename variable confirmResponse to readResponse for clarity

In the test method UpdateCorrespondenceStatus_MarkAsRead_WithoutFetched_ReturnsBadRequest, the variable confirmResponse is used to store the response from the markasread endpoint. To improve readability and avoid confusion, consider renaming the variable to readResponse to reflect the action being tested.

Apply this diff to rename the variable:

- var confirmResponse = await _recipientClient.PostAsync($"correspondence/api/v1/correspondence/{correspondenceId}/markasread", null);
- Assert.Equal(HttpStatusCode.BadRequest, confirmResponse.StatusCode);
+ var readResponse = await _recipientClient.PostAsync($"correspondence/api/v1/correspondence/{correspondenceId}/markasread", null);
+ Assert.Equal(HttpStatusCode.BadRequest, readResponse.StatusCode);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between f6e7fa2 and 4336251.

📒 Files selected for processing (21)
  • .github/actions/update-infrastructure/action.yml (0 hunks)
  • .github/workflows/ci-cd.yaml (4 hunks)
  • Test/Altinn.Correspondence.Tests/CorrespondenceControllerTests.cs (7 hunks)
  • Test/Altinn.Correspondence.Tests/NotificationTests.cs (3 hunks)
  • src/Altinn.Correspondence.API/Controllers/LegacyCorrespondenceController.cs (3 hunks)
  • src/Altinn.Correspondence.API/Mappers/LegacyCorrespondenceOverviewMapper.cs (1 hunks)
  • src/Altinn.Correspondence.API/Models/LegacyCorrespondenceItemExt.cs (1 hunks)
  • src/Altinn.Correspondence.API/Models/LegacyCorrespondenceOverviewExt.cs (1 hunks)
  • src/Altinn.Correspondence.Application/DependencyInjection.cs (2 hunks)
  • src/Altinn.Correspondence.Application/Errors.cs (1 hunks)
  • src/Altinn.Correspondence.Application/GetCorespondences/LegacyGetCorrespondencesHandler.cs (1 hunks)
  • src/Altinn.Correspondence.Application/GetCorespondences/LegacyGetCorrespondencesResponse.cs (1 hunks)
  • src/Altinn.Correspondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewHandler.cs (4 hunks)
  • src/Altinn.Correspondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewResponse.cs (1 hunks)
  • src/Altinn.Correspondence.Application/Helpers/CorrespondenceExtensions.cs (1 hunks)
  • src/Altinn.Correspondence.Application/PurgeCorrespondence/PurgeCorrespondenceHandler.cs (1 hunks)
  • src/Altinn.Correspondence.Application/UpdateCorrespondenceStatus/UpdateCorrespondenceStatusHandler.cs (2 hunks)
  • src/Altinn.Correspondence.Core/Repositories/IAltinnAuthorizationService.cs (1 hunks)
  • src/Altinn.Correspondence.Integrations/Altinn/Authorization/AltinnAuthorizationDevService.cs (1 hunks)
  • src/Altinn.Correspondence.Integrations/Altinn/Authorization/AltinnAuthorizationService.cs (2 hunks)
  • src/Altinn.Correspondence.Integrations/Idporten/IdPortenXacmlMapper.cs (1 hunks)
💤 Files with no reviewable changes (1)
  • .github/actions/update-infrastructure/action.yml
✅ Files skipped from review due to trivial changes (2)
  • src/Altinn.Correspondence.Application/GetCorespondences/LegacyGetCorrespondencesHandler.cs
  • src/Altinn.Correspondence.Application/GetCorespondences/LegacyGetCorrespondencesResponse.cs
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/Altinn.Correspondence.API/Controllers/LegacyCorrespondenceController.cs
  • src/Altinn.Correspondence.Application/DependencyInjection.cs
🧰 Additional context used
📓 Learnings (1)
src/Altinn.Correspondence.Application/UpdateCorrespondenceStatus/UpdateCorrespondenceStatusHandler.cs (1)
Learnt from: CelineTrammi
PR: Altinn/altinn-correspondence#387
File: src/Altinn.Correspondence.Application/UpdateCorrespondenceStatus/UpdateCorrespondenceStatusHandler.cs:72-75
Timestamp: 2024-10-24T12:47:27.417Z
Learning: The `IsConfirmationNeeded` property in the `CorrespondenceEntity` class is no longer a required property.
🪛 yamllint
.github/workflows/ci-cd.yaml

[error] 47-47: trailing spaces

(trailing-spaces)


[error] 49-49: trailing spaces

(trailing-spaces)


[error] 131-131: trailing spaces

(trailing-spaces)


[error] 135-135: trailing spaces

(trailing-spaces)

🔇 Additional comments (31)
src/Altinn.Correspondence.Core/Repositories/IAltinnAuthorizationService.cs (1)

8-8: Verify the nullable return type design.

The nullable return type suggests that the method might return null in some cases. Let's verify if this is the intended behavior.

Consider whether returning a non-nullable int with exceptions for access denial might be more explicit:

// Alternative signature:
Task<int> CheckUserAccessAndGetMinimumAuthLevel(...); // Throws UnauthorizedAccessException if access is denied
✅ Verification successful

Based on the shell script results, I can now generate the final response as the implementation and usage patterns are clear.

The nullable return type is correctly designed and well-handled

The nullable int return type is intentional and properly implemented:

  • Returns null to indicate access denial in AltinnAuthorizationService
  • Consumers like LegacyGetCorrespondenceOverviewHandler explicitly handle the null case by returning an error
  • Dev service implementation maintains the contract by returning a nullable int
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check how the return value is handled in the implementation and usage

# Check implementation in dev and production services
echo "Checking service implementations:"
rg -A 10 "CheckUserAccessAndGetMinimumAuthLevel.*=.*" --type cs

# Check how the return value is handled by consumers
echo "\nChecking method usage:"
rg -A 5 "CheckUserAccessAndGetMinimumAuthLevel\(" --type cs

Length of output: 6818

src/Altinn.Correspondence.API/Models/LegacyCorrespondenceOverviewExt.cs (3)

1-11: LGTM! Well-structured class declaration with clear documentation.

The class is properly organized with appropriate namespaces, clear XML documentation, and follows naming conventions. The inheritance from CorrespondenceOverviewExt makes sense for legacy API compatibility.


15-40: Verify authorization checks before exposing sensitive data.

This model exposes several authorization-related properties (MinimumAuthenticationLevel, AuthorizedForSign, AllowDelete). Ensure proper authorization checks are implemented before returning this data to clients.

#!/bin/bash
# Look for authorization checks in handlers using this model
rg -A 5 "LegacyCorrespondenceOverviewExt.*=.*new" --type cs
rg -A 5 "IAuthorizationService|Authorize" --type cs

15-16: Consider making MinimumAuthenticationLevel nullable.

The non-nullable int could be problematic if there's no authentication level set. Consider using int? to explicitly indicate when no authentication level is specified, or document the default value's meaning.

src/Altinn.Correspondence.Application/Helpers/CorrespondenceExtensions.cs (1)

35-35: Verify state transition rules for Fetched status.

The addition of CorrespondenceStatus.Fetched to valid statuses is logical for enabling attachment downloads. However, let's verify the state transition rules.

✅ Verification successful

Let me analyze the results from the shell scripts to verify the state transition rules for the Fetched status.

From the search results, I can see:

  1. The status transitions are tracked in the database with timestamps (StatusChanged) and text descriptions (StatusText)
  2. The codebase maintains status history for both correspondence and attachments
  3. The IsAvailableForRecipient method in CorrespondenceExtensions.cs is the key validation point for status access
  4. The status transitions appear to be one-way (no reverting back to previous states)
  5. The order of statuses in the list represents the valid progression:
    • Published -> Fetched -> Read -> Replied
    • Each status change is timestamped and preserved in history

Based on this evidence, I can now generate the final response:

Addition of Fetched status is safe and follows existing patterns

The Fetched status is correctly positioned between Published and Read states in the valid status list. The codebase:

  • Maintains full status history with timestamps
  • Preserves state transition order
  • Allows correspondence to remain available after being fetched
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for state transition rules or documentation
# to ensure Fetched status is handled correctly

# Look for state transition documentation
echo "Searching for state transition documentation..."
rg -i "correspondence.*status.*transition" --type md

# Look for status enum definition to understand all possible states
echo "Searching for CorrespondenceStatus enum definition..."
ast-grep --pattern 'enum CorrespondenceStatus {
  $$$
}'

# Look for any validation or guard conditions around status transitions
echo "Searching for status transition validation..."
rg -A 5 "Status.*Changed|UpdateStatus|SetStatus"

Length of output: 120315

src/Altinn.Correspondence.API/Mappers/LegacyCorrespondenceOverviewMapper.cs (2)

1-5: LGTM! Clean and minimal imports.

The imports are well-organized and contain only the necessary dependencies.


7-8: LGTM! Appropriate class design.

The class is correctly designed as a static utility class with appropriate access level.

Test/Altinn.Correspondence.Tests/NotificationTests.cs (2)

Line range hint 42-58: LGTM! Good refactoring of client creation.

The change to use _factory.CreateClientWithAddedClaims improves code reuse and maintains consistent client creation across tests.


70-72: LGTM! Good enhancement to test reliability.

Adding the fetch operation before marking as read ensures the test follows the correct business logic flow and prevents potential ReadBeforeFetched errors.

src/Altinn.Correspondence.Application/PurgeCorrespondence/PurgeCorrespondenceHandler.cs (1)

92-92: LGTM! Consider verifying error handling in consumers.

The semantic change from CorrespondenceNotConfirmed to ArchiveBeforeConfirmed better describes the specific scenario where purging is blocked due to pending confirmation.

Let's verify if all consumers handle this error correctly:

src/Altinn.Correspondence.Integrations/Idporten/IdPortenXacmlMapper.cs (1)

131-157: Verify integration with attachment download logic.

Since this PR implements attachment download functionality, we should verify how this authentication level check is integrated with the download process.

Let's check for the usage of this method in the attachment download context:

✅ Verification successful

Let's gather more specific information about how the authentication level check is integrated with the download process.


Let's check the actual download handler implementation and authorization constants to understand the complete flow.


Based on the gathered information, I can now provide the final response:

Authentication level check is properly integrated with attachment download process

The implementation shows a secure multi-layer authorization approach for attachment downloads:

  • Controller level: Protected by [Authorize(Policy = AuthorizationConstants.Sender)] ensuring only authenticated senders can access
  • Handler level: Uses IAltinnAuthorizationService.CheckUserAccess which internally utilizes the GetMinimumAuthLevel check
  • Proper error handling for unauthorized access scenarios
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for references to GetMinimumAuthLevel in attachment download related code
rg -l "GetMinimumAuthLevel|DownloadAttachment" --type cs

# Look for any authorization checks in attachment handlers
ast-grep --pattern 'class $_ { 
  $$$
  Download$_($$$) {
    $$$
  }
  $$$
}'

Length of output: 1667


Script:

#!/bin/bash
# Check how GetMinimumAuthLevel is used in download handlers
rg -A 10 "GetMinimumAuthLevel" src/Altinn.Correspondence.Application/DownloadCorrespondenceAttachment/DownloadCorrespondenceAttachmentHandler.cs src/Altinn.Correspondence.Application/DownloadAttachment/DownloadAttachmentHandler.cs

# Check authorization service implementation
rg -A 10 "GetMinimumAuthLevel" src/Altinn.Correspondence.Integrations/Altinn/Authorization/AltinnAuthorizationService.cs

# Check attachment controller for authorization flow
rg -A 10 "Download" src/Altinn.Correspondence.API/Controllers/AttachmentController.cs

Length of output: 2968


Script:

#!/bin/bash
# Check download handler implementation
cat src/Altinn.Correspondence.Application/DownloadAttachment/DownloadAttachmentHandler.cs

# Check authorization constants
cat src/Altinn.Correspondence.Application/Configuration/AuthorizationConstants.cs

# Check if there are any specific authorization requirements in the request
cat src/Altinn.Correspondence.Application/DownloadAttachment/DownloadAttachmentRequest.cs

Length of output: 3558

src/Altinn.Correspondence.Application/Errors.cs (2)

49-49: LGTM! Improved error naming.

The rename from CorrespondenceNotConfirmed to ArchiveBeforeConfirmed makes the error more specific and clearer about the actual validation failure, while maintaining the same error code and message.


57-59: LGTM! Well-structured error definitions.

The new error definitions are:

  • Properly sequenced with unique error codes
  • Have clear, concise messages
  • Use appropriate HTTP status codes
  • Support the workflow requirements for correspondence operations

These additions align well with the PR's objective of implementing attachment download functionality.

src/Altinn.Correspondence.Application/UpdateCorrespondenceStatus/UpdateCorrespondenceStatusHandler.cs (2)

67-70: Good practice: Extracted validation logic into a separate method

Extracting the validation logic into ValidateUpdateRequest enhances readability and maintainability by isolating validation concerns from the main Process method.


85-100: Ensure all previous validation checks are preserved

The new ValidateUpdateRequest method centralizes status validation effectively. However, please verify that all validation conditions from the original Process method are included in this new method, especially any checks against invalid status transitions that may have been present before refactoring.

Run the following script to compare previous and current validation logic:

✅ Verification successful

All validation checks are properly preserved in the refactored code

After comparing both versions, I can confirm that all essential validation checks are present and properly handled. The new ValidateUpdateRequest method correctly encapsulates the status transition validations that were previously in the Process method, specifically:

  • Read status requires prior Fetched status
  • Confirm status requires prior Fetched status
  • Archive status requires prior Confirmed status (when confirmation is needed)

The other validations remain in the Process method as they deal with different concerns:

  • Correspondence existence
  • Authorization checks
  • Recipient validation
  • Status availability and purge checks
  • Marked unread handling
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Compare old and new validation logic to ensure all cases are covered.
# Expected result: All important validation checks are present in the new method.

# Fetch the previous version of the handler
git show HEAD~1:src/Altinn.Correspondence.Application/UpdateCorrespondenceStatus/UpdateCorrespondenceStatusHandler.cs > old_handler.cs

# Extract validation conditions from the old handler
grep -E 'if\s*\(' old_handler.cs > old_validations.txt

# Extract validation conditions from the new ValidateUpdateRequest method
grep -E 'if\s*\(' -A 5 src/Altinn.Correspondence.Application/UpdateCorrespondenceStatus/UpdateCorrespondenceStatusHandler.cs | grep -A 5 'private static Error\?' > new_validations.txt

# Compare the old and new validations
diff old_validations.txt new_validations.txt

Length of output: 1285


Script:

#!/bin/bash
# Let's get both the old and new handler content for a proper comparison
echo "=== Previous version ==="
git show HEAD~1:src/Altinn.Correspondence.Application/UpdateCorrespondenceStatus/UpdateCorrespondenceStatusHandler.cs

echo -e "\n=== Current version ==="
cat src/Altinn.Correspondence.Application/UpdateCorrespondenceStatus/UpdateCorrespondenceStatusHandler.cs

Length of output: 12439

src/Altinn.Correspondence.Application/GetCorrespondenceOverview/LegacyGetCorrespondenceOverviewHandler.cs (5)

12-12: Consistency in response types

Updating the handler to use LegacyGetCorrespondenceOverviewResponse ensures alignment with the new response model and enhances code clarity.


33-33: Update method return type to match new response model

Changing the return type of the Process method to OneOf<LegacyGetCorrespondenceOverviewResponse, Error> reflects the updated response structure and maintains consistency.


37-37: Appropriate use of InvalidPartyId error

Returning Errors.InvalidPartyId when the PartyId is invalid provides precise feedback to the caller about the nature of the error.


126-126: Verify the safe casting of minimumAuthLevel to int

Ensure that minimumAuthLevel can be safely cast to an int without risking data loss or runtime exceptions. If minimumAuthLevel is already an int or an enum with underlying int values, the cast is appropriate.


43-43: 🛠️ Refactor suggestion

Use a more general error code when party information is missing

When userParty is null or lacks identification numbers, returning Errors.CouldNotFindOrgNo might not accurately represent the issue, especially for individuals without an organization number. Consider using a more general error code like Errors.PartyNotFound to improve clarity.

Apply this diff to enhance error handling:

if (userParty == null || (string.IsNullOrEmpty(userParty.SSN) && string.IsNullOrEmpty(userParty.OrgNumber)))
{
-    return Errors.CouldNotFindOrgNo;
+    return Errors.PartyNotFound;
}

Likely invalid or redundant comment.

src/Altinn.Correspondence.Integrations/Altinn/Authorization/AltinnAuthorizationService.cs (1)

75-88: Verify unrestricted access in development environment

In the CheckMigrationAccess method, returning true when running in a development environment may pose security risks if not handled carefully.

Please ensure that granting full access in development is intentional and complies with security policies.

Test/Altinn.Correspondence.Tests/CorrespondenceControllerTests.cs (10)

872-872: Test correctly verifies status remains Published after recipient retrieval

The assertion ensures that the correspondence status remains Published even after the recipient fetches the correspondence overview, which is the expected behavior.


897-897: Test confirms status remains Published for sender accessing correspondence

The test correctly verifies that when the sender accesses the correspondence overview, the status remains Published and the Fetched status is not added to the status history.


991-991: Test ensures status remains Published when sender fetches details

The assertion correctly checks that the status remains Published when the sender retrieves the correspondence details, and that the Fetched status is not recorded in the status history.


Line range hint 995-1007: Test verifies 404 response for non-existent correspondence

The test method UpdateCorrespondenceStatus_CorrespondenceNotExists_Return404 appropriately checks that attempts to update the status of a non-existent correspondence return a 404 Not Found response.


1008-1025: Test validates 404 response when updating unpublished correspondence

The test UpdateCorrespondenceStatus_CorrespondenceNotPublished_Return404 correctly ensures that attempting to update the status of an unpublished correspondence results in a 404 Not Found response.


1030-1055: Test verifies successful status updates on published correspondence

The test UpdateCorrespondenceStatus_CorrespondencePublished_ReturnOk effectively confirms that status updates (mark as read, mark as unread) on a published correspondence return 200 OK and the correspondence status updates appropriately.


1089-1092: Test correctly handles BadRequest when confirming without fetching

The test UpdateCorrespondenceStatus_ToConfirmed_WithoutFetched_ReturnsBadRequest appropriately verifies that attempting to confirm a correspondence without first fetching it results in a 400 Bad Request.


1108-1113: Test confirms successful confirmation after fetching correspondence

The test UpdateCorrespondenceStatus_ToConfirmed_WhenCorrespondenceIsFetched_GivesOk accurately checks that confirming a fetched correspondence succeeds with a 200 OK response.


1152-1155: Test verifies successful archival after confirmation

In UpdateCorrespondenceStatus_ToArchived_WithConfirmation_WhenConfirmationNeeded_GivesOk, the test correctly ensures that after fetching and confirming a correspondence requiring confirmation, archiving it succeeds.


1336-1338: Test confirms deletion of confirmed correspondence requiring confirmation

The test Delete_Published_Correspondence_WithConfirmation_WhenConfirmationNeeded_Gives_OK appropriately verifies that after fetching and confirming a correspondence that requires confirmation, deleting it returns 200 OK.

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 (3)
src/Altinn.Correspondence.Application/DownloadCorrespondenceAttachment/LegacyDownloadCorrespondenceAttachmentHandler.cs (3)

8-8: Remove unused import.

The ReverseMarkdown.Converters import is not used in this file.

-using ReverseMarkdown.Converters;

57-61: Consider using authorization service for recipient check.

The recipient check is currently done by direct comparison, but this logic should ideally be moved to the authorization service for better separation of concerns and future extensibility.

-        bool isRecipient = correspondence.Recipient == party.OrgNumber || correspondence.Recipient == party.SSN;
-        if (!isRecipient)
-        {
-            return Errors.CorrespondenceNotFound;
-        }
+        var isRecipient = await _altinnAuthorizationService.IsRecipient(correspondence, party);
+        if (!isRecipient)
+        {
+            return Errors.CorrespondenceNotFound;
+        }

67-68: Consider moving background job to a separate method.

The background job enqueuing logic could be moved to a separate private method for better readability and maintainability.

         var attachmentStream = await _storageRepository.DownloadAttachment(attachment.Id, cancellationToken);
-        _backgroundJobClient.Enqueue<IDialogportenService>((dialogportenService) => dialogportenService.CreateInformationActivity(request.CorrespondenceId, DialogportenActorType.Recipient, DialogportenTextType.DownloadStarted, attachment.FileName ?? attachment.Name));
+        await EnqueueDownloadActivity(request.CorrespondenceId, attachment.FileName ?? attachment.Name);

Add the following private method:

private Task EnqueueDownloadActivity(Guid correspondenceId, string fileName)
{
    _backgroundJobClient.Enqueue<IDialogportenService>((dialogportenService) => 
        dialogportenService.CreateInformationActivity(
            correspondenceId,
            DialogportenActorType.Recipient,
            DialogportenTextType.DownloadStarted,
            fileName));
    
    return Task.CompletedTask;
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 4336251 and 6775d67.

📒 Files selected for processing (2)
  • src/Altinn.Correspondence.Application/DownloadCorrespondenceAttachment/LegacyDownloadCorrespondenceAttachmentHandler.cs (1 hunks)
  • src/Altinn.Correspondence.Application/Helpers/UserClaimsHelper.cs (2 hunks)
🧰 Additional context used
📓 Learnings (1)
src/Altinn.Correspondence.Application/DownloadCorrespondenceAttachment/LegacyDownloadCorrespondenceAttachmentHandler.cs (4)
Learnt from: CelineTrammi
PR: Altinn/altinn-correspondence#421
File: src/Altinn.Correspondence.Application/DownloadCorrespondenceAttachment/LegacyDownloadCorrespondenceAttachmentHandler.cs:52-52
Timestamp: 2024-11-01T13:32:16.888Z
Learning: When reviewing pull requests in the `Altinn/altinn-correspondence` repository, suggestions for adding error handling may be considered outside the scope if they are not directly related to the PR's objectives.
Learnt from: CelineTrammi
PR: Altinn/altinn-correspondence#421
File: src/Altinn.Correspondence.Application/DownloadCorrespondenceAttachment/LegacyDownloadCorrespondenceAttachmentHandler.cs:31-51
Timestamp: 2024-11-01T13:31:21.051Z
Learning: In the `LegacyDownloadCorrespondenceAttachmentHandler.Process` method in `src/Altinn.Correspondence.Application/DownloadCorrespondenceAttachment/LegacyDownloadCorrespondenceAttachmentHandler.cs`, when request parameters are omitted, a 404 is returned, so explicit request validation may not be necessary.
Learnt from: Ceredron
PR: Altinn/altinn-correspondence#368
File: src/Altinn.Correspondence.Application/MigrateCorrespondenceAttachment/MigrateUploadAttachmentHandler.cs:39-39
Timestamp: 2024-10-21T09:58:25.465Z
Learning: In the `Altinn.Correspondence.Application` codebase, error handling is performed using `OneOf` result types instead of exceptions.
Learnt from: Ceredron
PR: Altinn/altinn-correspondence#368
File: src/Altinn.Correspondence.Application/UploadAttachment/UploadAttachmentHandler.cs:10-10
Timestamp: 2024-10-21T10:04:04.975Z
Learning: In the Altinn.Correspondence application, when injecting dependencies such as `UploadHelper`, it's acceptable to inject the concrete class directly without defining an interface, especially when it is a dependency inside the same project.
🔇 Additional comments (3)
src/Altinn.Correspondence.Application/Helpers/UserClaimsHelper.cs (2)

21-21: LGTM! Constant follows established patterns.

The constant follows the class's naming conventions and uses the correct URN format for Altinn claims.


30-34: Verify party ID validation in authorization flow.

The current implementation might need additional validation:

  1. Ensure downstream code properly handles null returns for authorization decisions
  2. Consider validating that the party ID is a positive number

Let's verify the usage context:

src/Altinn.Correspondence.Application/DownloadCorrespondenceAttachment/LegacyDownloadCorrespondenceAttachmentHandler.cs (1)

34-73: LGTM with minor suggestions.

The overall implementation looks good:

  • Proper error handling using OneOf
  • Comprehensive validation steps
  • Proper null checks
  • Correct usage of cancellation token

Note: As mentioned in the PR objectives, authorization will be addressed in a subsequent PR.

Ceredron and others added 6 commits November 5, 2024 14:35
…irmed (#427)

* fix: validate correspondence has been fetched before it can be read and confirmed

* update tests

* typo fix

* Handle potential null value for IsConfirmationNeeded

* reuse factory for client initialization

* rename testname

* add Fetched to statuses available for Recipient
@CelineTrammi CelineTrammi merged commit 4cb90ac into main Nov 6, 2024
6 checks passed
@CelineTrammi CelineTrammi deleted the feat/legacy-download-correspondence-attachment branch November 6, 2024 09:28
@coderabbitai coderabbitai bot mentioned this pull request Nov 8, 2024
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants