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
@@ -10,7 +10,7 @@ public sealed partial class ChannelService
|
||||
{
|
||||
var channel = tx.GetChannel(id)!;
|
||||
var role = tx.GetChannelMember(id, username)?.Role == "owner" ? Role.Owner : channel.WriteHash is not null ? Role.Write : Role.Read;
|
||||
return ToInfo(channel, tx.CountMembers(id), new Principal(role, [], username));
|
||||
return ToInfo(channel, tx.CountMembers(id), new Principal(role, username));
|
||||
}).ToList());
|
||||
private static WorkspaceState NewWorkspace(string username, long now)
|
||||
{
|
||||
@@ -19,7 +19,7 @@ public sealed partial class ChannelService
|
||||
}
|
||||
public WorkspaceState GetWorkspace(Id16 id, Credentials creds) => store.Read(tx =>
|
||||
{
|
||||
var (space, principal) = Authenticate(tx, id, creds, SeatRule.Required);
|
||||
var (space, principal) = Authenticate(tx, id, creds, Membership.Required);
|
||||
var state = tx.GetWorkspace(id) ?? new WorkspaceState();
|
||||
if (principal.AccountName != space.CreatorAccount)
|
||||
{
|
||||
@@ -42,8 +42,7 @@ public sealed partial class ChannelService
|
||||
{
|
||||
var state = store.Write(tx =>
|
||||
{
|
||||
var (channel, principal) = Authenticate(tx, id, creds, SeatRule.Required);
|
||||
if (requireAccount && principal.AccountName is null) throw new WebDropException(ErrorCode.AccountRequired);
|
||||
var (channel, principal) = Authenticate(tx, id, creds, Membership.Required);
|
||||
if (requireAccount && principal.Role != Role.Owner) throw new WebDropException(ErrorCode.Forbidden);
|
||||
if (!ChannelPolicy.CanWrite(channel, principal)) throw new WebDropException(ErrorCode.Forbidden);
|
||||
var current = tx.GetWorkspace(id) ?? new WorkspaceState();
|
||||
@@ -97,7 +96,7 @@ public sealed partial class ChannelService
|
||||
if (!Id16.TryParse(itemId, out var parsed)) throw new WebDropException(ErrorCode.BadRequest);
|
||||
var item = tx.GetItem(id, parsed) ?? throw new WebDropException(ErrorCode.NotFound);
|
||||
if ((item.Flags & (FrameFlags.Control | FrameFlags.Snapshot)) != 0) throw new WebDropException(ErrorCode.BadRequest);
|
||||
if (principal.Role != Role.Owner && (item.AuthorAccount is not null ? item.AuthorAccount != principal.AccountName : !item.AuthorHash.AsSpan().SequenceEqual(principal.EndpointHash))) throw new WebDropException(ErrorCode.Forbidden);
|
||||
if (principal.Role != Role.Owner && item.AuthorAccount != principal.AccountName) throw new WebDropException(ErrorCode.Forbidden);
|
||||
state.Locations.RemoveAll(l => l.ItemId == itemId);
|
||||
state.Locations.Add(new WorkspaceLocation { ItemId = itemId, ThreadId = threadId, FolderId = folderId, AuthorAccount = item.AuthorAccount });
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user