Signal-iOS/SignalServiceKit/tests/Contacts/OWSRecipientIdentityTest.swift
Max Radermacher d7c52b6ad0
Fix bugs marking SignalRecipients as registered
Previously, low-trust SignalRecipients wouldn’t be marked as registered
unless they were newly-created. Now, they are marked as registered in
places where they should be (eg, successfully sending a message or
fetching a pre key means that the device exists).

As part of this change, SignalRecipients are unregistered by default,
though most call sites still mark them as registered immediately, so the
behavior in practice will be identical. There are a few places (such as
ensureAccountId) which will no longer mark new values as registered.

Finally, creating a new SignalRecipient would also update Storage
Service, even if that recipient was created in response to a storage
service update. Now, recipients updated as part of storage service
operations won’t immediately trigger another storage service update.
2023-01-03 13:23:33 -08:00

143 lines
6.4 KiB
Swift

//
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
import XCTest
import GRDB
@testable import SignalServiceKit
class OWSRecipientIdentityTest: SSKBaseTestSwift {
private lazy var localAddress = CommonGenerator.address()
private lazy var aliceAddress = CommonGenerator.address()
private lazy var bobAddress = CommonGenerator.address()
private lazy var charlieAddress = CommonGenerator.address()
private var recipients: [SignalServiceAddress] {
[aliceAddress, bobAddress, charlieAddress, localAddress]
}
private var groupThread: TSGroupThread!
private var identityKeys = [SignalServiceAddress: Data]()
private func identityKey(_ address: SignalServiceAddress) -> Data {
if let value = identityKeys[address] {
return value
}
let data = Randomness.generateRandomBytes(Int32(kStoredIdentityKeyLength))
identityKeys[address] = data
return data
}
private func createFakeGroup() throws {
// Create local account.
tsAccountManager.registerForTests(withLocalNumber: localAddress.phoneNumber!,
uuid: localAddress.uuid!)
// Create recipients.
write { transaction in
for recipient in self.recipients {
SignalRecipient.fetchOrCreate(for: recipient, trustLevel: .high, transaction: transaction)
.markAsRegistered(transaction: transaction)
}
}
// Create identities for our recipients.
for recipient in recipients {
OWSIdentityManager.shared.saveRemoteIdentity(identityKey(recipient),
address: recipient)
}
// Create a group with our recipients plus us.
self.groupThread = try! GroupManager.createGroupForTests(members: recipients,
name: "Test Group")
}
override func setUp() {
super.setUp()
try! createFakeGroup()
}
func testNoneVerified() throws {
XCTAssertTrue(Self.identityManager.groupContainsUnverifiedMember(groupThread.uniqueId))
}
func testAllVerified() throws {
for recipient in recipients {
OWSIdentityManager.shared.setVerificationState(.verified,
identityKey: identityKey(recipient),
address: recipient,
isUserInitiatedChange: true)
}
XCTAssertFalse(Self.identityManager.groupContainsUnverifiedMember(groupThread.uniqueId))
}
func testSomeVerified() throws {
let recipient = recipients[0]
OWSIdentityManager.shared.setVerificationState(.verified,
identityKey: identityKey(recipient),
address: recipient,
isUserInitiatedChange: true)
XCTAssertTrue(Self.identityManager.groupContainsUnverifiedMember(groupThread.uniqueId))
}
func testSomeNoLongerVerified() throws {
// Verify everyone
for recipient in recipients {
OWSIdentityManager.shared.setVerificationState(.verified,
identityKey: identityKey(recipient),
address: recipient,
isUserInitiatedChange: true)
}
// Make Alice and Bob no-longer-verified.
let deverifiedAddresses = [aliceAddress, bobAddress]
for recipient in deverifiedAddresses {
OWSIdentityManager.shared.setVerificationState(.noLongerVerified,
identityKey: identityKey(recipient),
address: recipient,
isUserInitiatedChange: false)
}
XCTAssertTrue(Self.identityManager.groupContainsUnverifiedMember(groupThread.uniqueId))
// Check that the list of no-longer-verified addresses is just Alice and Bob.
read { transaction in
let noLongerVerifiedAddresses =
OWSRecipientIdentity.noLongerVerifiedAddresses(inGroup: self.groupThread.uniqueId,
limit: 2,
transaction: transaction)
XCTAssertEqual(Set(noLongerVerifiedAddresses), Set(deverifiedAddresses))
}
}
func testNoLongerVerifiedLimit() throws {
for recipient in recipients {
OWSIdentityManager.shared.setVerificationState(.noLongerVerified,
identityKey: identityKey(recipient),
address: recipient,
isUserInitiatedChange: false)
}
// All recipients are no longer verified. Check that the limit is respected.
for limit in 1..<recipients.count {
read { transaction in
let noLongerVerifiedAddresses =
OWSRecipientIdentity.noLongerVerifiedAddresses(inGroup: self.groupThread.uniqueId,
limit: limit,
transaction: transaction)
XCTAssertEqual(noLongerVerifiedAddresses.count, limit)
}
}
}
func testLocalAddressIgnoredForVerifiedCheck() {
// Verify everyone except me.
for recipient in recipients {
if recipient == localAddress {
continue
}
OWSIdentityManager.shared.setVerificationState(.verified,
identityKey: identityKey(recipient),
address: recipient,
isUserInitiatedChange: true)
}
XCTAssertFalse(Self.identityManager.groupContainsUnverifiedMember(groupThread.uniqueId))
}
}