基于角色的权限控制
1、用户角色枚举、权限枚举、结果记录和密码存储模型 IPermissionService 接口及包含认证、权限检查、密码管理和登出功能的 PermissionService 单例 2、支持层级化角色-权限映射的权限矩阵(SuperAdmin ⊇ Admin ⊇ User) 密码持久化至 passwords.json 文件,并提供工厂默认值回退机制 3、UI 层 LoginDialog — 启动时弹出模态登录对话框,支持密码掩码输入、错误提示以及取消退出功能 RibbonStatusAreaView — 在Ribbon右侧区域始终显示角色标签和“切换用户”按钮 权限感知的CncEditorViewModel — 用户角色无法使用CNC编辑控件 权限感知的CncInspectionModulePipelineViewModel — 用户角色无法进行流程编辑 设置导航可见性 — Admin/User角色隐藏Factory_Settings,User角色隐藏Report_Settings PasswordManagementView — 仅SuperAdmin可访问的修改角色密码对话框 PermissionTooltipHelper — 附加属性,在禁用控件上显示“当前角色无权访问此功能”提示
This commit is contained in:
@@ -2,8 +2,10 @@ using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Moq;
|
||||
using XP.Common.Logging.Interfaces;
|
||||
using XplorePlane.Models;
|
||||
using XplorePlane.Services;
|
||||
using XplorePlane.Services.Permission;
|
||||
using XplorePlane.Services.Storage;
|
||||
using XplorePlane.Tests.Helpers;
|
||||
using Xunit;
|
||||
@@ -24,7 +26,11 @@ namespace XplorePlane.Tests.Pipeline
|
||||
Directory.CreateDirectory(_tempDir);
|
||||
|
||||
var mockImageSvc = TestHelpers.CreateMockImageService(new[] { "Blur", "Sharpen" });
|
||||
_svc = new PipelinePersistenceService(mockImageSvc.Object, _tempDir);
|
||||
var mockPermissionSvc = new Mock<IPermissionService>();
|
||||
mockPermissionSvc.Setup(p => p.HasPermission(It.IsAny<Permission>())).Returns(true);
|
||||
var mockLogger = new Mock<ILoggerService>();
|
||||
mockLogger.Setup(l => l.ForModule<PipelinePersistenceService>()).Returns(mockLogger.Object);
|
||||
_svc = new PipelinePersistenceService(mockImageSvc.Object, mockPermissionSvc.Object, mockLogger.Object, _tempDir);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
@@ -206,10 +212,14 @@ namespace XplorePlane.Tests.Pipeline
|
||||
public async Task LoadAllAsync_UsesToolsPath_WhenConstructedWithDataPathService()
|
||||
{
|
||||
var mockImageSvc = TestHelpers.CreateMockImageService(new[] { "Blur" });
|
||||
var mockPermissionSvc = new Mock<IPermissionService>();
|
||||
mockPermissionSvc.Setup(p => p.HasPermission(It.IsAny<Permission>())).Returns(true);
|
||||
var mockLogger = new Mock<ILoggerService>();
|
||||
mockLogger.Setup(l => l.ForModule<PipelinePersistenceService>()).Returns(mockLogger.Object);
|
||||
var mockDataPathSvc = new Mock<IXpDataPathService>();
|
||||
mockDataPathSvc.SetupGet(s => s.ToolsPath).Returns(_tempDir);
|
||||
|
||||
var service = new PipelinePersistenceService(mockImageSvc.Object, mockDataPathSvc.Object);
|
||||
var service = new PipelinePersistenceService(mockImageSvc.Object, mockPermissionSvc.Object, mockLogger.Object, mockDataPathSvc.Object);
|
||||
await service.SaveAsync(BuildModel("P3", "Blur"), Path.Combine(_tempDir, "p3.xpm"));
|
||||
|
||||
var result = await service.LoadAllAsync(null);
|
||||
|
||||
@@ -12,6 +12,7 @@ using System.Threading.Tasks;
|
||||
using XP.Common.Logging.Interfaces;
|
||||
using XplorePlane.Models;
|
||||
using XplorePlane.Services;
|
||||
using XplorePlane.Services.Permission;
|
||||
using XplorePlane.Services.Storage;
|
||||
using XplorePlane.Tests.Helpers;
|
||||
using XplorePlane.ViewModels;
|
||||
@@ -181,7 +182,11 @@ namespace XplorePlane.Tests.Pipeline
|
||||
try
|
||||
{
|
||||
var mockImageSvc = TestHelpers.CreateMockImageService(new[] { "Blur", "Sharpen" });
|
||||
var svc = new PipelinePersistenceService(mockImageSvc.Object, tempDir);
|
||||
var mockPermissionSvc = new Mock<IPermissionService>();
|
||||
mockPermissionSvc.Setup(p => p.HasPermission(It.IsAny<Permission>())).Returns(true);
|
||||
var mockLogger = new Mock<ILoggerService>();
|
||||
mockLogger.Setup(l => l.ForModule<PipelinePersistenceService>()).Returns(mockLogger.Object);
|
||||
var svc = new PipelinePersistenceService(mockImageSvc.Object, mockPermissionSvc.Object, mockLogger.Object, tempDir);
|
||||
|
||||
var model = new PipelineModel { Name = $"Pipeline_{nodeCount}" };
|
||||
for (int i = 0; i < nodeCount; i++)
|
||||
|
||||
@@ -6,6 +6,7 @@ using XP.Hardware.RaySource.Services;
|
||||
using XplorePlane.Models;
|
||||
using XplorePlane.Services.AppState;
|
||||
using XplorePlane.Services.Cnc;
|
||||
using XplorePlane.Services.Permission;
|
||||
using Xunit;
|
||||
|
||||
namespace XplorePlane.Tests.Services
|
||||
@@ -24,7 +25,10 @@ namespace XplorePlane.Tests.Services
|
||||
var logger = new Mock<ILoggerService>();
|
||||
logger.Setup(l => l.ForModule<CncProgramService>()).Returns(logger.Object);
|
||||
|
||||
var service = new CncProgramService(appState.Object, raySource.Object, logger.Object);
|
||||
var permissionService = new Mock<IPermissionService>();
|
||||
permissionService.Setup(p => p.HasPermission(It.IsAny<Permission>())).Returns(true);
|
||||
|
||||
var service = new CncProgramService(appState.Object, raySource.Object, logger.Object, permissionService.Object);
|
||||
var program = new CncProgram(
|
||||
Guid.NewGuid(),
|
||||
"Program",
|
||||
|
||||
@@ -18,6 +18,7 @@ using XplorePlane.Services.AppState;
|
||||
using XplorePlane.Services.Cnc;
|
||||
using XplorePlane.Services.Storage;
|
||||
using XplorePlane.Services;
|
||||
using XplorePlane.Services.Permission;
|
||||
using XplorePlane.ViewModels.Cnc;
|
||||
using Xunit;
|
||||
|
||||
@@ -36,10 +37,14 @@ namespace XplorePlane.Tests.ViewModels
|
||||
var mockAppState = new Mock<IAppStateService>();
|
||||
var mockLogger = new Mock<ILoggerService>();
|
||||
var mockDataPathService = new Mock<IXpDataPathService>();
|
||||
var mockPermissionService = new Mock<IPermissionService>();
|
||||
mockPipelinePersistenceService ??= new Mock<IPipelinePersistenceService>();
|
||||
mockLogger.Setup(l => l.ForModule<CncEditorViewModel>()).Returns(mockLogger.Object);
|
||||
mockDataPathService.SetupGet(s => s.PlanPath).Returns(System.IO.Path.GetTempPath());
|
||||
|
||||
// Default: grant all permissions (Admin/SuperAdmin behavior)
|
||||
mockPermissionService.Setup(p => p.HasPermission(It.IsAny<XplorePlane.Models.Permission>())).Returns(true);
|
||||
|
||||
mockExecSvc ??= new Mock<ICncExecutionService>();
|
||||
|
||||
// Setup CreateProgram so ExecuteNewProgram works
|
||||
@@ -95,7 +100,8 @@ namespace XplorePlane.Tests.ViewModels
|
||||
mockLogger.Object,
|
||||
mockExecSvc.Object,
|
||||
mockDataPathService.Object,
|
||||
mockPipelinePersistenceService.Object);
|
||||
mockPipelinePersistenceService.Object,
|
||||
mockPermissionService.Object);
|
||||
|
||||
if (initialProgram != null)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user