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

Make Authorization service more testable by passing ClaimsPrincipal as argument #589

Merged
merged 2 commits into from
Nov 19, 2024

Conversation

Ceredron
Copy link
Collaborator

@Ceredron Ceredron commented Nov 19, 2024

Description

Pass ClaimsPrincipal as argument instead of HttpContextAccessor to make code cleaner and easier to test

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

    • Enhanced user context handling in file transfer and resource management operations.
    • Improved access control by incorporating user claims into various processing methods.
  • Bug Fixes

    • Adjusted error handling to ensure proper logging and responses based on user context during file operations.
  • Documentation

    • Updated method signatures across multiple classes to reflect the inclusion of user context.
  • Refactor

    • Streamlined dependency management in authorization services by removing unnecessary HTTP context dependencies.
  • Tests

    • Updated test setups to accommodate changes in method signatures for user access checks.

Copy link

coderabbitai bot commented Nov 19, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

The pull request introduces significant modifications across multiple controllers and handler classes to incorporate user context into various file transfer and resource management operations. The changes primarily involve updating method signatures to include HttpContext.User or ClaimsPrincipal? user as parameters in processing methods. This adjustment enhances the ability to perform user-specific access checks and ensures that user information is consistently passed throughout the operations.

Changes

File Change Summary
src/Altinn.Broker.API/Controllers/FileTransferController.cs Updated multiple method signatures to include HttpContext.User as a parameter in methods such as InitializeFileTransfer, UploadStreamed, GetFileTransferOverview, and others.
src/Altinn.Broker.API/Controllers/LegacyFileController.cs Updated method signatures to include HttpContext.User in methods like InitializeFile, UploadFileStreamed, GetFileOverview, and others.
src/Altinn.Broker.API/Controllers/MalwareScanResultsController.cs Changed the ProcessMalwareScanResult method to pass null instead of result as the second parameter in the handler.Process method call.
src/Altinn.Broker.API/Controllers/ResourceController.cs Modified the ConfigureResource method to include HttpContext.User as a parameter in the handler.Process method call.
src/Altinn.Broker.Application/ConfigureResource/ConfigureResourceHandler.cs Updated the Process method signature to include ClaimsPrincipal? user, affecting access control logic.
src/Altinn.Broker.Application/ConfirmDownload/ConfirmDownloadHandler.cs Updated Process method to include ClaimsPrincipal? user, modifying access checks to utilize this parameter.
src/Altinn.Broker.Application/DownloadFile/DownloadFileHandler.cs Modified Process method to include ClaimsPrincipal? user, affecting user access verification.
src/Altinn.Broker.Application/ExpireFileTransfer/ExpireFileTransferHandler.cs Updated Process method to include ClaimsPrincipal? user, allowing for user claims access.
src/Altinn.Broker.Application/GetFileTransferDetails/GetFileTransferDetailsHandler.cs Updated Process method to include ClaimsPrincipal? user, modifying access checks to utilize the user context.
src/Altinn.Broker.Application/GetFileTransferOverview/GetFileTransferOverviewHandler.cs Updated Process method to include ClaimsPrincipal? user, affecting user access checks.
src/Altinn.Broker.Application/GetFileTransfers/GetFileTransfersHandler.cs Updated Process method to include ClaimsPrincipal? user, enhancing access control logic.
src/Altinn.Broker.Application/GetFileTransfers/LegacyGetFilesHandler.cs Updated Process method to include ClaimsPrincipal? user, allowing for user context in processing.
src/Altinn.Broker.Application/IHandler.cs Updated Process method signature in the interface to include ClaimsPrincipal? user.
src/Altinn.Broker.Application/InitializeFileTransfer/InitializeFileTransferHandler.cs Updated Process method to include ClaimsPrincipal? user, affecting access control checks.
src/Altinn.Broker.Application/MalwareScanResults/MalwareScanResultHandler.cs Updated Process method to include ClaimsPrincipal? user, allowing for user context during processing.
src/Altinn.Broker.Application/UploadFile/UploadFileHandler.cs Updated Process method to include ClaimsPrincipal? user, modifying user access verification logic.
src/Altinn.Broker.Core/Repositories/IAuthorizationService.cs Updated CheckUserAccess method signature to include ClaimsPrincipal? user as the first parameter.
src/Altinn.Broker.Integrations/Altinn/Authorization/AltinnAuthorizationService.cs Removed IHttpContextAccessor from constructor; updated CheckUserAccess method to accept ClaimsPrincipal? user.
tests/Altinn.Broker.Tests/Helpers/CustomWebApplicationFactory.cs Updated CheckUserAccess mock method signature to accept ClaimsPrincipal? instead of a string.

Possibly related PRs

Suggested labels

kind/bug

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 08848fc and 21d1fe7.

📒 Files selected for processing (2)
  • src/Altinn.Broker.Application/ConfirmDownload/ConfirmDownloadHandler.cs (4 hunks)
  • src/Altinn.Broker.Application/MalwareScanResults/MalwareScanResultHandler.cs (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Altinn.Broker.Application/MalwareScanResults/MalwareScanResultHandler.cs
🔇 Additional comments (3)
src/Altinn.Broker.Application/ConfirmDownload/ConfirmDownloadHandler.cs (3)

32-32: LGTM! Method signature change enhances testability.

The addition of ClaimsPrincipal? user parameter aligns well with the PR objective of making the Authorization service more testable by explicitly passing user context instead of using HttpContextAccessor.

Note: There's an existing review comment about adding null checks for the user parameter, which is still valid.


40-42: LGTM! Access check implementation is appropriate.

The implementation correctly uses the user parameter for access verification and handles access denial appropriately.

Note: There's an existing review comment about ensuring CheckUserAccess handles nullable user parameter appropriately, which is still valid.


83-83: LGTM! Explicitly passing null user to background jobs is appropriate.

Passing null for the user parameter in background jobs is a good practice because:

  1. Background jobs run in a different security context
  2. User claims shouldn't be persisted in background jobs for security reasons
  3. The null value makes it explicit that there's no user context

Also applies to: 92-92


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.

@Ceredron Ceredron added the kind/chore Routine task or minor maintenance work that doesn't introduce new features or functionality label Nov 19, 2024
@Ceredron Ceredron marked this pull request as ready for review November 19, 2024 09:08
Copy link

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

🧹 Outside diff range and nitpick comments (21)
src/Altinn.Broker.Application/IHandler.cs (1)

10-10: LGTM! Well-designed interface change

The modification to pass ClaimsPrincipal explicitly is a solid architectural improvement that:

  • Makes dependencies explicit and visible at the interface level
  • Removes hidden coupling to HttpContext
  • Improves testability by allowing direct injection of user claims
  • Maintains flexibility with nullable user parameter

Remember to handle null user cases appropriately in implementations.

src/Altinn.Broker.Core/Repositories/IAuthorizationService.cs (1)

8-8: Excellent architectural improvement!

This change significantly improves the testability and maintainability of the authorization service by:

  • Making the user context explicit instead of relying on HttpContext
  • Supporting dependency injection principles
  • Enabling easier mocking in unit tests
  • Maintaining backward compatibility with nullable user parameter

The parameter ordering is also logical, placing the user context first followed by operation-specific parameters.

Consider documenting these key points in the XML documentation for the interface:

  • The purpose of the nullable user parameter
  • The relationship between IsLegacyUser and user parameter
  • The expected behavior when user is null
src/Altinn.Broker.Application/GetFileTransferOverview/GetFileTransferOverviewHandler.cs (1)

Read access alone is sufficient for file transfer overview

Based on the codebase analysis, the GetFileTransferOverview operation should only require Read access. This is supported by:

  1. The operation is purely a read operation that retrieves and returns file transfer details
  2. Similar read operations in the codebase like DownloadFileHandler only require Read access
  3. Write access is typically required only for operations that modify state, such as:
    • UploadFileHandler: Write access only
    • InitializeFileTransferHandler: Write access only

Recommendation: Remove ResourceAccessLevel.Write from the access check to follow the principle of least privilege.

🔗 Analysis chain

Line range hint 29-33: Verify if both Write and Read access levels are required

The code checks for both Write and Read access levels. This seems broad - consider if the file transfer overview operation really needs Write access or if Read access alone would be sufficient.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other usages of GetFileTransferOverview to understand the access pattern
rg -A 5 "GetFileTransferOverview" 

# Search for other CheckUserAccess calls to compare access level patterns
ast-grep --pattern 'CheckUserAccess($$$, $$$, new List<ResourceAccessLevel> { $$$'

Length of output: 137


Script:

#!/bin/bash
# Search for GetFileTransferOverview in controller/API endpoints
rg -A 10 "GetFileTransferOverview" --type cs

# Search for similar file transfer operations to understand access patterns
rg -A 5 "FileTransfer.*Controller" --type cs

# Look for other CheckUserAccess usage patterns
rg -A 3 "CheckUserAccess" --type cs

Length of output: 20973

src/Altinn.Broker.API/Controllers/ResourceController.cs (1)

Line range hint 23-41: Consider enhancing testability further with interface-based dependency injection.

While passing ClaimsPrincipal directly improves testability, the method could be even more testable with a few additional improvements:

- public async Task<ActionResult> ConfigureResource(
+ public virtual async Task<ActionResult> ConfigureResource(
    string resourceId,
    [FromBody] ResourceExt resourceExt,
    [ModelBinder(typeof(MaskinportenModelBinder))] CallerIdentity token,
-   [FromServices] ConfigureResourceHandler handler,
+   [FromServices] IConfigureResourceHandler handler,
    CancellationToken cancellationToken)

These changes would:

  1. Make the method virtual to allow mocking in tests
  2. Use an interface for the handler to follow dependency inversion principle
src/Altinn.Broker.Application/GetFileTransferDetails/GetFileTransferDetailsHandler.cs (1)

Line range hint 28-32: Consider making access levels configurable

While the authorization check correctly uses the new user parameter, consider extracting the required access levels to a configuration or constant to improve maintainability and reusability.

+private static readonly IReadOnlyList<ResourceAccessLevel> RequiredAccessLevels = new[] 
+{ 
+    ResourceAccessLevel.Write, 
+    ResourceAccessLevel.Read 
+};

-var hasAccess = await resourceRightsRepository.CheckUserAccess(user, fileTransfer.ResourceId, new List<ResourceAccessLevel> { ResourceAccessLevel.Write, ResourceAccessLevel.Read }, cancellationToken: cancellationToken);
+var hasAccess = await resourceRightsRepository.CheckUserAccess(user, fileTransfer.ResourceId, RequiredAccessLevels, cancellationToken: cancellationToken);
src/Altinn.Broker.Application/GetFileTransfers/GetFileTransfersHandler.cs (2)

Line range hint 17-56: Consider adding XML documentation for the updated method

The Process method would benefit from XML documentation that describes the new user parameter and its role in authorization.

+    /// <summary>
+    /// Processes a request to get file transfers
+    /// </summary>
+    /// <param name="request">The file transfer request parameters</param>
+    /// <param name="user">The claims principal representing the authenticated user</param>
+    /// <param name="cancellationToken">Cancellation token</param>
+    /// <returns>A list of file transfer GUIDs or an error</returns>
     public async Task<OneOf<List<Guid>, Error>> Process(GetFileTransfersRequest request, ClaimsPrincipal? user, CancellationToken cancellationToken)

Line range hint 17-56: Consider adding unit tests for authorization scenarios

Since this change is aimed at improving testability, we should ensure comprehensive test coverage for various authorization scenarios.

Would you like me to help generate unit tests covering:

  • Authorized user access
  • Unauthorized user access
  • Null user handling
  • Various combinations of search parameters with different user contexts
src/Altinn.Broker.Application/GetFileTransfers/LegacyGetFilesHandler.cs (1)

Line range hint 37-37: Address the TODO comment about performance optimization

The comment raises a valid question about the query strategy. The current implementation might not be optimal for scenarios with multiple recipients.

Would you like me to help analyze the performance implications of both approaches and propose a solution? I can:

  1. Compare the performance characteristics of multiple single queries vs. one combined query
  2. Provide a concrete implementation for the preferred approach
src/Altinn.Broker.API/Controllers/MalwareScanResultsController.cs (1)

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

The webhook endpoint should implement Event Grid's authentication mechanism

The endpoint currently lacks any authentication mechanism, while the codebase shows JWT bearer authentication is used for other endpoints. For Event Grid webhooks:

  • The endpoint already implements the subscription validation handshake, but the TODO comment correctly identifies that source validation is missing
  • Event Grid provides built-in security mechanisms that should be implemented:
    1. Event validation using the webhook validation handshake (already present)
    2. Source validation by checking the Event Grid topic ID against allowed sources
    3. Optional: Add the aeg-subscription-name header validation
🔗 Analysis chain

Line range hint 1-65: Verify if this endpoint needs authorization

Since this is a webhook endpoint called by Azure Event Grid, we should verify if it needs any user-based authorization at all. The endpoint should likely be secured using Event Grid's built-in authentication mechanisms instead.

Let's check if this endpoint has any authorization attributes:


Let me gather more information about the authentication mechanisms in the codebase:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for authorization attributes and similar endpoints
# Look for other webhook endpoints and their authorization patterns
rg -B 5 -A 10 "Route\(\"broker/api/v1/webhooks" 

# Check for Event Grid validation logic in similar controllers
ast-grep --pattern 'if \(eventData is SubscriptionValidationEventData'

Length of output: 1908


Script:

#!/bin/bash
# Check for any authentication middleware or configuration
rg -B 5 -A 5 "UseAuthentication|AddAuthentication|AuthenticationBuilder" 

# Look for any Event Grid specific validation or authentication code
rg -B 5 -A 5 "EventGrid|WebhookValidation|EventValidation"

# Check for any security attributes on controllers or endpoints
ast-grep --pattern '[Authorize]'

Length of output: 15629

src/Altinn.Broker.Application/DownloadFile/DownloadFileHandler.cs (1)

Line range hint 35-39: Consider adding null check for user parameter

While the authorization check is properly placed, consider adding a null check for defensive programming. This would make the behavior explicit when no user context is provided.

Here's a suggested improvement:

-        var hasAccess = await resourceRightsRepository.CheckUserAccess(user, fileTransfer.ResourceId, new List<ResourceAccessLevel> { ResourceAccessLevel.Read }, request.IsLegacy, cancellationToken);
+        if (user == null)
+        {
+            return Errors.NoAccessToResource;
+        }
+        var hasAccess = await resourceRightsRepository.CheckUserAccess(user, fileTransfer.ResourceId, new List<ResourceAccessLevel> { ResourceAccessLevel.Read }, request.IsLegacy, cancellationToken);
         if (!hasAccess)
         {
             return Errors.NoAccessToResource;
         };
src/Altinn.Broker.Application/MalwareScanResults/MalwareScanResultHandler.cs (2)

27-27: Consider adding XML documentation for the new parameter.

The signature change aligns well with making the service more testable. Consider adding XML documentation to explain when the user parameter might be null and its usage.

+    /// <param name="user">The claims principal representing the user context. Can be null for system operations.</param>

Line range hint 69-77: Remove or relocate the unrelated Foo class.

The Foo class appears to be unrelated to the MalwareScanResultHandler and violates the single responsibility principle. If this class is needed, it should be moved to its own file.

-public class Foo
-{
-    private readonly IFileTransferRepository _fileTransferRepository;
-    public Foo(IFileTransferRepository fileTransferRepository)
-    {
-        _fileTransferRepository = fileTransferRepository;
-    }
-}
src/Altinn.Broker.Integrations/Altinn/Authorization/AltinnAuthorizationService.cs (3)

Line range hint 34-52: Remove duplicate null check for user parameter

There are two separate null checks for the user parameter with different behaviors:

  1. First check throws InvalidOperationException
  2. Second check logs error and returns false

This inconsistency could lead to confusion and potential bugs since the second check is unreachable.

Suggested fix:

 public async Task<bool> CheckUserAccess(ClaimsPrincipal? user, string resourceId, List<ResourceAccessLevel> rights, bool IsLegacyUser = false, CancellationToken cancellationToken = default)
 {
     if (user is null)
     {
         throw new InvalidOperationException("This operation cannot be called outside an authenticated HttpContext");
     }
     if (IsLegacyUser || _hostEnvironment.IsDevelopment())
     {
         return true;
     }
     var resource = await _resourceRepository.GetResource(resourceId, cancellationToken);
     if (resource is null)
     {
         return false;
     }
-    if (user is null)
-    {
-        _logger.LogError("Unexpected null value. User was null when checking access to resource");
-        return false;
-    }

Line range hint 40-43: Add logging for authorization bypasses

The method silently bypasses authorization checks for legacy users and development environment. This should be logged for security auditing purposes.

Suggested enhancement:

     if (IsLegacyUser || _hostEnvironment.IsDevelopment())
     {
+        _logger.LogWarning("Authorization check bypassed: IsLegacyUser={isLegacy}, IsDevelopment={isDev}",
+            IsLegacyUser, _hostEnvironment.IsDevelopment());
         return true;
     }

Line range hint 53-65: Enhance error logging for authorization failures

The error handling could be improved by adding more context to log messages when authorization fails.

Suggested enhancement:

     var response = await _httpClient.PostAsJsonAsync("authorization/api/v1/authorize", jsonRequest, cancellationToken);
     if (!response.IsSuccessStatusCode)
     {
+        _logger.LogError("Authorization API request failed with status code {StatusCode}", response.StatusCode);
         return false;
     }
     var responseContent = await response.Content.ReadFromJsonAsync<XacmlJsonResponse>(cancellationToken: cancellationToken);
     if (responseContent is null)
     {
-        _logger.LogError("Unexpected null or invalid json response from Authorization.");
+        var rawContent = await response.Content.ReadAsStringAsync(cancellationToken);
+        _logger.LogError("Failed to deserialize authorization response. Content: {Content}", rawContent);
         return false;
     }
src/Altinn.Broker.Application/ExpireFileTransfer/ExpireFileTransferHandler.cs (1)

Line range hint 25-63: Consider refactoring for better maintainability and documentation

The Process method handles multiple responsibilities and could benefit from some improvements:

  1. Consider extracting the file deletion and status update logic into separate methods
  2. Error messages could be more specific (e.g., include file transfer ID in the expiration error)
  3. The force parameter's purpose and implications should be documented

Here's a suggested refactoring approach:

+ /// <summary>
+ /// Processes the expiration of a file transfer
+ /// </summary>
+ /// <param name="request">The expiration request</param>
+ /// <param name="user">The user initiating the request</param>
+ /// <param name="cancellationToken">Cancellation token</param>
+ /// <param name="force">When true, allows expiration regardless of the expiration time</param>
+ /// <returns>A task representing the asynchronous operation</returns>
    public async Task<OneOf<Task, Error>> Process(ExpireFileTransferRequest request, 
        ClaimsPrincipal? user, CancellationToken cancellationToken)
    {
        logger.LogInformation("Deleting file transfer with id {fileTransferId}", 
            request.FileTransferId.ToString());
            
        var fileTransfer = await GetFileTransferAsync(request.FileTransferId, cancellationToken);
        var resource = await GetResource(fileTransfer.ResourceId, cancellationToken);
        var serviceOwner = await GetServiceOwnerAsync(resource.ServiceOwnerId);

-       if (fileTransfer.FileTransferStatusEntity.Status == Core.Domain.Enums.FileTransferStatus.Purged)
+       if (await IsPurged(fileTransfer))
        {
            logger.LogInformation("FileTransfer has already been set to purged");
        }
-       if (request.Force || fileTransfer.ExpirationTime < DateTime.UtcNow)
+       if (CanExpire(request.Force, fileTransfer))
        {
-           await brokerStorageService.DeleteFile(serviceOwner, fileTransfer, cancellationToken);
-           if (!request.DoNotUpdateStatus)
-           {
-               await TransactionWithRetriesPolicy.Execute(async (cancellationToken) =>
-               {
-                   await fileTransferStatusRepository.InsertFileTransferStatus(/*...*/);
-                   await eventBus.Publish(/*...*/);
-                   return Task.CompletedTask;
-               }, logger, cancellationToken);
-           }
+           await DeleteFileAndUpdateStatus(serviceOwner, fileTransfer, 
+               request.DoNotUpdateStatus, cancellationToken);
            
-           return TransactionWithRetriesPolicy.Execute(async (cancellationToken) =>
-           {
-               var recipientsWhoHaveNotDownloaded = fileTransfer.RecipientCurrentStatuses
-                   .Where(latestStatus => 
-                       latestStatus.Status < Core.Domain.Enums.ActorFileTransferStatus.DownloadConfirmed)
-                   .ToList();
-               foreach (var recipient in recipientsWhoHaveNotDownloaded)
-               {
-                   logger.LogError(/*...*/);
-                   await eventBus.Publish(/*...*/);
-               }
-               if (recipientsWhoHaveNotDownloaded.Count > 0) 
-                   await eventBus.Publish(/*...*/);
-               return Task.CompletedTask;
-           }, logger, cancellationToken);
+           return await NotifyUndownloadedRecipients(fileTransfer, cancellationToken);
        }
        
-       throw new Exception("FileTransfer has not expired, and should not be purged");
+       throw new InvalidOperationException(
+           $"FileTransfer {request.FileTransferId} has not expired and force parameter is not set");
    }

+   private async Task<bool> IsPurged(FileTransferEntity fileTransfer) =>
+       fileTransfer.FileTransferStatusEntity.Status == 
+           Core.Domain.Enums.FileTransferStatus.Purged;

+   private bool CanExpire(bool force, FileTransferEntity fileTransfer) =>
+       force || fileTransfer.ExpirationTime < DateTime.UtcNow;
src/Altinn.Broker.API/Controllers/LegacyFileController.cs (2)

81-81: Consistent implementation of ClaimsPrincipal across handlers

The changes consistently add HttpContext.User to all handler.Process calls, which is a good systematic approach to implementing claims-based authorization. This aligns well with the PR objective of improving testability.

Consider documenting this architectural change in your technical documentation to help other developers understand:

  1. The transition from token-based to claims-based authorization
  2. How to properly mock ClaimsPrincipal in tests
  3. The relationship between CallerIdentity and ClaimsPrincipal

Also applies to: 110-110, 163-163, 191-191, 219-219


Line range hint 1-234: Well-structured controller with clean separation of concerns

The controller demonstrates good design practices:

  • Each operation has its dedicated handler (SOLID principles)
  • Consistent error handling using the Problem pattern
  • Clean separation of legacy compatibility layer
  • Proper use of dependency injection

The addition of claims-based authorization fits naturally into this structure.

Consider adding XML documentation to the handler.Process calls to document the role of ClaimsPrincipal parameter:

 var commandResult = await handler.Process(new UploadFileRequest()
 {
     FileTransferId = fileTransferId,
     Token = legacyToken,
     UploadStream = Request.Body,
     IsLegacy = true
-}, HttpContext.User, cancellationToken);
+}, HttpContext.User, // Used for claims-based authorization
+   cancellationToken);
src/Altinn.Broker.API/Controllers/FileTransferController.cs (3)

Line range hint 116-129: Fix error handling in initialization result

The error handling for the initialization result needs attention:

  1. The current code continues execution even when initialization fails
  2. The Problem() result is not being returned

Apply this fix:

  var initializeResult = await initializeFileTransferHandler.Process(initializeRequest, HttpContext.User, cancellationToken);
  if (initializeResult.IsT1)
  {
-     Problem(initializeResult.AsT1);
+     return Problem(initializeResult.AsT1);
  }

268-268: Consider simplifying the idempotency wrapper

While the change correctly passes the user context, the lambda wrapper makes the code slightly harder to read. Consider extracting the Process call to a separate method for better readability.

+ private async Task<OneOf<Task, Error>> ProcessConfirmDownload(ConfirmDownloadRequest request, ClaimsPrincipal user, CancellationToken cancellationToken)
+ {
+     return await handler.Process(request, user, cancellationToken);
+ }

  // In ConfirmDownload method:
- var proccessingFunction = new Func<Task<OneOf<Task, Error>>>(() => handler.Process(requestData, HttpContext.User, cancellationToken));
+ var proccessingFunction = new Func<Task<OneOf<Task, Error>>>(() => ProcessConfirmDownload(requestData, HttpContext.User, cancellationToken));

Line range hint 1-277: Well-structured authorization pattern implementation

The changes successfully implement a consistent pattern of passing user context to handlers, which:

  1. Improves testability by making the authorization flow explicit
  2. Maintains security through proper authorization policies
  3. Keeps the responsibility of authorization checks in the handlers
  4. Makes the code more maintainable by following a consistent pattern

Consider documenting this pattern in the project's architectural guidelines to ensure consistency across other controllers.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 23f259c and 08848fc.

📒 Files selected for processing (19)
  • src/Altinn.Broker.API/Controllers/FileTransferController.cs (9 hunks)
  • src/Altinn.Broker.API/Controllers/LegacyFileController.cs (6 hunks)
  • src/Altinn.Broker.API/Controllers/MalwareScanResultsController.cs (1 hunks)
  • src/Altinn.Broker.API/Controllers/ResourceController.cs (1 hunks)
  • src/Altinn.Broker.Application/ConfigureResource/ConfigureResourceHandler.cs (2 hunks)
  • src/Altinn.Broker.Application/ConfirmDownload/ConfirmDownloadHandler.cs (4 hunks)
  • src/Altinn.Broker.Application/DownloadFile/DownloadFileHandler.cs (3 hunks)
  • src/Altinn.Broker.Application/ExpireFileTransfer/ExpireFileTransferHandler.cs (2 hunks)
  • src/Altinn.Broker.Application/GetFileTransferDetails/GetFileTransferDetailsHandler.cs (3 hunks)
  • src/Altinn.Broker.Application/GetFileTransferOverview/GetFileTransferOverviewHandler.cs (3 hunks)
  • src/Altinn.Broker.Application/GetFileTransfers/GetFileTransfersHandler.cs (2 hunks)
  • src/Altinn.Broker.Application/GetFileTransfers/LegacyGetFilesHandler.cs (2 hunks)
  • src/Altinn.Broker.Application/IHandler.cs (1 hunks)
  • src/Altinn.Broker.Application/InitializeFileTransfer/InitializeFileTransferHandler.cs (3 hunks)
  • src/Altinn.Broker.Application/MalwareScanResults/MalwareScanResultHandler.cs (3 hunks)
  • src/Altinn.Broker.Application/UploadFile/UploadFileHandler.cs (2 hunks)
  • src/Altinn.Broker.Core/Repositories/IAuthorizationService.cs (1 hunks)
  • src/Altinn.Broker.Integrations/Altinn/Authorization/AltinnAuthorizationService.cs (1 hunks)
  • tests/Altinn.Broker.Tests/Helpers/CustomWebApplicationFactory.cs (2 hunks)
🔇 Additional comments (33)
src/Altinn.Broker.Application/IHandler.cs (1)

1-2: LGTM! Clean import addition

The ClaimsPrincipal import is properly placed and necessary for the interface changes.

src/Altinn.Broker.Core/Repositories/IAuthorizationService.cs (1)

1-3: LGTM! Clean import organization.

The addition of System.Security.Claims import is necessary and well-organized.

src/Altinn.Broker.Application/GetFileTransferOverview/GetFileTransferOverviewHandler.cs (2)

1-1: LGTM: Required import for ClaimsPrincipal

The addition of the System.Security.Claims import is appropriate for the new ClaimsPrincipal parameter.


Line range hint 16-37: Verify controller updates for the new parameter

The handler's signature change requires updates in all controllers that use this handler. Let's verify that all callers have been properly updated to pass the user context.

✅ Verification successful

Let's try a broader search to find the controller and usage patterns. The previous search might have been too specific. We'll look for files containing the handler name first, and then search for Process method calls to understand the usage pattern.


All controllers have been properly updated with the user context parameter

Based on the search results, I can verify that all controllers using the GetFileTransferOverviewHandler are passing the HttpContext.User parameter correctly:

  • In LegacyFileController.cs:
await handler.Process(new GetFileTransferOverviewRequest() {
    // ... request properties ...
}, HttpContext.User, cancellationToken);
  • In FileTransferController.cs:
await handler.Process(new GetFileTransferOverviewRequest() {
    // ... request properties ...
}, HttpContext.User, cancellationToken);

The implementation is consistent across both controllers that use this handler, and they properly pass the user context parameter.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usages of GetFileTransferOverviewHandler to verify controller updates
ast-grep --pattern 'class $_ {
  $$$
  GetFileTransferOverviewHandler $_
  $$$
}'

# Search for Process method calls to verify the new parameter is passed
rg -A 5 "GetFileTransferOverviewHandler.*Process\("

Length of output: 137


Script:

#!/bin/bash
# Search for files containing GetFileTransferOverviewHandler
rg -l "GetFileTransferOverviewHandler"

# Search for Process method invocations with context
rg -B 2 -A 5 "\.Process\(" 

Length of output: 20330

src/Altinn.Broker.API/Controllers/ResourceController.cs (2)

35-35: LGTM! The change aligns with the PR objective.

The addition of HttpContext.User to the handler.Process call improves testability by making the user context explicit rather than relying on HttpContextAccessor. This change makes it easier to unit test the handler by allowing direct injection of test claims.


Line range hint 26-34: Verify validation of resource configuration parameters.

The handler is processing several configuration parameters that could impact system behavior and security.

✅ Verification successful

Let me generate additional scripts to check for validation logic in the UpdateFileTransferTimeToLive method and any validation attributes on the request model.


Let me check the actual implementation of the validation logic in the ConfigureResourceHandler.


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

Resource configuration parameters are properly validated

The codebase shows comprehensive validation for both MaxFileTransferSize and FileTransferTimeToLive:

  • MaxFileTransferSize validation:

    • Checks for negative values
    • Prevents zero values
    • Enforces virus scan size limits in production
    • Enforces global maximum upload size limit
  • FileTransferTimeToLive validation:

    • Validates format using XmlConvert.ToTimeSpan
    • Enforces maximum limit of 365 days
    • Provides default of 30 days if not specified

The validation is implemented in ConfigureResourceHandler with appropriate error handling and clear error messages.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for validation logic in the handler implementation
# Expected: Find validation checks for MaxFileTransferSize and TimeToLive

# Search for validation logic in the handler
ast-grep --pattern 'class ConfigureResourceHandler {
  $$$
  Process($_, $_, $_) {
    $$$
    if ($$$) {
      $$$
    }
    $$$
  }
}'

# Search for any existing validation attributes
rg -A 2 "MaxFileTransferSize|FileTransferTimeToLive" 

Length of output: 11580


Script:

#!/bin/bash
# Check validation in UpdateFileTransferTimeToLive method
ast-grep --pattern 'UpdateFileTransferTimeToLive($_, $_, $_) {
  $$$
  if ($$$) {
    $$$
  }
  $$$
}'

# Check for validation attributes on request model
rg -A 5 "class ConfigureResourceRequest" 

# Check for any validation constants or rules
rg "MaxFileTransferSize|FileTransferTimeToLive" --type cs -C 3 "Constants|Validation"

Length of output: 1006


Script:

#!/bin/bash
# Get the full implementation of ConfigureResourceHandler
rg -A 20 "UpdateFileTransferTimeToLive.*CancellationToken" --type cs

# Check for any validation errors or constants
rg -A 3 "Errors\." --type cs

