- all authorization rules (owner/creator, per-channel read/write grants, who may remove whom, delete rules, structure management) live in ChannelPolicy; a test fails if they are reimplemented elsewhere - ChannelInfo carries what the caller may do (can_*), member and invitation lists say who can be removed; clients display it and never derive it - the host no longer stores or calls the file service: it only signs short-lived tickets from space permissions (create/put/get/delete/domain), and keeps an opaque fileDomain reference on the channel - a whole file is registered in one request (last frame header + per-frame length and digest) instead of one request per 1 MiB frame; the signed manifest still has to match every digest - drop file quota/threshold, receipts, reconcile and delete-queue code from the host - contract generator emits constants for enums, error codes, token roles, permissions and share states
49 lines
2.5 KiB
C#
49 lines
2.5 KiB
C#
using System.Text.RegularExpressions;
|
|
|
|
namespace WebDrop.Core.Tests;
|
|
|
|
/// <summary>
|
|
/// 权限规则只写在 ChannelPolicy 一处:别的地方只许调用,不许再各写一遍。
|
|
/// 这个测试扫描源码,发现在 ChannelPolicy 之外重新判断角色、读写授权就失败,防止重复实现长回来。
|
|
/// </summary>
|
|
public sealed class PolicySingleSourceTests
|
|
{
|
|
private static string SourceRoot()
|
|
{
|
|
var dir = new DirectoryInfo(AppContext.BaseDirectory);
|
|
while (dir is not null && !Directory.Exists(Path.Combine(dir.FullName, "src", "WebDrop.Core"))) dir = dir.Parent;
|
|
return Path.Combine(dir?.FullName ?? throw new InvalidOperationException("找不到 server/src"), "src");
|
|
}
|
|
|
|
// 这些写法只能出现在 ChannelPolicy.cs(数据类的定义和令牌校验除外)
|
|
private static readonly (string Name, Regex Pattern)[] Forbidden =
|
|
[
|
|
("直接读频道访问授权的读写位", new Regex(@"\.(ChatRead|ChatWrite|FilesRead|FilesUpload)\b")),
|
|
("直接比较是不是所有者", new Regex(@"Role\s*[!=]=\s*Role\.Owner")),
|
|
("自己拼「所有者或创建者」", new Regex(@"AccountName\s*==\s*\w+\.CreatorAccount")),
|
|
];
|
|
|
|
// 令牌校验(凭据层,不是授权规则)和数据定义,允许出现
|
|
private static readonly string[] Allowed =
|
|
["ChannelPolicy.cs", "WorkspaceCrypto.cs", "RequestAuth.cs", "ShareService.cs"];
|
|
|
|
[Fact]
|
|
public void AuthorizationRulesAreWrittenOnlyInChannelPolicy()
|
|
{
|
|
var offenders = new List<string>();
|
|
foreach (var file in Directory.EnumerateFiles(SourceRoot(), "*.cs", SearchOption.AllDirectories))
|
|
{
|
|
if (file.Contains(Path.DirectorySeparatorChar + "obj" + Path.DirectorySeparatorChar) || file.Contains(Path.DirectorySeparatorChar + "bin" + Path.DirectorySeparatorChar)) continue;
|
|
if (Allowed.Contains(Path.GetFileName(file))) continue;
|
|
var lines = File.ReadAllLines(file);
|
|
for (int i = 0; i < lines.Length; i++)
|
|
{
|
|
if (lines[i].TrimStart().StartsWith("//") || lines[i].TrimStart().StartsWith("///")) continue;
|
|
foreach (var (name, pattern) in Forbidden)
|
|
if (pattern.IsMatch(lines[i])) offenders.Add($"{Path.GetFileName(file)}:{i + 1} {name}: {lines[i].Trim()}");
|
|
}
|
|
}
|
|
Assert.True(offenders.Count == 0, "这些地方在 ChannelPolicy 之外重新判断了权限,请改成调用 ChannelPolicy:\n" + string.Join("\n", offenders));
|
|
}
|
|
}
|