Add commands to update profile name and avatar

Two new commands are added `setProfileName` and `setProfileAvatar` which
allow to update the name and avatar visible by other users for the
current profiles.

Closes #227
This commit is contained in:
Jérémy Bobbio 2019-09-24 19:22:14 +02:00 committed by AsamK
parent c53bb132eb
commit abb6ebc910
6 changed files with 113 additions and 0 deletions

View file

@ -208,6 +208,19 @@ number::
Specify the safety number or fingerprint of the key, only use this option if you have verified Specify the safety number or fingerprint of the key, only use this option if you have verified
the fingerprint. the fingerprint.
setProfileName
--------------
Update the name visible by message recipients for the current users.
name::
New name visible by message recipients.
setProfileAvatar
----------------
Update the avatar visible by message recipients for the current users.
avatar::
Path to the new avatar visible by message recipients.
daemon daemon
~~~~~~ ~~~~~~

View file

@ -20,6 +20,8 @@ public class Commands {
addCommand("removeDevice", new RemoveDeviceCommand()); addCommand("removeDevice", new RemoveDeviceCommand());
addCommand("removePin", new RemovePinCommand()); addCommand("removePin", new RemovePinCommand());
addCommand("send", new SendCommand()); addCommand("send", new SendCommand());
addCommand("setProfileAvatar", new SetProfileAvatarCommand());
addCommand("setProfileName", new SetProfileNameCommand());
addCommand("setPin", new SetPinCommand()); addCommand("setPin", new SetPinCommand());
addCommand("trust", new TrustCommand()); addCommand("trust", new TrustCommand());
addCommand("unregister", new UnregisterCommand()); addCommand("unregister", new UnregisterCommand());

View file

@ -0,0 +1,40 @@
package org.asamk.signal.commands;
import java.io.IOException;
import java.io.File;
import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager;
public class SetProfileAvatarCommand implements LocalCommand {
@Override
public void attachToSubparser(final Subparser subparser) {
subparser.addArgument("avatar")
.help("Path to new profile avatar");
subparser.help("Set the avatar for this profile");
}
@Override
public int handleCommand(final Namespace ns, final Manager m) {
if (!m.isRegistered()) {
System.err.println("User is not registered.");
return 1;
}
String avatarPath = ns.getString("avatar");
File avatarFile = new File(avatarPath);
try {
m.setProfileAvatar(avatarFile);
} catch (IOException e) {
System.err.println("UpdateAccount error: " + e.getMessage());
return 3;
}
return 0;
}
}

View file

@ -0,0 +1,38 @@
package org.asamk.signal.commands;
import java.io.IOException;
import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.manager.Manager;
public class SetProfileNameCommand implements LocalCommand {
@Override
public void attachToSubparser(final Subparser subparser) {
subparser.addArgument("name")
.help("New profile name");
subparser.help("Set a new name for this profile");
}
@Override
public int handleCommand(final Namespace ns, final Manager m) {
if (!m.isRegistered()) {
System.err.println("User is not registered.");
return 1;
}
String name = ns.getString("name");
try {
m.setProfileName(name);
} catch (IOException e) {
System.err.println("UpdateAccount error: " + e.getMessage());
return 3;
}
return 0;
}
}

View file

@ -54,6 +54,7 @@ import org.whispersystems.signalservice.api.push.exceptions.NetworkFailureExcept
import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException; import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException;
import org.whispersystems.signalservice.api.util.InvalidNumberException; import org.whispersystems.signalservice.api.util.InvalidNumberException;
import org.whispersystems.signalservice.api.util.SleepTimer; import org.whispersystems.signalservice.api.util.SleepTimer;
import org.whispersystems.signalservice.api.util.StreamDetails;
import org.whispersystems.signalservice.api.util.UptimeSleepTimer; import org.whispersystems.signalservice.api.util.UptimeSleepTimer;
import org.whispersystems.signalservice.internal.push.SignalServiceProtos; import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
import org.whispersystems.signalservice.internal.push.UnsupportedDataMessageException; import org.whispersystems.signalservice.internal.push.UnsupportedDataMessageException;
@ -204,6 +205,14 @@ public class Manager implements Signal {
accountManager.setAccountAttributes(account.getSignalingKey(), account.getSignalProtocolStore().getLocalRegistrationId(), true, account.getRegistrationLockPin(), getSelfUnidentifiedAccessKey(), false); accountManager.setAccountAttributes(account.getSignalingKey(), account.getSignalProtocolStore().getLocalRegistrationId(), true, account.getRegistrationLockPin(), getSelfUnidentifiedAccessKey(), false);
} }
public void setProfileName(String name) throws IOException {
accountManager.setProfileName(account.getProfileKey(), name);
}
public void setProfileAvatar(File avatar) throws IOException {
accountManager.setProfileAvatar(account.getProfileKey(), Utils.createStreamDetailsFromFile(avatar));
}
public void unregister() throws IOException { public void unregister() throws IOException {
// When setting an empty GCM id, the Signal-Server also sets the fetchesMessages property to false. // When setting an empty GCM id, the Signal-Server also sets the fetchesMessages property to false.
// If this is the master device, other users can't send messages to this number anymore. // If this is the master device, other users can't send messages to this number anymore.

View file

@ -15,6 +15,7 @@ import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.util.InvalidNumberException; import org.whispersystems.signalservice.api.util.InvalidNumberException;
import org.whispersystems.signalservice.api.util.PhoneNumberFormatter; import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
import org.whispersystems.signalservice.api.util.StreamDetails;
import org.whispersystems.signalservice.internal.util.Base64; import org.whispersystems.signalservice.internal.util.Base64;
import java.io.*; import java.io.*;
@ -56,6 +57,16 @@ class Utils {
return new SignalServiceAttachmentStream(attachmentStream, mime, attachmentSize, Optional.of(attachmentFile.getName()), false, preview, 0, 0, caption, null); return new SignalServiceAttachmentStream(attachmentStream, mime, attachmentSize, Optional.of(attachmentFile.getName()), false, preview, 0, 0, caption, null);
} }
static StreamDetails createStreamDetailsFromFile(File file) throws IOException {
InputStream stream = new FileInputStream(file);
final long size = file.length();
String mime = Files.probeContentType(file.toPath());
if (mime == null) {
mime = "application/octet-stream";
}
return new StreamDetails(stream, mime, size);
}
static CertificateValidator getCertificateValidator() { static CertificateValidator getCertificateValidator() {
try { try {
ECPublicKey unidentifiedSenderTrustRoot = Curve.decodePoint(Base64.decode(BaseConfig.UNIDENTIFIED_SENDER_TRUST_ROOT), 0); ECPublicKey unidentifiedSenderTrustRoot = Curve.decodePoint(Base64.decode(BaseConfig.UNIDENTIFIED_SENDER_TRUST_ROOT), 0);