# Check for any TimeSpan parsing and validation
rg -A 5 "TimeSpan\.Parse|TimeSpan\.TryParse" --type cs

Length of output: 29121

src/Altinn.Broker.Application/GetFileTransferDetails/GetFileTransferDetailsHandler.cs (1)

1-2: LGTM: Clean import addition

The System.Security.Claims import is appropriately added to support the new ClaimsPrincipal parameter.

src/Altinn.Broker.Application/GetFileTransfers/GetFileTransfersHandler.cs (3)

1-2: LGTM: Required import added for ClaimsPrincipal

The addition of the System.Security.Claims import is necessary for the ClaimsPrincipal parameter.


17-17: LGTM: Method signature updated to support explicit user context

The Process method signature has been updated to accept ClaimsPrincipal as a parameter, which aligns with the PR objective of improving testability by making the authorization context explicit.


20-20: Verify error handling for null user parameter

While the change to pass the user directly to CheckUserAccess is correct, we should verify how null users are handled since the parameter is nullable (ClaimsPrincipal?).

✅ Verification successful

Null user parameter is properly handled with clear error message

The implementation in AltinnAuthorizationService.CheckUserAccess explicitly checks for null users and throws an InvalidOperationException with a clear error message: "This operation cannot be called outside an authenticated HttpContext". This is an appropriate handling of the null case.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for null handling patterns in CheckUserAccess implementation
ast-grep --pattern 'CheckUserAccess(ClaimsPrincipal? $_, $$$)'

