mirror of
https://github.com/AsamK/signal-cli
synced 2025-09-02 20:40:38 +00:00
DBus sendTyping and getGroupsByName
flesh out sendTyping method to include multiple recipients new getGroupsByName to lookup groupId when you know the group name update documentation
This commit is contained in:
parent
f5089789fb
commit
cc738e55b5
7 changed files with 224 additions and 58 deletions
|
@ -106,6 +106,7 @@ Exceptions: None
|
|||
=== Group control methods
|
||||
The following methods listen to the recipient's object path, which is constructed as follows:
|
||||
"/org/asamk/Signal/" + DBusNumber
|
||||
|
||||
* DBusNumber : recipient's phone number, with underscore (_) replacing plus (+)
|
||||
|
||||
createGroup(groupName<s>, members<as>, avatar<s>) -> groupId<ay>::
|
||||
|
@ -114,17 +115,28 @@ createGroup(groupName<s>, members<as>, avatar<s>) -> groupId<ay>::
|
|||
* avatar : Filename of avatar picture to be set for group (empty if none)
|
||||
* groupId : Byte array representing the internal group identifier
|
||||
|
||||
Exceptions: AttachmentInvalid, Failure, InvalidNumber;
|
||||
Exceptions: AttachmentInvalid, Failure, InvalidNumber
|
||||
|
||||
getGroup(groupId<ay>) -> objectPath<o>::
|
||||
* groupId : Byte array representing the internal group identifier
|
||||
* objectPath : DBusPath for the group
|
||||
|
||||
getGroupMembers(groupId<ay>) -> members<as>::
|
||||
getGroup(groupId<ay>) -> groupPath<o>::
|
||||
* groupId : Byte array representing the internal group identifier
|
||||
* members : String array with the phone numbers of all active members of a group
|
||||
* groupPath : DBusPath for the group
|
||||
|
||||
Exceptions: None, if the group name is not found an empty array is returned
|
||||
Exceptions: GroupNotFound
|
||||
|
||||
getGroups() -> groupPaths<o>::
|
||||
* groupPaths : DBusPaths for the groups
|
||||
|
||||
All groups known are returned, regardless of their active or blocked status.
|
||||
|
||||
Exceptions: None
|
||||
|
||||
getGroupsByName(groupName<s>) -> groupIds<aay>::
|
||||
* groupName : String representing the display name of the group
|
||||
* groupIds : Array of Byte arrays representing the internal group identifiers
|
||||
|
||||
Returns empty array if no groups match the groupName.
|
||||
|
||||
Exceptions: None
|
||||
|
||||
joinGroup(inviteURI<s>) -> <>::
|
||||
* inviteURI : String starting with https://signal.group/#
|
||||
|
@ -134,8 +146,8 @@ Behavior of this method depends on the `requirePermission` parameter of the `ena
|
|||
Exceptions: Failure
|
||||
|
||||
listGroups() -> groups<a(oays)>::
|
||||
* groups : Array of Structs(objectPath, groupId, groupName)
|
||||
** objectPath : DBusPath
|
||||
* groups : Array of Structs(groupPath, groupId, groupName)
|
||||
** groupPath : DBusPath for the group
|
||||
** groupId : Byte array representing the internal group identifier
|
||||
** groupName : String representing the display name of the group
|
||||
|
||||
|
@ -167,10 +179,12 @@ Exceptions: Failure, GroupNotFound, InvalidGroupId
|
|||
=== Group methods
|
||||
The following methods listen to the group's object path, which can be obtained from the listGroups() method and is constructed as follows:
|
||||
"/org/asamk/Signal/" + DBusNumber + "/Groups/" + DBusGroupId
|
||||
|
||||
* DBusNumber : recipient's phone number, with underscore (_) replacing plus (+)
|
||||
* DBusGroupId : groupId in base64 format, with underscore (_) replacing plus (+), equals (=), or slash (/)
|
||||
|
||||
Groups have the following (case-sensitive) properties:
|
||||
|
||||
* Id<ay> (read-only) : Byte array representing the internal group identifier
|
||||
* Name<s> : Display name of the group
|
||||
* Description<s> : Description of the group
|
||||
|
@ -253,19 +267,32 @@ Exceptions: Failure
|
|||
=== Deprecated group control methods
|
||||
The following deprecated methods listen to the recipient's object path, which is constructed as follows:
|
||||
"/org/asamk/Signal/" + DBusNumber
|
||||
|
||||
* DBusNumber : recipient's phone number, with underscore (_) replacing plus (+)
|
||||
|
||||
getGroupIds() -> groupList<aay>::
|
||||
groupList : Array of Byte arrays representing the internal group identifiers
|
||||
getGroupIds() -> groupIds<aay>::
|
||||
* groupIds : Array of Byte arrays representing the internal group identifiers
|
||||
|
||||
All groups known are returned, regardless of their active or blocked status. To query that use isMember() and isGroupBlocked()
|
||||
All groups known are returned, regardless of their active or blocked status.
|
||||
|
||||
Replacement: Use the `getGroups()` method.
|
||||
|
||||
Exceptions: None
|
||||
|
||||
getGroupMembers(groupId<ay>) -> members<as>::
|
||||
* groupId : Byte array representing the internal group identifier
|
||||
* members : String array with the phone numbers of all active members of a group
|
||||
|
||||
Replacement: Use the `Members` property.
|
||||
|
||||
Exceptions: None, if the group name is not found an empty array is returned
|
||||
|
||||
getGroupName(groupId<ay>) -> groupName<s>::
|
||||
* groupId : Byte array representing the internal group identifier
|
||||
* groupName : The display name of the group
|
||||
|
||||
Replacement: Use the `Name` property.
|
||||
|
||||
Exceptions: None, if the group name is not found an empty string is returned
|
||||
|
||||
isGroupBlocked(groupId<ay>) -> isGroupBlocked<b>::
|
||||
|
@ -274,6 +301,8 @@ isGroupBlocked(groupId<ay>) -> isGroupBlocked<b>::
|
|||
|
||||
Dbus will not forward messages from a group when you have blocked it.
|
||||
|
||||
Replacement: Use the `IsBlocked` property.
|
||||
|
||||
Exceptions: InvalidGroupId, Failure
|
||||
|
||||
isMember(groupId<ay>) -> isMember<b>::
|
||||
|
@ -282,11 +311,17 @@ isMember(groupId<ay>) -> isMember<b>::
|
|||
|
||||
Note that this method does not raise an Exception for a non-existing/unknown group but will simply return 0 (false)
|
||||
|
||||
Replacement: Use the `IsMember` property.
|
||||
|
||||
Exceptions: None
|
||||
|
||||
quitGroup(groupId<ay>) -> <>::
|
||||
* groupId : Byte array representing the internal group identifier
|
||||
|
||||
Note that quitting a group will not remove the group from the getGroupIds command, but set it inactive which can be tested with isMember()
|
||||
|
||||
Replacement: Use the `quitGroup()` group method.
|
||||
|
||||
Exceptions: GroupNotFound, Failure, InvalidGroupId
|
||||
|
||||
setGroupBlocked(groupId<ay>, block<b>) -> <>::
|
||||
|
@ -295,6 +330,8 @@ setGroupBlocked(groupId<ay>, block<b>) -> <>::
|
|||
|
||||
Messages from blocked groups will no longer be forwarded via DBus.
|
||||
|
||||
Replacement: Use the `IsBlocked` property.
|
||||
|
||||
Exceptions: GroupNotFound, InvalidGroupId
|
||||
|
||||
updateGroup(groupId<ay>, newName<s>, members<as>, avatar<s>) -> groupId<ay>::
|
||||
|
@ -303,11 +340,19 @@ updateGroup(groupId<ay>, newName<s>, members<as>, avatar<s>) -> groupId<ay>::
|
|||
* members : String array of new members to be invited to group
|
||||
* avatar : Filename of avatar picture to be set for group (empty if none)
|
||||
|
||||
To create a new group, send an empty groupId and the newName. The return value
|
||||
will be the groupId randomly assigned to the new group.
|
||||
|
||||
Replacement: To create a group, use the `createGroup()` group method. To
|
||||
update the name, members, or avatar, use the respective property (`Name`,
|
||||
`Members`, `Avatar`).
|
||||
|
||||
Exceptions: AttachmentInvalid, Failure, InvalidNumber, GroupNotFound
|
||||
|
||||
=== Device control methods
|
||||
The following methods listen to the recipient's object path, which is constructed as follows:
|
||||
"/org/asamk/Signal/" + DBusNumber
|
||||
|
||||
* DBusNumber : recipient's phone number, with underscore (_) replacing plus (+)
|
||||
|
||||
addDevice(deviceUri<s>) -> <>::
|
||||
|
@ -315,13 +360,13 @@ addDevice(deviceUri<s>) -> <>::
|
|||
|
||||
getDevice(deviceId<x>) -> devicePath<o>::
|
||||
* deviceId : Long representing a deviceId
|
||||
* devicePath : DBusPath object for the device
|
||||
* devicePath : DBusPath for the device
|
||||
|
||||
Exceptions: DeviceNotFound
|
||||
|
||||
listDevices() -> devices<a(oxs)>::
|
||||
* devices : Array of structs (objectPath, id, name)
|
||||
** objectPath : DBusPath representing the device's object path
|
||||
* devices : Array of structs (devicePath, id, name)
|
||||
** devicePath : DBusPath representing the device
|
||||
** id : Long representing the deviceId
|
||||
** name : String representing the device's name
|
||||
|
||||
|
@ -342,10 +387,12 @@ Exceptions: Failure
|
|||
=== Device methods and properties
|
||||
The following methods listen to the device's object path, which is constructed as follows:
|
||||
"/org/asamk/Signal/" + DBusNumber + "/Devices/" + deviceId
|
||||
|
||||
* DBusNumber : recipient's phone number, with underscore (_) replacing plus (+)
|
||||
* deviceId : Long representing the device identifier (obtained from listDevices() method)
|
||||
|
||||
Devices have the following (case-sensitive) properties:
|
||||
|
||||
* Id<x> (read-only) : Long representing the device identifier
|
||||
* Created<x> (read-only) : Long representing the number of milliseconds since the Unix epoch
|
||||
* LastSeen<x> (read-only) : Long representing the number of milliseconds since the Unix epoch
|
||||
|
@ -473,11 +520,23 @@ Depending on the type of the recipient(s) field this deletes a message with one
|
|||
|
||||
Exceptions: Failure, InvalidNumber
|
||||
|
||||
sendTyping(recipient<s>, stop<b>) -> <>::
|
||||
* recipient : Phone number of a single recipient
|
||||
* targetSentTimestamp : True, if typing state should be stopped
|
||||
sendTyping(number<s>, stop<b>) -> <>::
|
||||
* number : Phone number of a single recipient
|
||||
* stop : true = stop typing, false = start typing
|
||||
|
||||
Exceptions: Failure, GroupNotFound, UntrustedIdentity
|
||||
Stop or start sending typing indicators to a single recipient.
|
||||
|
||||
Exceptions: Failure, UntrustedIdentity
|
||||
|
||||
sendTyping(stop<b>, groupIdStrings<as>, numbers<as>) -> <>::
|
||||
* stop : true = stop typing, false = start typing
|
||||
* groupIdStrings : List of strings representing groupIds in base64-encoded format for the groups
|
||||
* numbers : List of phone numbers for recipients
|
||||
|
||||
Stop or start sending typing indicators to a list of recipients and/or a list of groups. The groupIdString is
|
||||
derived from the groupId byte array by encoding it in base64 form.
|
||||
|
||||
Exceptions: Failure, GroupNotFound, UntrustedIdentity;
|
||||
|
||||
setContactBlocked(number<s>, block<b>) -> <>::
|
||||
* number : Phone number affected by method
|
||||
|
|
|
@ -31,8 +31,14 @@ public interface Signal extends DBusInterface {
|
|||
|
||||
void sendTyping(
|
||||
String recipient, boolean stop
|
||||
) throws Error.Failure, Error.UntrustedIdentity;
|
||||
|
||||
void sendTyping(
|
||||
boolean stop, List<String> groupIdStrings, List<String> numbers
|
||||
) throws Error.Failure, Error.GroupNotFound, Error.UntrustedIdentity;
|
||||
|
||||
List<byte[]> getGroupsByName(String groupName);
|
||||
|
||||
void sendReadReceipt(
|
||||
String recipient, List<Long> messageIds
|
||||
) throws Error.Failure, Error.UntrustedIdentity;
|
||||
|
|
|
@ -24,6 +24,7 @@ public interface SignalControl extends DBusInterface {
|
|||
|
||||
void verifyWithPin(String number, String verificationCode, String pin) throws Error.Failure, Error.InvalidNumber;
|
||||
|
||||
String link() throws Error.Failure;
|
||||
String link(String newDeviceName) throws Error.Failure;
|
||||
|
||||
public String version();
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.asamk.signal.dbus;
|
|||
|
||||
import org.asamk.Signal;
|
||||
import org.asamk.signal.DbusConfig;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.AttachmentInvalidException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.manager.NotMasterDeviceException;
|
||||
|
@ -298,14 +299,17 @@ public class DbusManagerImpl implements Manager {
|
|||
public void sendTypingMessage(
|
||||
final TypingAction action, final Set<RecipientIdentifier> recipients
|
||||
) throws IOException, UntrustedIdentityException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException {
|
||||
List<String> numbers = new ArrayList<>();
|
||||
List<String> groupIdStrings = new ArrayList<>();
|
||||
boolean typingAction = (action == TypingAction.START);
|
||||
for (final var recipient : recipients) {
|
||||
if (recipient instanceof RecipientIdentifier.Single) {
|
||||
signal.sendTyping(((RecipientIdentifier.Single) recipient).getIdentifier(),
|
||||
action == TypingAction.STOP);
|
||||
numbers.add(((RecipientIdentifier.Single) recipient).getIdentifier());
|
||||
} else if (recipient instanceof RecipientIdentifier.Group) {
|
||||
throw new UnsupportedOperationException();
|
||||
groupIdStrings.add(((RecipientIdentifier.Group) recipient).groupId.toBase64());
|
||||
}
|
||||
}
|
||||
signal.sendTyping(typingAction, groupIdStrings, numbers);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -131,6 +131,11 @@ public class DbusSignalControlImpl implements org.asamk.SignalControl {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String link() throws Error.Failure {
|
||||
return link("cli");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String link(final String newDeviceName) throws Error.Failure {
|
||||
try {
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.asamk.signal.manager.Manager;
|
|||
import org.asamk.signal.manager.NotMasterDeviceException;
|
||||
import org.asamk.signal.manager.StickerPackInvalidException;
|
||||
import org.asamk.signal.manager.UntrustedIdentityException;
|
||||
import org.asamk.signal.manager.api.Group;
|
||||
import org.asamk.signal.manager.api.Identity;
|
||||
import org.asamk.signal.manager.api.Message;
|
||||
import org.asamk.signal.manager.api.RecipientIdentifier;
|
||||
|
@ -23,7 +24,9 @@ import org.asamk.signal.manager.groups.LastGroupAdminException;
|
|||
import org.asamk.signal.manager.groups.NotAGroupMemberException;
|
||||
import org.asamk.signal.manager.storage.recipients.Profile;
|
||||
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
|
||||
import org.asamk.signal.util.CommandUtil;
|
||||
import org.asamk.signal.util.ErrorUtils;
|
||||
|
||||
import org.freedesktop.dbus.DBusPath;
|
||||
import org.freedesktop.dbus.connections.impl.DBusConnection;
|
||||
import org.freedesktop.dbus.exceptions.DBusException;
|
||||
|
@ -191,6 +194,25 @@ public class DbusSignalImpl implements Signal {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<byte[]> getGroupsByName(String groupName) {
|
||||
List<byte[]>groupList = new ArrayList<>();
|
||||
List<byte[]>result = new ArrayList<>();
|
||||
groupList = getGroupIds();
|
||||
org.asamk.signal.manager.api.Group group = null;
|
||||
for (byte[] groupId : groupList) {
|
||||
try {
|
||||
group = m.getGroup(getGroupId(groupId));
|
||||
} catch (AssertionError e) {
|
||||
throw new Error.Failure(e.getMessage());
|
||||
}
|
||||
if (group.getTitle().equals(groupName)) {
|
||||
result.add(groupId);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long sendGroupRemoteDeleteMessage(
|
||||
final long targetSentTimestamp, final byte[] groupId
|
||||
|
@ -245,26 +267,6 @@ public class DbusSignalImpl implements Signal {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTyping(
|
||||
final String recipient, final boolean stop
|
||||
) throws Error.Failure, Error.GroupNotFound, Error.UntrustedIdentity {
|
||||
try {
|
||||
var recipients = new ArrayList<String>(1);
|
||||
recipients.add(recipient);
|
||||
m.sendTypingMessage(stop ? TypingAction.STOP : TypingAction.START,
|
||||
getSingleRecipientIdentifiers(recipients, m.getSelfNumber()).stream()
|
||||
.map(RecipientIdentifier.class::cast)
|
||||
.collect(Collectors.toSet()));
|
||||
} catch (IOException e) {
|
||||
throw new Error.Failure(e.getMessage());
|
||||
} catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) {
|
||||
throw new Error.GroupNotFound(e.getMessage());
|
||||
} catch (UntrustedIdentityException e) {
|
||||
throw new Error.UntrustedIdentity(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendReadReceipt(
|
||||
final String recipient, final List<Long> messageIds
|
||||
|
@ -363,6 +365,44 @@ public class DbusSignalImpl implements Signal {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTyping(String recipient, boolean stop) {
|
||||
List<String> numbers = Arrays.asList(recipient);
|
||||
List<String> groupIdStrings = Arrays.asList();
|
||||
sendTyping(stop, null, numbers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTyping(boolean stop, List<String> groupIdStrings, List<String> numbers) {
|
||||
final boolean noNumbers = numbers == null || numbers.isEmpty();
|
||||
final boolean noGroup = groupIdStrings == null || groupIdStrings.isEmpty();
|
||||
if (noNumbers && noGroup) {
|
||||
throw new Error.Failure("No recipients given");
|
||||
}
|
||||
|
||||
final TypingAction action = stop ? TypingAction.STOP : TypingAction.START;
|
||||
final var timestamp = System.currentTimeMillis();
|
||||
final var localNumber = m.getSelfNumber();
|
||||
Set<RecipientIdentifier> recipients = new HashSet<RecipientIdentifier>();
|
||||
|
||||
try {
|
||||
if (!noGroup) {
|
||||
recipients.addAll(CommandUtil.getGroupIdentifiers(groupIdStrings));
|
||||
}
|
||||
|
||||
if (!noNumbers) {
|
||||
recipients.addAll(CommandUtil.getSingleRecipientIdentifiers(numbers, localNumber));
|
||||
}
|
||||
m.sendTypingMessage(action, recipients);
|
||||
} catch (IOException e) {
|
||||
throw new Error.Failure("Failed to send message: " + e.getMessage());
|
||||
} catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) {
|
||||
throw new Error.InvalidGroupId("Invalid group id: " + e.getMessage());
|
||||
} catch (Exception e) {
|
||||
throw new Error.UntrustedIdentity("Failed to send message: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Since contact names might be empty if not defined, also potentially return
|
||||
// the profile name
|
||||
@Override
|
||||
|
@ -404,10 +444,19 @@ public class DbusSignalImpl implements Signal {
|
|||
|
||||
@Override
|
||||
public void setGroupBlocked(final byte[] groupId, final boolean blocked) {
|
||||
GroupId group = null;
|
||||
try {
|
||||
m.setGroupBlocked(getGroupId(groupId), blocked);
|
||||
group = getGroupId(groupId);
|
||||
} catch (AssertionError e) {
|
||||
throw new Error.Failure(e.getMessage());
|
||||
}
|
||||
if (group == null) {
|
||||
throw new Error.InvalidGroupId("GroupId is null.");
|
||||
}
|
||||
try {
|
||||
m.setGroupBlocked(group, blocked);
|
||||
} catch (NotMasterDeviceException e) {
|
||||
throw new Error.Failure("This command doesn't work on linked devices.");
|
||||
throw new Error.Failure("This command doesn't work on linked device");
|
||||
} catch (GroupNotFoundException e) {
|
||||
throw new Error.GroupNotFound(e.getMessage());
|
||||
} catch (IOException e) {
|
||||
|
@ -443,9 +492,14 @@ public class DbusSignalImpl implements Signal {
|
|||
|
||||
@Override
|
||||
public String getGroupName(final byte[] groupId) {
|
||||
var group = m.getGroup(getGroupId(groupId));
|
||||
if (group == null || group.getTitle() == null) {
|
||||
return "";
|
||||
org.asamk.signal.manager.api.Group group = null;
|
||||
try {
|
||||
group = m.getGroup(getGroupId(groupId));
|
||||
} catch (AssertionError e) {
|
||||
throw new Error.Failure(e.getMessage());
|
||||
}
|
||||
if (group == null) {
|
||||
throw new Error.InvalidGroupId("GroupId is null.");
|
||||
} else {
|
||||
return group.getTitle();
|
||||
}
|
||||
|
@ -453,9 +507,14 @@ public class DbusSignalImpl implements Signal {
|
|||
|
||||
@Override
|
||||
public List<String> getGroupMembers(final byte[] groupId) {
|
||||
var group = m.getGroup(getGroupId(groupId));
|
||||
org.asamk.signal.manager.api.Group group = null;
|
||||
try {
|
||||
group = m.getGroup(getGroupId(groupId));
|
||||
} catch (AssertionError e) {
|
||||
throw new Error.Failure(e.getMessage());
|
||||
}
|
||||
if (group == null) {
|
||||
return List.of();
|
||||
throw new Error.InvalidGroupId("GroupId is null.");
|
||||
} else {
|
||||
final var members = group.getMembers();
|
||||
return getRecipientStrings(members);
|
||||
|
@ -638,7 +697,15 @@ public class DbusSignalImpl implements Signal {
|
|||
|
||||
@Override
|
||||
public void quitGroup(final byte[] groupId) {
|
||||
var group = getGroupId(groupId);
|
||||
GroupId group = null;
|
||||
try {
|
||||
group = getGroupId(groupId);
|
||||
} catch (AssertionError e) {
|
||||
throw new Error.Failure(e.getMessage());
|
||||
}
|
||||
if (group == null) {
|
||||
throw new Error.InvalidGroupId("GroupId is null.");
|
||||
}
|
||||
try {
|
||||
m.quitGroup(group, Set.of());
|
||||
} catch (GroupNotFoundException | NotAGroupMemberException e) {
|
||||
|
@ -673,9 +740,14 @@ public class DbusSignalImpl implements Signal {
|
|||
|
||||
@Override
|
||||
public boolean isGroupBlocked(final byte[] groupId) {
|
||||
var group = m.getGroup(getGroupId(groupId));
|
||||
org.asamk.signal.manager.api.Group group = null;
|
||||
try {
|
||||
group = m.getGroup(getGroupId(groupId));
|
||||
} catch (AssertionError e) {
|
||||
throw new Error.Failure(e.getMessage());
|
||||
}
|
||||
if (group == null) {
|
||||
return false;
|
||||
throw new Error.InvalidGroupId("GroupId is null.");
|
||||
} else {
|
||||
return group.isBlocked();
|
||||
}
|
||||
|
@ -683,9 +755,14 @@ public class DbusSignalImpl implements Signal {
|
|||
|
||||
@Override
|
||||
public boolean isMember(final byte[] groupId) {
|
||||
var group = m.getGroup(getGroupId(groupId));
|
||||
org.asamk.signal.manager.api.Group group = null;
|
||||
try {
|
||||
group = m.getGroup(getGroupId(groupId));
|
||||
} catch (AssertionError e) {
|
||||
throw new Error.Failure(e.getMessage());
|
||||
}
|
||||
if (group == null) {
|
||||
return false;
|
||||
throw new Error.InvalidGroupId("GroupId is null.");
|
||||
} else {
|
||||
return group.isMember();
|
||||
}
|
||||
|
@ -848,6 +925,20 @@ public class DbusSignalImpl implements Signal {
|
|||
}
|
||||
|
||||
private static String getGroupObjectPath(String basePath, byte[] groupId) {
|
||||
/* note that DBus cannot provide a one-to-one reverse translation
|
||||
* of groupPath to groupId. This is because Signal uses base64 for
|
||||
* its group strings, converting any slash (/) to an underscore but
|
||||
* retaining any plus (+) symbol.
|
||||
*
|
||||
* But DBus forbids both slash and plus, so both must be converted
|
||||
* to an underscore, as DBus provides for only 63 of the 64 characters.
|
||||
*
|
||||
* The solution is to use the groupPath to get the Id group property,
|
||||
* which is an array of bytes, then use Base64.getEncoder().encodeToString(groupId)
|
||||
* to obtain the groupIdString. Note that it is theoretically possible, though
|
||||
* extremely unlikely, that two different groups will map to the same groupPath.
|
||||
*
|
||||
*/
|
||||
return basePath + "/Groups/" + Base64.getEncoder()
|
||||
.encodeToString(groupId)
|
||||
.replace("+", "_")
|
||||
|
|
|
@ -63,12 +63,12 @@ public class CommandUtil {
|
|||
return groupIds;
|
||||
}
|
||||
|
||||
public static GroupId getGroupId(String groupId) throws UserErrorException {
|
||||
if (groupId == null) {
|
||||
public static GroupId getGroupId(String groupIdString) throws UserErrorException {
|
||||
if (groupIdString == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return GroupId.fromBase64(groupId);
|
||||
return GroupId.fromBase64(groupIdString);
|
||||
} catch (GroupIdFormatException e) {
|
||||
throw new UserErrorException("Invalid group id: " + e.getMessage());
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue