Skip to content

Conversation

@ysmoradi
Copy link
Member

@ysmoradi ysmoradi commented Jun 7, 2025

closes #10933

Summary by CodeRabbit

  • New Features

    • Added a button in user session details to directly read logs for a specific user session (when available).
  • Bug Fixes

    • Improved performance and reliability of user claims retrieval, reducing redundant database queries.
  • Refactor

    • Streamlined log retrieval to operate on specific user sessions instead of multiple identifiers.
    • Removed previously available option to read logs for arbitrary users from the diagnostics modal.

@ysmoradi ysmoradi requested review from Copilot and msynk June 7, 2025 09:08
@coderabbitai
Copy link

coderabbitai bot commented Jun 7, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The changes overhaul the user claims retrieval process in the boilerplate project template for improved performance. They introduce a single-query, cached approach to fetching user claims, update the claims principal factory to use this method, and refactor related SignalR diagnostic log retrieval to use user session IDs instead of flexible queries.

Changes

Files/Groups Change Summary
.../Components/Layout/AppDiagnosticModal.razor, AppDiagnosticModal.razor.Utils.cs Removed UI and logic for reading another user's logs via SignalR from the diagnostics modal.
.../Components/Pages/Authorized/Management/UsersPage.razor, UsersPage.razor.cs Added button to read user session logs; implemented SignalR-based method to fetch logs by session ID (with conditional compilation).
.../Services/Identity/AppUserClaimsPrincipalFactory.cs Refactored to use a new, efficient claims retrieval method; constructor and claims generation logic updated.
.../Services/Identity/UserClaimsService.cs Added per-instance caching and a new method to retrieve all user claims in a single query.
.../SignalR/AppHub.cs Changed diagnostic log retrieval method to accept a user session ID and simplified logic to operate on a single session.

Sequence Diagram(s)

sequenceDiagram
    participant UsersPage
    participant AppHub (Server)
    participant SignalR Client
    participant DiagnosticModal

    UsersPage->>AppHub (Server): GetUserSessionLogs(userSessionId)
    AppHub (Server)->>DB: Query SignalRConnectionId for userSessionId
    AppHub (Server)->>SignalR Client: UPLOAD_DIAGNOSTIC_LOGGER_STORE (via SignalR)
    SignalR Client-->>AppHub (Server): DiagnosticLogDto[]
    AppHub (Server)-->>UsersPage: DiagnosticLogDto[]
    UsersPage->>DiagnosticModal: Show logs
Loading
sequenceDiagram
    participant AppUserClaimsPrincipalFactory
    participant UserClaimsService
    participant DB

    AppUserClaimsPrincipalFactory->>UserClaimsService: GetAllUserClaims(userId)
    UserClaimsService->>DB: Query user claims, role claims, role names (single query)
    DB-->>UserClaimsService: Claims[]
    UserClaimsService-->>AppUserClaimsPrincipalFactory: Claims[]
    AppUserClaimsPrincipalFactory->>AppUserClaimsPrincipalFactory: Build ClaimsIdentity
Loading

Assessment against linked issues

Objective Addressed Explanation
Improve claim retrieval performance by reducing database queries and introducing single-query, cached logic (#10933)
Update AppUserClaimsPrincipalFactory to use the new claims retrieval approach (#10933)
Ensure claims are correctly added to ClaimsIdentity and avoid duplicates (#10933)

Poem

In the warren where claims once would roam,
Now a single swift query brings them home.
Caches are nibbled, performance is bright,
SignalR logs fetched in the blink of a byte.
With every hop, this code runs fast—
A rabbit’s delight: improvements that last!
🐇✨


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this 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

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR improves the boilerplate claim retrieval by refactoring SignalR log retrieval methods and consolidating user claim queries. The key changes include:

  • Replacing the GetUserDiagnosticLogs method with a streamlined GetUserSessionLogs that uses a session identifier.
  • Refactoring the user claims retrieval by introducing an in-memory cache and using a consolidated query in UserClaimsService.
  • Adjusting SignalR functionality on the client side to match the updated API for log retrieval.

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
AppHub.cs Updated to fetch logs by user session identifier and simplified connection handling.
UserClaimsService.cs Added an in-memory cache for claims and replaced inline queries with a consolidated async query.
AppUserClaimsPrincipalFactory.cs Modified constructor dependency and refactored claims generation to use the new UserClaimsService method.
UsersPage.razor.cs / UsersPage.razor Integrated conditional SignalR-based log fetching on the client.
AppDiagnosticModal.razor.Utils.cs / AppDiagnosticModal.razor Removed legacy SignalR log reading code for diagnostic modal display.

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

🧹 Nitpick comments (3)
src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Authorized/Management/UsersPage.razor (1)

178-182: Consider adding accessibility attributes for better UX.

The new diagnostic logs button is well-positioned and uses consistent error handling. However, consider improving accessibility for screen readers.

 <BitButton IconOnly AutoLoading
            OnClick="WrapHandled(() => ReadUserSessionLogs(session.Id))"
            Title="Read user session logs"
+           AriaLabel="Read user session logs"
            Color="BitColor.SecondaryBackground"
            IconName="@BitIconName.Download" />
src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Authorized/Management/UsersPage.razor.cs (1)

192-203: Consider thread safety when clearing the diagnostic store.

The implementation correctly calls the updated SignalR method and displays the modal. However, clearing the entire DiagnosticLogger.Store before adding new logs could potentially interfere with concurrent diagnostic operations.

Consider a more targeted approach:

 private async Task ReadUserSessionLogs(Guid userSessionId)
 {
     var logs = await hubConnection.InvokeAsync<DiagnosticLogDto[]>("GetUserSessionLogs", userSessionId, CurrentCancellationToken);

-    DiagnosticLogger.Store.Clear();
-    foreach (var log in logs)
-    {
-        DiagnosticLogger.Store.Enqueue(log);
-    }
+    // Clear only if we have new logs to avoid clearing other concurrent operations
+    if (logs.Length > 0)
+    {
+        DiagnosticLogger.Store.Clear();
+        foreach (var log in logs)
+        {
+            DiagnosticLogger.Store.Enqueue(log);
+        }
+    }

     PubSubService.Publish(ClientPubSubMessages.SHOW_DIAGNOSTIC_MODAL);
 }
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Services/Identity/AppUserClaimsPrincipalFactory.cs (1)

32-46: Add null checks for user properties to prevent potential NullReferenceException.

The null-forgiving operators on userName and SecurityStamp could cause runtime exceptions if these values are unexpectedly null.

Consider adding null checks:

         id.AddClaim(new Claim(Options.ClaimsIdentity.UserIdClaimType, userId));
-        id.AddClaim(new Claim(Options.ClaimsIdentity.UserNameClaimType, userName!));
+        if (!string.IsNullOrEmpty(userName))
+            id.AddClaim(new Claim(Options.ClaimsIdentity.UserNameClaimType, userName));
         var email = user.Email;
         if (string.IsNullOrEmpty(email) is false)
         {
             id.AddClaim(new Claim(Options.ClaimsIdentity.EmailClaimType, email));
         }
-        id.AddClaim(new Claim(Options.ClaimsIdentity.SecurityStampClaimType, user.SecurityStamp!));
+        if (!string.IsNullOrEmpty(user.SecurityStamp))
+            id.AddClaim(new Claim(Options.ClaimsIdentity.SecurityStampClaimType, user.SecurityStamp));
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between c2dc189 and aa23e4d.

📒 Files selected for processing (7)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/AppDiagnosticModal.razor (0 hunks)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/AppDiagnosticModal.razor.Utils.cs (0 hunks)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Authorized/Management/UsersPage.razor (1 hunks)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Authorized/Management/UsersPage.razor.cs (3 hunks)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Services/Identity/AppUserClaimsPrincipalFactory.cs (3 hunks)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Services/Identity/UserClaimsService.cs (3 hunks)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/SignalR/AppHub.cs (1 hunks)
💤 Files with no reviewable changes (2)
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/AppDiagnosticModal.razor
  • src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Layout/AppDiagnosticModal.razor.Utils.cs
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build and test
🔇 Additional comments (4)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/SignalR/AppHub.cs (2)

80-88: Implementation is cleaner and more focused.

The simplified query logic that directly looks up a single user session and its SignalR connection is much cleaner than the previous flexible query approach. The early return for empty connection IDs is appropriate.


75-75:

✅ Verification successful

Verify all callers have been updated for the breaking change.

The method signature change from GetUserDiagnosticLogs(string? userQuery) to GetUserSessionLogs(Guid userSessionId) is a breaking change that improves type safety and clarity.


🏁 Script executed:

#!/bin/bash
# Description: Verify no remaining references to the old method name exist
# Expected: No references to GetUserDiagnosticLogs should be found

echo "Searching for references to old method name..."
rg "GetUserDiagnosticLogs" --type cs

echo "Searching for SignalR method invocations with old name..."
rg "GetUserDiagnosticLogs" --type js --type ts

Length of output: 311


No remaining references to GetUserDiagnosticLogs

Verification using rg "GetUserDiagnosticLogs" across C# and JS/TS files returned no matches, confirming that all callers have been updated for the signature change.

src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Components/Pages/Authorized/Management/UsersPage.razor.cs (2)

3-8: Conditional compilation is properly implemented.

The conditional compilation directives for SignalR-related imports are correctly implemented and maintain clean separation of concerns.


34-36: HubConnection injection follows consistent pattern.

The conditional injection of HubConnection is properly implemented and follows the same pattern as other dependencies.

ysmoradi added 3 commits June 7, 2025 11:26
Signed-off-by: Yaser Moradi <ysmoradi@outlook.com>
@ysmoradi ysmoradi merged commit 1987511 into bitfoundation:develop Jun 7, 2025
3 checks passed
@ysmoradi ysmoradi deleted the 10933 branch June 7, 2025 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Boilerplate project template claim retrieval needs improvements

2 participants