# Look for related test cases
rg -l "CheckUserAccess.*null" --type cs

Length of output: 106


Script:

#!/bin/bash
# Let's first find the implementation of CheckUserAccess
rg -A 5 "CheckUserAccess.*ClaimsPrincipal" --type cs

# Also search for any test files related to this method
fd ".*Tests?.cs" --exec rg -l "CheckUserAccess" {}

# Look for the interface definition as well
rg "interface.*ResourceRightsRepository" -A 10 --type cs

Length of output: 2475

src/Altinn.Broker.Application/GetFileTransfers/LegacyGetFilesHandler.cs (1)

1-2: LGTM! Import added correctly

The System.Security.Claims import is appropriately added and necessary for the ClaimsPrincipal parameter.

src/Altinn.Broker.Application/DownloadFile/DownloadFileHandler.cs (2)

1-1: LGTM: Required import for ClaimsPrincipal

The addition of the System.Security.Claims import is necessary and correctly placed.


15-15: LGTM: Signature change improves testability

The addition of ClaimsPrincipal? user parameter aligns with the PR objective and makes the authorization more testable. The nullable parameter allows for flexible testing scenarios.

Let's verify that all callers of this method have been updated:

✅ Verification successful

Breaking change has been properly handled

Based on the search results, I can confirm that all callers of the DownloadFileHandler.Process method have been updated to include the HttpContext.User parameter. The method is called in:

  • LegacyFileController.cs: await handler.Process(new DownloadFileRequest() {...}, HttpContext.User, cancellationToken)
  • FileTransferController.cs: await handler.Process(new DownloadFileRequest() {...}, HttpContext.User, cancellationToken)

All instances properly pass the user context from the HTTP context, maintaining the security context throughout the request pipeline.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any calls to Process method of DownloadFileHandler
ast-grep --pattern 'downloadFileHandler.Process($$$)'

Length of output: 55


Script:

#!/bin/bash
# Let's try a more comprehensive search for Process method calls
# First, search for any reference to DownloadFileHandler
rg -l "DownloadFileHandler" 

# Then search for Process method calls with context
rg "\.Process\(" -A 2 -B 2

Length of output: 13717

