多角色账号按 All > College > Class > Self 自动取最高权限。
学院管理员限制在所属学院。 辅导员通过稳定账号 ID 绑定行政班,避免重名串班。 教师只能访问本人档案、授课课程和所授课学生。 学生只能访问本人档案及所在班级课程。 教师/学生角色会自动校验并绑定工号或学号档案。 超级管理员可在用户页面调整角色、学院、工号/学号,并预览生效后的数据范围。
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
using System.Security.Claims;
|
||||
using Jiaowu.Api.Domain.Identity;
|
||||
using Jiaowu.Api.Infrastructure.Auth;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Jiaowu.Api.Tests;
|
||||
|
||||
public sealed class DataScopeTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(SystemRoles.Student, null, DataScope.Self)]
|
||||
[InlineData(SystemRoles.Counselor, SystemRoles.Teacher, DataScope.Class)]
|
||||
[InlineData(SystemRoles.CollegeAdmin, SystemRoles.Counselor, DataScope.College)]
|
||||
[InlineData(SystemRoles.SuperAdmin, SystemRoles.CollegeAdmin, DataScope.All)]
|
||||
[InlineData(SystemRoles.AcademicAdmin, SystemRoles.Student, DataScope.All)]
|
||||
public void Resolver_UsesHighestScope(
|
||||
string firstRole,
|
||||
string? secondRole,
|
||||
DataScope expected)
|
||||
{
|
||||
var roles = secondRole is null
|
||||
? [firstRole]
|
||||
: new[] { firstRole, secondRole };
|
||||
|
||||
Assert.Equal(expected, EffectiveDataScopeResolver.Resolve(roles));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CurrentScope_ReadsIdentityAndCollegeClaims()
|
||||
{
|
||||
var userId = Guid.NewGuid();
|
||||
var collegeId = Guid.NewGuid();
|
||||
var claims = new[]
|
||||
{
|
||||
new Claim(ClaimTypes.NameIdentifier, userId.ToString()),
|
||||
new Claim(ClaimTypes.Name, "院系管理员"),
|
||||
new Claim(ClaimTypes.Role, SystemRoles.CollegeAdmin),
|
||||
new Claim("college_id", collegeId.ToString())
|
||||
};
|
||||
var accessor = new HttpContextAccessor
|
||||
{
|
||||
HttpContext = new DefaultHttpContext
|
||||
{
|
||||
User = new ClaimsPrincipal(new ClaimsIdentity(claims, "test"))
|
||||
}
|
||||
};
|
||||
|
||||
var current = new CurrentUserDataScope(accessor).Current;
|
||||
|
||||
Assert.Equal(userId, current.UserId);
|
||||
Assert.Equal(collegeId, current.CollegeId);
|
||||
Assert.Equal(DataScope.College, current.Scope);
|
||||
Assert.True(current.CanAccessCollege(collegeId));
|
||||
Assert.False(current.CanAccessCollege(Guid.NewGuid()));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Jiaowu.Api.Domain.Academic;
|
||||
using Jiaowu.Api.Domain.Identity;
|
||||
using Jiaowu.Api.Infrastructure.Persistence;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@@ -82,12 +83,21 @@ public sealed class PersistenceTests : IAsyncLifetime
|
||||
CollegeId = college.Id,
|
||||
DegreeType = "工学学士"
|
||||
};
|
||||
var counselor = new ApplicationUser
|
||||
{
|
||||
UserName = "counselor",
|
||||
NormalizedUserName = "COUNSELOR",
|
||||
DisplayName = "陈老师"
|
||||
};
|
||||
var administrativeClass = new AdministrativeClass
|
||||
{
|
||||
Code = "CS2026-01",
|
||||
Name = "计科 2026-1 班",
|
||||
MajorId = major.Id,
|
||||
Grade = 2026
|
||||
Grade = 2026,
|
||||
CounselorName = counselor.DisplayName,
|
||||
CounselorUserId = counselor.Id,
|
||||
CounselorUser = counselor
|
||||
};
|
||||
var course = new Course
|
||||
{
|
||||
@@ -135,6 +145,7 @@ public sealed class PersistenceTests : IAsyncLifetime
|
||||
campus,
|
||||
college,
|
||||
major,
|
||||
counselor,
|
||||
administrativeClass,
|
||||
teacher,
|
||||
new Student
|
||||
@@ -223,6 +234,9 @@ public sealed class PersistenceTests : IAsyncLifetime
|
||||
.Include(x => x.AdministrativeClass)
|
||||
.ThenInclude(x => x!.Major)
|
||||
.SingleAsync();
|
||||
var savedClass = await _db.AdministrativeClasses
|
||||
.Include(x => x.CounselorUser)
|
||||
.SingleAsync();
|
||||
var savedCourse = await _db.Courses.Include(x => x.College).SingleAsync();
|
||||
var curriculumPlan = await _db.CurriculumPlans
|
||||
.Include(x => x.Modules)
|
||||
@@ -239,6 +253,7 @@ public sealed class PersistenceTests : IAsyncLifetime
|
||||
|
||||
Assert.Equal("计算机学院", savedTeacher.College!.Name);
|
||||
Assert.Equal("计算机科学与技术", student.AdministrativeClass!.Major!.Name);
|
||||
Assert.Equal("陈老师", savedClass.CounselorUser!.DisplayName);
|
||||
Assert.Equal(4m, savedCourse.Credits);
|
||||
Assert.Equal(savedCourse.TotalHours, savedCourse.LectureHours + savedCourse.PracticeHours);
|
||||
Assert.Single(curriculumPlan.Modules);
|
||||
|
||||
Reference in New Issue
Block a user