This commit is contained in:
@@ -24,7 +24,21 @@ public sealed record RemoteSyncBatch(
|
||||
[property: JsonPropertyName("payload_hash")] string PayloadHash,
|
||||
[property: JsonPropertyName("coverage_state")] string CoverageState,
|
||||
[property: JsonPropertyName("conversations")] IReadOnlyList<RemoteSyncConversation> Conversations,
|
||||
[property: JsonPropertyName("messages")] IReadOnlyList<RemoteSyncMessage> Messages);
|
||||
[property: JsonPropertyName("messages")] IReadOnlyList<RemoteSyncMessage> Messages)
|
||||
{
|
||||
[JsonPropertyName("contacts")]
|
||||
public IReadOnlyList<RemoteSyncContact> Contacts { get; init; } = [];
|
||||
|
||||
[JsonPropertyName("contacts_snapshot_id")]
|
||||
public string? ContactsSnapshotId { get; init; }
|
||||
}
|
||||
|
||||
public sealed record RemoteSyncContact(
|
||||
[property: JsonPropertyName("chat_id")] string ChatId,
|
||||
[property: JsonPropertyName("chat_type")] ReportingChatType ChatType,
|
||||
[property: JsonPropertyName("display_name")] string DisplayName,
|
||||
[property: JsonPropertyName("remark")] string Remark,
|
||||
[property: JsonPropertyName("observed_at")] DateTimeOffset ObservedAt);
|
||||
|
||||
public sealed record RemoteSyncConversation(
|
||||
[property: JsonPropertyName("chat_id")] string ChatId,
|
||||
@@ -276,14 +290,19 @@ public static class RemoteDataBatchAuthorization
|
||||
ReportingAuthorization.Check(config, batch.AccountId, conversation.ChatId, conversation.ChatType, ReportingDataType.TaskResult).Allowed).ToArray();
|
||||
var messages = batch.Messages.Where(message =>
|
||||
ReportingAuthorization.Check(config, batch.AccountId, message.ChatId, message.ChatType, ReportingDataType.Message).Allowed).ToArray();
|
||||
var dropped = conversations.Length != batch.Conversations.Count || messages.Length != batch.Messages.Count;
|
||||
var contacts = batch.Contacts.Where(contact =>
|
||||
ReportingAuthorization.Check(config, batch.AccountId, contact.ChatId, contact.ChatType, ReportingDataType.TaskResult).Allowed).ToArray();
|
||||
var dropped = conversations.Length != batch.Conversations.Count || messages.Length != batch.Messages.Count || contacts.Length != batch.Contacts.Count;
|
||||
reason = dropped ? "SomeRecordsDroppedByReporting" : "Authorized";
|
||||
if (conversations.Length == 0 && messages.Length == 0 && (batch.Conversations.Count > 0 || batch.Messages.Count > 0))
|
||||
if (conversations.Length == 0 && messages.Length == 0 && contacts.Length == 0 && (batch.Conversations.Count > 0 || batch.Messages.Count > 0 || batch.Contacts.Count > 0))
|
||||
{
|
||||
reason = "AllRecordsDroppedByReporting";
|
||||
return null;
|
||||
}
|
||||
return dropped ? batch with { CoverageState = "partial", Conversations = conversations, Messages = messages } : batch;
|
||||
if (!dropped)
|
||||
return batch;
|
||||
var filteredBatch = batch with { CoverageState = "partial", Conversations = conversations, Messages = messages, Contacts = contacts };
|
||||
return filteredBatch with { PayloadHash = ComputePayloadHash(filteredBatch) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,7 +459,21 @@ public sealed class RemoteDataBatchQueue
|
||||
{
|
||||
foreach (var value in new[] { batch.NodeId, batch.AccountId, batch.BatchId, batch.SourceGeneration, batch.StreamKey, batch.PayloadHash })
|
||||
RemoteAgentOptions.ValidateIdentifier(value, "sync batch field", 512);
|
||||
if (batch.Sequence < 1 || batch.Conversations.Count + batch.Messages.Count > RemoteDataProtocol.MaxBatchMessages)
|
||||
if (batch.Sequence < 1 || batch.Conversations.Count + batch.Messages.Count > RemoteDataProtocol.MaxBatchMessages
|
||||
|| batch.Contacts.Count > RemoteDataProtocol.MaxBatchItems
|
||||
|| batch.StreamKey is not ("messages" or "contacts")
|
||||
|| batch.StreamKey == "contacts" && (string.IsNullOrWhiteSpace(batch.ContactsSnapshotId) || batch.Conversations.Count > 0 || batch.Messages.Count > 0)
|
||||
|| batch.StreamKey == "messages" && (batch.Contacts.Count > 0 || batch.ContactsSnapshotId is not null))
|
||||
throw new WxAgentException(WxAgentErrorCode.InvalidArgument, "The sync batch sequence or item count is invalid.");
|
||||
if (batch.ContactsSnapshotId is not null)
|
||||
RemoteAgentOptions.ValidateIdentifier(batch.ContactsSnapshotId, "contacts snapshot", 512);
|
||||
foreach (var contact in batch.Contacts)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(contact.ChatId) || contact.ChatId.Length > 512
|
||||
|| contact.DisplayName.Length > 2048 || contact.Remark.Length > 2048
|
||||
|| contact.ChatType is not (ReportingChatType.Group or ReportingChatType.Private)
|
||||
|| contact.ObservedAt == default)
|
||||
throw new WxAgentException(WxAgentErrorCode.InvalidArgument, "The contact record is invalid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user