src/Altinn.Broker.Application/MalwareScanResults/MalwareScanResultHandler.cs (2)

2-2: LGTM!

The System.Security.Claims import is correctly added to support the new ClaimsPrincipal parameter.


27-27: Verify consistent parameter usage across handlers.

Let's verify that other handlers in the codebase follow the same pattern of accepting ClaimsPrincipal.

✅ Verification successful

Parameter usage is consistent across all handlers

All handlers in the application consistently follow the same pattern, accepting three parameters:

  • A request/data parameter of their specific type
  • A nullable ClaimsPrincipal? user parameter
  • A CancellationToken cancellationToken parameter

The MalwareScanResultHandler implementation aligns perfectly with this pattern, using ScanResultData data as its specific request type along with the common user and cancellationToken parameters.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other handler implementations to verify consistent parameter usage
ast-grep --pattern 'class $_ : IHandler<$_, $_>
{
  $$$
  Process($$$)
  {
    $$$
  }
}'

Length of output: 91


Script:

#!/bin/bash
# Let's try a different approach to find handler implementations
# First, let's find all files that might contain handlers
fd "Handler.cs$"

# Then let's use ripgrep to find Process method signatures
rg "public.*Task.*Process.*\(" --type cs -A 1

Length of output: 4995

src/Altinn.Broker.Integrations/Altinn/Authorization/AltinnAuthorizationService.cs (2)

25-32: LGTM: Constructor changes align with PR objectives

The removal of IHttpContextAccessor dependency makes the service more testable by eliminating the HTTP context dependency. All remaining dependencies are properly initialized.


34-34: Verify updates to all service consumers

The signature change from using IHttpContextAccessor to accepting ClaimsPrincipal directly requires updates to all calling code.

Let's verify all callers have been updated:

✅ Verification successful

Based on the search results, I can generate the final response as I have enough information to verify the changes. The results show all usages of both the concrete AltinnAuthorizationService and the IAuthorizationService interface across the codebase.

All service consumers properly updated to use the new signature

The verification shows that all consumers have been correctly updated to work with the new signature that accepts ClaimsPrincipal directly:

  • All handlers (InitializeFileTransfer, UploadFile, GetFileTransfers, etc.) are injecting IAuthorizationService and passing the user context explicitly
  • The test mock in CustomWebApplicationFactory.cs correctly sets up the new signature
  • No instances found of direct HttpContextAccessor usage with this service
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for direct usage of AltinnAuthorizationService
rg -l "AltinnAuthorizationService" | while read -r file; do
  echo "=== $file ==="
  # Show context of service usage
  rg -B 2 -A 2 "AltinnAuthorizationService" "$file"
done

# Search for interface usage
rg -l "IAuthorizationService" | while read -r file; do
  echo "=== $file ==="
  # Show context of service usage
  rg -B 2 -A 2 "IAuthorizationService" "$file"
done

Length of output: 9998

src/Altinn.Broker.Application/InitializeFileTransfer/InitializeFileTransferHandler.cs (4)

1-2: LGTM!

The addition of the ClaimsPrincipal import is necessary for the new user context parameter.


Line range hint 36-40: LGTM! Authorization check properly uses the passed user context.

The authorization check correctly utilizes the explicit user parameter while maintaining the appropriate access level verification and error handling.


33-33: LGTM! Verify interface implementation across the codebase.

The nullable ClaimsPrincipal parameter aligns with the PR objective of improving testability. This change allows for explicit user context passing while maintaining backward compatibility.

#!/bin/bash
# Verify that all implementations of IHandler have been updated with the new signature
ast-grep --pattern 'class $_ : IHandler<$_, $_>
{
  $$$
  Process($_, ClaimsPrincipal? user, $_)
  {
    $$$
  }
}'

79-79: Verify the design decision for expiration job authorization.

The expiration job is scheduled with a null user context. While this is typically acceptable for system operations, please verify that:

  1. The expiration process is designed to run with system privileges
  2. No user-specific authorization is required during expiration
✅ Verification successful

Passing null user context for expiration job is correct by design

The ExpireFileTransferHandler implementation shows that while it accepts a ClaimsPrincipal parameter, it doesn't perform any authorization checks. This aligns with the design where file expiration is a system-level operation that runs independently of user context. Other handlers like InitializeFileTransferHandler and ConfirmDownloadHandler do perform explicit user access checks, but expiration intentionally does not.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if ExpireFileTransferHandler requires user context in its authorization checks
ast-grep --pattern 'class ExpireFileTransferHandler
{
  $$$
  Process($_, ClaimsPrincipal? user, $_)
  {
    $$$
    CheckUserAccess($$$)
    $$$
  }
}'

Length of output: 280


Script:

#!/bin/bash
# Search for ExpireFileTransferHandler implementation
rg -A 10 "class ExpireFileTransferHandler" 

# Search for any authorization checks in files containing ExpireFileTransfer
rg -l "ExpireFileTransfer" | xargs rg "CheckUserAccess|Authorize|ClaimsPrincipal"

Length of output: 3479

src/Altinn.Broker.Application/ExpireFileTransfer/ExpireFileTransferHandler.cs (2)

1-1: LGTM: Appropriate namespace addition

The addition of System.Security.Claims aligns with the PR objective of making the service more testable by passing ClaimsPrincipal as an argument.


25-25: Verify authorization requirements for file expiration

The ClaimsPrincipal? user parameter has been added but isn't utilized within the method. Consider whether authorization checks should be implemented to ensure only authorized users can expire file transfers.

Let's check if other handlers implement authorization checks:

tests/Altinn.Broker.Tests/Helpers/CustomWebApplicationFactory.cs (2)

3-3: LGTM: Required import for ClaimsPrincipal

The addition of the System.Security.Claims import is necessary to support the updated IAuthorizationService interface.


103-104: LGTM: Mock setup correctly handles the new ClaimsPrincipal parameter

The mock setup has been properly updated to accommodate the new ClaimsPrincipal parameter while maintaining existing test behavior. Consider adding specific test cases that verify authorization with different types of claims.

