Add removeContact command

Closes #335
This commit is contained in:
AsamK 2021-11-26 20:50:54 +01:00
parent 5cd5697aea
commit 7e7e4150e1
14 changed files with 167 additions and 7 deletions

View file

@ -174,6 +174,10 @@ public interface Manager extends Closeable {
SendMessageResults sendEndSessionMessage(Set<RecipientIdentifier.Single> recipients) throws IOException;
void deleteRecipient(RecipientIdentifier.Single recipient) throws IOException;
void deleteContact(RecipientIdentifier.Single recipient) throws IOException;
void setContactName(
RecipientIdentifier.Single recipient, String name
) throws NotMasterDeviceException, IOException;

View file

@ -279,13 +279,17 @@ public class ManagerImpl implements Manager {
*
* @param numbers The set of phone number in question
* @return A map of numbers to canonicalized number and uuid. If a number is not registered the uuid is null.
* @throws IOException if its unable to get the contacts to check if they're registered
* @throws IOException if it's unable to get the contacts to check if they're registered
*/
@Override
public Map<String, Pair<String, UUID>> areUsersRegistered(Set<String> numbers) throws IOException {
Map<String, String> canonicalizedNumbers = numbers.stream().collect(Collectors.toMap(n -> n, n -> {
try {
return PhoneNumberFormatter.formatNumber(n, account.getAccount());
final var canonicalizedNumber = PhoneNumberFormatter.formatNumber(n, account.getAccount());
if (!canonicalizedNumber.equals(n)) {
logger.debug("Normalized number {} to {}.", n, canonicalizedNumber);
}
return canonicalizedNumber;
} catch (InvalidNumberException e) {
return "";
}
@ -774,6 +778,16 @@ public class ManagerImpl implements Manager {
}
}
@Override
public void deleteRecipient(final RecipientIdentifier.Single recipient) throws IOException {
account.removeRecipient(resolveRecipient(recipient));
}
@Override
public void deleteContact(final RecipientIdentifier.Single recipient) throws IOException {
account.getContactStore().deleteContact(resolveRecipient(recipient));
}
@Override
public void setContactName(
RecipientIdentifier.Single recipient, String name

View file

@ -2,6 +2,8 @@ package org.asamk.signal.manager.api;
import org.asamk.signal.manager.groups.GroupId;
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
import org.whispersystems.signalservice.api.util.UuidUtil;
@ -18,9 +20,16 @@ public sealed interface RecipientIdentifier {
static Single fromString(String identifier, String localNumber) throws InvalidNumberException {
try {
return UuidUtil.isUuid(identifier)
? new Uuid(UUID.fromString(identifier))
: new Number(PhoneNumberFormatter.formatNumber(identifier, localNumber));
if (UuidUtil.isUuid(identifier)) {
return new Uuid(UUID.fromString(identifier));
}
final var normalizedNumber = PhoneNumberFormatter.formatNumber(identifier, localNumber);
if (!normalizedNumber.equals(identifier)) {
final Logger logger = LoggerFactory.getLogger(RecipientIdentifier.class);
logger.debug("Normalized number {} to {}.", identifier, normalizedNumber);
}
return new Number(normalizedNumber);
} catch (org.whispersystems.signalservice.api.util.InvalidNumberException e) {
throw new InvalidNumberException(e.getMessage(), e);
}

View file

@ -324,6 +324,14 @@ public class SignalAccount implements Closeable {
senderKeyStore.mergeRecipients(recipientId, toBeMergedRecipientId);
}
public void removeRecipient(final RecipientId recipientId) {
sessionStore.deleteAllSessions(recipientId);
identityKeyStore.deleteIdentity(recipientId);
messageCache.deleteMessages(recipientId);
senderKeyStore.deleteAll(recipientId);
recipientStore.deleteRecipientData(recipientId);
}
public static File getFileName(File dataPath, String account) {
return new File(dataPath, account);
}

View file

@ -13,4 +13,6 @@ public interface ContactsStore {
Contact getContact(RecipientId recipientId);
List<Pair<RecipientId, Contact>> getContacts();
void deleteContact(RecipientId recipientId);
}

View file

@ -172,6 +172,12 @@ public class IdentityKeyStore implements org.whispersystems.libsignal.state.Iden
}
}
public void deleteIdentity(final RecipientId recipientId) {
synchronized (cachedIdentities) {
deleteIdentityLocked(recipientId);
}
}
/**
* @param identifier can be either a serialized uuid or a e164 phone number
*/

View file

@ -71,6 +71,25 @@ public class MessageCache {
return new CachedMessage(cacheFile);
}
public void deleteMessages(final RecipientId recipientId) {
final var recipientMessageCachePath = getMessageCachePath(recipientId);
if (!recipientMessageCachePath.exists()) {
return;
}
for (var file : Objects.requireNonNull(recipientMessageCachePath.listFiles())) {
if (!file.isFile()) {
continue;
}
try {
Files.delete(file.toPath());
} catch (IOException e) {
logger.warn("Failed to delete cache file “{}”, ignoring: {}", file, e.getMessage());
}
}
}
private File getMessageCachePath(RecipientId recipientId) {
if (recipientId == null) {
return messageCachePath;

View file

@ -220,6 +220,25 @@ public class RecipientStore implements RecipientResolver, ContactsStore, Profile
.collect(Collectors.toList());
}
@Override
public void deleteContact(final RecipientId recipientId) {
synchronized (recipients) {
final var recipient = recipients.get(recipientId);
storeRecipientLocked(recipientId, Recipient.newBuilder(recipient).withContact(null).build());
}
}
public void deleteRecipientData(final RecipientId recipientId) {
synchronized (recipients) {
final var recipient = recipients.get(recipientId);
storeRecipientLocked(recipientId,
Recipient.newBuilder()
.withRecipientId(recipientId)
.withAddress(new RecipientAddress(recipient.getAddress().getUuid().orElse(null)))
.build());
}
}
@Override
public Profile getProfile(final RecipientId recipientId) {
final var recipient = getRecipient(recipientId);

View file

@ -63,7 +63,7 @@ public class SenderKeyStore implements SignalServiceSenderKeyStore {
senderKeyRecordStore.deleteAll();
}
public void rotateSenderKeys(RecipientId recipientId) {
public void deleteAll(RecipientId recipientId) {
senderKeySharedStore.deleteAllFor(recipientId);
senderKeyRecordStore.deleteAllFor(recipientId);
}