feat(server)!: require a logged-in account for every channel request
Drop unauthenticated guests from channels: the allow_guests setting, the /guests endpoints and the guest seat table are gone, and requests without an account session get 401 account_required. Share links are unaffected. Contract version is now 8.0.0.
This commit is contained in:
1 parent
b1ac11e1d7
commit
c858bd2a09
31 files changed
+194
-358
No files matched your search
@@ -126,11 +126,6 @@ public class RestTests(ServerFixture s) : IClassFixture<ServerFixture>
|
||||
|
||||
using (var patch = await OwnerRequest(HttpMethod.Patch, $"/api/v1/channels/{ch.Id}/settings", JsonBody(new { max_members = 3 })))
|
||||
Assert.Equal(HttpStatusCode.OK, patch.StatusCode);
|
||||
using (var guests = await OwnerRequest(HttpMethod.Get, $"/api/v1/channels/{ch.Id}/guests"))
|
||||
Assert.Equal(HttpStatusCode.OK, guests.StatusCode);
|
||||
using (var absentGuest = await OwnerRequest(HttpMethod.Delete,
|
||||
$"/api/v1/channels/{ch.Id}/guests/{B64(RandomNumberGenerator.GetBytes(32))}"))
|
||||
await AssertErrorAsync(absentGuest, 404, "not_found");
|
||||
using (var deleted = await OwnerRequest(HttpMethod.Delete, $"/api/v1/channels/{ch.Id}"))
|
||||
Assert.Equal(HttpStatusCode.NoContent, deleted.StatusCode);
|
||||
await AssertErrorAsync(await s.Http.SendAsync(s.Req(HttpMethod.Get, $"/api/v1/channels/{ch.Id}", ch.Owner)), 404, "not_found");
|
||||
@@ -232,7 +227,7 @@ public class RestTests(ServerFixture s) : IClassFixture<ServerFixture>
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task JoinListGuestsAndRelease()
|
||||
public async Task JoinMembersAndRevoke()
|
||||
{
|
||||
var ch = await s.CreateAsync();
|
||||
|
||||
@@ -241,26 +236,24 @@ public class RestTests(ServerFixture s) : IClassFixture<ServerFixture>
|
||||
Assert.Equal(2, j.GetProperty("members_used").GetInt32());
|
||||
Assert.Equal(2, j.GetProperty("members_max").GetInt32());
|
||||
Assert.False(j.TryGetProperty("endpoint_hash", out _)); // 终端不再对外暴露
|
||||
string memberHash = B64(System.Security.Cryptography.SHA256.HashData(ch.Reader.EndpointSecret));
|
||||
|
||||
// 第三个终端被拒绝
|
||||
var third = new Who("read", ch.ReadToken, System.Security.Cryptography.RandomNumberGenerator.GetBytes(32));
|
||||
// 第三个账号被拒绝:成员已满
|
||||
var thirdAccount = s.NewAccountToken("third_" + Guid.NewGuid().ToString("N")[..8]);
|
||||
var third = new Who("read", ch.ReadToken, RandomNumberGenerator.GetBytes(32), thirdAccount);
|
||||
await AssertErrorAsync(await s.JoinAsync(ch, third), 403, "members_full");
|
||||
|
||||
// 访客清单只有所有者能看;账号成员不在其中
|
||||
await AssertErrorAsync(await s.Http.SendAsync(s.Req(HttpMethod.Get, $"/api/v1/channels/{ch.Id}/guests", ch.Reader)), 403, "forbidden");
|
||||
using var list = await s.Http.SendAsync(s.Req(HttpMethod.Get, $"/api/v1/channels/{ch.Id}/guests", ch.Owner));
|
||||
var guests = await ReadJsonAsync(list);
|
||||
Assert.Equal(1, guests.GetArrayLength());
|
||||
Assert.Equal(memberHash, guests[0].GetProperty("endpoint_hash").GetString());
|
||||
// 访客接口已移除
|
||||
using var guests = await s.Http.SendAsync(s.Req(HttpMethod.Get, $"/api/v1/channels/{ch.Id}/guests", ch.Owner));
|
||||
Assert.Equal(HttpStatusCode.NotFound, guests.StatusCode);
|
||||
|
||||
// 设备名接口已移除
|
||||
using var label = await s.Http.SendAsync(s.Req(HttpMethod.Put, $"/api/v1/channels/{ch.Id}/seats/me", ch.Reader, Bytes([9, 8, 7])));
|
||||
Assert.Equal(HttpStatusCode.NotFound, label.StatusCode);
|
||||
// 没有账号会话的请求被拒绝
|
||||
using var anonymous = s.Req(HttpMethod.Post, $"/api/v1/channels/{ch.Id}/join", ch.Reader);
|
||||
anonymous.Headers.Remove("X-WD-Account");
|
||||
await AssertErrorAsync(await s.Http.SendAsync(anonymous), 401, "account_required");
|
||||
|
||||
// 所有者移除访客后,成员失去访问
|
||||
using var release = await s.Http.SendAsync(s.Req(HttpMethod.Delete, $"/api/v1/channels/{ch.Id}/guests/{memberHash}", ch.Owner));
|
||||
Assert.Equal(HttpStatusCode.NoContent, release.StatusCode);
|
||||
// 所有者撤销成员后,成员失去访问
|
||||
using var revoke = await s.Http.SendAsync(s.Req(HttpMethod.Delete, $"/api/v1/channels/{ch.Id}/invitations/fixture_member", ch.Owner));
|
||||
Assert.Equal(HttpStatusCode.NoContent, revoke.StatusCode);
|
||||
await AssertErrorAsync(await s.AppendAsync(ch, ch.Member, Small(NewId())), 403, "not_joined");
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user