Let's verify if there are test cases that exercise different claim scenarios:

src/Altinn.Broker.Application/ConfigureResource/ConfigureResourceHandler.cs (2)

1-1: LGTM: Required import for ClaimsPrincipal

The addition of System.Security.Claims import is necessary and correctly placed.


Line range hint 23-27: Consider enhancing authorization with claims-based checks

The current authorization check only verifies resource.ServiceOwnerId against request.Token.Consumer. Since we now have access to user claims, consider enhancing this with additional claims-based authorization checks.

Consider adding claims validation:

 if (resource.ServiceOwnerId != request.Token.Consumer)
 {
     return Errors.NoAccessToResource;
 };
+if (user?.HasClaim(c => c.Type == "resource-access" && 
+    c.Value == resource.ServiceOwnerId) != true)
+{
+    return Errors.InsufficientPermissions;
+}

Let's check if similar patterns exist in other handlers:

#!/bin/bash
# Search for existing claims-based authorization patterns
rg -A 5 "HasClaim|GetClaim" 
src/Altinn.Broker.API/Controllers/LegacyFileController.cs (1)

48-48: Verify the relationship between CallerIdentity and ClaimsPrincipal

The method now passes both legacyToken and HttpContext.User to the handler. While this aligns with making the authorization service more testable, we should verify that these two authentication contexts are properly coordinated.

✅ Verification successful

Based on the search results, I can now provide a final response as the relationship between CallerIdentity and ClaimsPrincipal is clear:

Passing both CallerIdentity and ClaimsPrincipal is intentional and correct

The code shows a clear separation of concerns where:

  • CallerIdentity is used for legacy token-based authentication, created by MaskinportenModelBinder from bearer tokens
  • ClaimsPrincipal is passed to handlers which use IAuthorizationService to perform resource-based authorization checks
  • The LegacyFileController creates a new legacyToken from the original token while preserving the authorization context through HttpContext.User

This pattern enables:

  1. Backward compatibility through the legacy token system
  2. Modern authorization checks via the IAuthorizationService
  3. Proper testability of the authorization service as intended by the PR
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any validation or mapping between CallerIdentity and ClaimsPrincipal
rg -g "!*.{json,md,csproj}" -B 3 -A 3 "CallerIdentity.*ClaimsPrincipal|ClaimsPrincipal.*CallerIdentity"

# Search for handler implementations to understand how both contexts are used
ast-grep --pattern 'class $_ : $handler {
  $$$
  Process($_, ClaimsPrincipal $_, $_) {
    $$$
  }
}'

Length of output: 210


Script:

#!/bin/bash
# Let's try a different approach to understand the authorization flow

# First, search for CallerIdentity usage
rg -g "!*.{json,md,csproj}" -B 3 -A 3 "CallerIdentity"

# Look for Process method implementations in handlers
rg -g "!*.{cs}" -B 5 -A 5 "public.*async.*Process.*ClaimsPrincipal"

# Search for any authorization-related services or utilities
rg -g "!*.{json,md,csproj}" -B 3 -A 3 "IAuthorizationService|AuthorizationService"

Length of output: 40314

src/Altinn.Broker.API/Controllers/FileTransferController.cs (3)

86-86: LGTM! Consistent with authorization pattern

The change maintains the security checks while improving testability through explicit user context passing.


155-155: LGTM! Consistent authorization pattern across query operations

The changes consistently apply the pattern of passing user context to handlers across all query operations, improving testability while maintaining proper authorization checks.

Also applies to: 181-181, 215-215, 241-241


48-48: LGTM! Verify handler's user parameter usage

The change improves testability by explicitly passing HttpContext.User to the handler. This makes the authorization flow more transparent and easier to test.

✅ Verification successful

Verified: User parameter is properly utilized for authorization

Looking at the InitializeFileTransferHandler.Process implementation, the ClaimsPrincipal user parameter is correctly used for authorization through the resourceRightsRepository.CheckUserAccess method. The handler validates user access rights before proceeding with the file transfer initialization, which aligns with security best practices.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify that the InitializeFileTransferHandler properly uses the user parameter
ast-grep --pattern 'class InitializeFileTransferHandler {
  $$$
  Process($_, ClaimsPrincipal $_, $_) {
    $$$
  }
  $$$
}'

Length of output: 126


Script:

#!/bin/bash
# Let's try a different approach to find the handler implementation
rg -l "InitializeFileTransferHandler" --type cs

# Then search for Process method implementation
rg "Process.*ClaimsPrincipal.*CancellationToken" --type cs -A 5

Length of output: 10627

src/Altinn.Broker.Application/ConfirmDownload/ConfirmDownloadHandler.cs (1)

92-95: Handle user parameter consistently in scheduled jobs

In the scheduled job, user is passed as null:

backgroundJobClient.Schedule<ExpireFileTransferHandler>((expireFileTransferHandler) => expireFileTransferHandler.Process(new ExpireFileTransferRequest
{
    FileTransferId = request.FileTransferId,
    Force = true
}, null, cancellationToken), DateTime.UtcNow.Add(gracePeriod));

This inconsistency with the previous Enqueue call could lead to confusion or errors if ExpireFileTransferHandler.Process expects a non-null user.

Ensure that ExpireFileTransferHandler.Process properly handles a null user, and consider standardizing how user is passed to background jobs.

If user is not necessary for the ExpireFileTransferHandler, you might refactor the method signature to omit user.

src/Altinn.Broker.Application/UploadFile/UploadFileHandler.cs (1)

1-2: Approved: Added necessary using directive

The addition of using System.Security.Claims; is appropriate for utilizing ClaimsPrincipal in the code.

@Ceredron Ceredron merged commit cefcec0 into main Nov 19, 2024
6 checks passed
@Ceredron Ceredron deleted the chore/pass-user-as-argument branch November 19, 2024 10:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/chore Routine task or minor maintenance work that doesn't introduce new features or functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants