feat: add permission checking and task assignment handling in ProjectBoardHub
This commit is contained in:
@@ -1,19 +1,70 @@
|
||||
using _0_Framework.Application;
|
||||
using GozareshgirProgramManager.Application._Common.Constants;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using GozareshgirProgramManager.Domain.ProjectAgg.Repositories;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
|
||||
namespace ServiceHost.Hubs.ProgramManager;
|
||||
|
||||
public class ProjectBoardHub:Hub
|
||||
public class ProjectBoardHub : Hub
|
||||
{
|
||||
private readonly IAuthHelper _authHelper;
|
||||
private readonly ITaskSectionRepository _taskSectionRepository;
|
||||
|
||||
public ProjectBoardHub(IAuthHelper authHelper, ITaskSectionRepository taskSectionRepository)
|
||||
{
|
||||
_authHelper = authHelper;
|
||||
_taskSectionRepository = taskSectionRepository;
|
||||
}
|
||||
|
||||
public override async Task OnConnectedAsync()
|
||||
{
|
||||
var user = Context.User?.FindFirst("pm.userId")?.Value;
|
||||
|
||||
if (user != null && user !="0")
|
||||
// Rule 4: Determine all group memberships server-side.
|
||||
if (!_authHelper.IsAuthenticated())
|
||||
{
|
||||
await Groups.AddToGroupAsync(
|
||||
Context.ConnectionId,
|
||||
$"pm.user-{user}"
|
||||
);
|
||||
await base.OnConnectedAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
var connectionId = Context.ConnectionId;
|
||||
|
||||
// Rule 2: Add to all permission-based groups based on user's claims.
|
||||
var permissionGroups = _authHelper.GetPermissions() ?? new List<int>();
|
||||
|
||||
// Rule 3: Add to task-specific groups for all tasks assigned to the user (by accountId claim).
|
||||
var userId =Convert.ToInt32(Context.User?.FindFirst("pm.userId")?.Value);
|
||||
|
||||
var taskGroups = new List<string>();
|
||||
if (userId > 0)
|
||||
{
|
||||
var assignedTasks = await _taskSectionRepository.GetAssignedToUserAsync(userId);
|
||||
if (assignedTasks is { Count: > 0 })
|
||||
{
|
||||
taskGroups = assignedTasks
|
||||
.Select(t => $"pm.task:{t.Id}")
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
// Build the full, de-duplicated set of groups to join.
|
||||
var groupsToJoin = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
// Permission-based groups
|
||||
foreach (var perm in permissionGroups)
|
||||
groupsToJoin.Add($"pm.perm:{perm}");
|
||||
|
||||
// Task-based groups
|
||||
foreach (var tg in taskGroups)
|
||||
groupsToJoin.Add(tg);
|
||||
|
||||
// Rule 5: Avoid duplicate joins; join all needed groups concurrently.
|
||||
if (groupsToJoin.Count > 0)
|
||||
{
|
||||
var joinTasks = groupsToJoin
|
||||
.Select(group => Groups.AddToGroupAsync(connectionId, group));
|
||||
await Task.WhenAll(joinTasks);
|
||||
}
|
||||
|
||||
await base.OnConnectedAsync();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using GozareshgirProgramManager.Application._Common.Constants;
|
||||
using GozareshgirProgramManager.Application.Interfaces;
|
||||
using GozareshgirProgramManager.Domain.ProjectAgg.Enums;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
@@ -19,12 +20,20 @@ public class SignalRBoardNotificationPublisher:IBoardNotificationPublisher
|
||||
{
|
||||
var payload = new
|
||||
{
|
||||
UserId = userId,
|
||||
UserId= userId,
|
||||
OldStatus = oldStatus,
|
||||
NewStatus = newStatus,
|
||||
SectionId = sectionId
|
||||
};
|
||||
_hubContext.Clients.Group($"pm.user-{userId}").SendAsync("ReceiveProjectStatusChanged",payload);
|
||||
return Task.CompletedTask;
|
||||
|
||||
// گروه task-specific (برای همه assigneeهای واقعی)
|
||||
var taskGroup = $"pm.task:{sectionId}";
|
||||
|
||||
// گروه permission-based (مثلاً برای Admin ها)
|
||||
var permissionGroup = $"pm.perm:{ProgramManagerPermissionCode.Board.All.ViewAll}";
|
||||
|
||||
// ارسال به هر دو گروه؛ SignalR خودش duplicate connection رو هندل میکنه
|
||||
return _hubContext.Clients.Groups(taskGroup, permissionGroup)
|
||||
.SendAsync("ReceiveProjectStatusChanged", payload);
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
"sqlDebugging": true,
|
||||
"dotnetRunMessages": "true",
|
||||
"nativeDebugging": true,
|
||||
"applicationUrl": "https://localhost:5004;http://localhost:5003",
|
||||
"applicationUrl": "https://localhost:5004;http://localhost:5003;https://192.168.0.117:5006",
|
||||
"jsWebView2Debugging": false,
|
||||
"hotReloadEnabled": true
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user