mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-20 21:08:07 +01:00
Support for versioned profiles
Includes support for issuing zkgroup auth credentials
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import org.hibernate.validator.constraints.NotEmpty;
|
||||
import org.signal.zkgroup.profiles.ProfileKeyCommitment;
|
||||
import org.whispersystems.textsecuregcm.util.ExactlySize;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
public class CreateProfileRequest {
|
||||
|
||||
@JsonProperty
|
||||
@NotEmpty
|
||||
private String version;
|
||||
|
||||
@JsonProperty
|
||||
@ExactlySize({108})
|
||||
private String name;
|
||||
|
||||
@JsonProperty
|
||||
private boolean avatar;
|
||||
|
||||
@JsonProperty
|
||||
@NotNull
|
||||
@JsonDeserialize(using = ProfileKeyCommitmentAdapter.Deserializing.class)
|
||||
@JsonSerialize(using = ProfileKeyCommitmentAdapter.Serializing.class)
|
||||
private ProfileKeyCommitment commitment;
|
||||
|
||||
public CreateProfileRequest() {}
|
||||
|
||||
public CreateProfileRequest(ProfileKeyCommitment commitment, String version, String name, boolean wantsAvatar) {
|
||||
this.commitment = commitment;
|
||||
this.version = version;
|
||||
this.name = name;
|
||||
this.avatar = wantsAvatar;
|
||||
}
|
||||
|
||||
public ProfileKeyCommitment getCommitment() {
|
||||
return commitment;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isAvatar() {
|
||||
return avatar;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import org.whispersystems.textsecuregcm.util.Base64;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class GroupCredentials {
|
||||
|
||||
@JsonProperty
|
||||
private List<GroupCredential> credentials;
|
||||
|
||||
public GroupCredentials() {}
|
||||
|
||||
public GroupCredentials(List<GroupCredential> credentials) {
|
||||
this.credentials = credentials;
|
||||
}
|
||||
|
||||
public List<GroupCredential> getCredentials() {
|
||||
return credentials;
|
||||
}
|
||||
|
||||
public static class GroupCredential {
|
||||
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = ByteArraySerializer.class)
|
||||
@JsonDeserialize(using = ByteArrayDeserializer.class)
|
||||
private byte[] credential;
|
||||
|
||||
@JsonProperty
|
||||
private int redemptionTime;
|
||||
|
||||
public GroupCredential() {}
|
||||
|
||||
public GroupCredential(byte[] credential, int redemptionTime) {
|
||||
this.credential = credential;
|
||||
this.redemptionTime = redemptionTime;
|
||||
}
|
||||
|
||||
public byte[] getCredential() {
|
||||
return credential;
|
||||
}
|
||||
|
||||
public int getRedemptionTime() {
|
||||
return redemptionTime;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ByteArraySerializer extends JsonSerializer<byte[]> {
|
||||
@Override
|
||||
public void serialize(byte[] bytes, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
|
||||
jsonGenerator.writeString(Base64.encodeBytes(bytes));
|
||||
}
|
||||
}
|
||||
|
||||
public static class ByteArrayDeserializer extends JsonDeserializer<byte[]> {
|
||||
@Override
|
||||
public byte[] deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
|
||||
return Base64.decode(jsonParser.getValueAsString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,12 @@
|
||||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import org.signal.zkgroup.profiles.ProfileKeyCredentialResponse;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class Profile {
|
||||
@@ -31,11 +35,17 @@ public class Profile {
|
||||
@JsonProperty
|
||||
private UUID uuid;
|
||||
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = ProfileKeyCredentialResponseAdapter.Serializing.class)
|
||||
@JsonDeserialize(using = ProfileKeyCredentialResponseAdapter.Deserializing.class)
|
||||
private ProfileKeyCredentialResponse credential;
|
||||
|
||||
public Profile() {}
|
||||
|
||||
public Profile(String name, String avatar, String identityKey,
|
||||
String unidentifiedAccess, boolean unrestrictedUnidentifiedAccess,
|
||||
UserCapabilities capabilities, String username, UUID uuid)
|
||||
UserCapabilities capabilities, String username, UUID uuid,
|
||||
ProfileKeyCredentialResponse credential)
|
||||
{
|
||||
this.name = name;
|
||||
this.avatar = avatar;
|
||||
@@ -45,6 +55,7 @@ public class Profile {
|
||||
this.capabilities = capabilities;
|
||||
this.username = username;
|
||||
this.uuid = uuid;
|
||||
this.credential = credential;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
@@ -41,4 +41,8 @@ public class ProfileAvatarUploadAttributes {
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import org.signal.zkgroup.InvalidInputException;
|
||||
import org.signal.zkgroup.profiles.ProfileKeyCommitment;
|
||||
import org.whispersystems.textsecuregcm.util.Base64;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ProfileKeyCommitmentAdapter {
|
||||
|
||||
public static class Serializing extends JsonSerializer<ProfileKeyCommitment> {
|
||||
@Override
|
||||
public void serialize(ProfileKeyCommitment value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||
gen.writeString(Base64.encodeBytes(value.serialize()));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Deserializing extends JsonDeserializer<ProfileKeyCommitment> {
|
||||
|
||||
@Override
|
||||
public ProfileKeyCommitment deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
|
||||
try {
|
||||
return new ProfileKeyCommitment(Base64.decode(p.getValueAsString()));
|
||||
} catch (InvalidInputException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import org.signal.zkgroup.InvalidInputException;
|
||||
import org.signal.zkgroup.profiles.ProfileKeyCredentialResponse;
|
||||
import org.whispersystems.textsecuregcm.util.Base64;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ProfileKeyCredentialResponseAdapter {
|
||||
|
||||
public static class Serializing extends JsonSerializer<ProfileKeyCredentialResponse> {
|
||||
@Override
|
||||
public void serialize(ProfileKeyCredentialResponse response, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
|
||||
throws IOException, JsonProcessingException
|
||||
{
|
||||
if (response == null) jsonGenerator.writeNull();
|
||||
else jsonGenerator.writeString(Base64.encodeBytes(response.serialize()));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Deserializing extends JsonDeserializer<ProfileKeyCredentialResponse> {
|
||||
@Override
|
||||
public ProfileKeyCredentialResponse deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
|
||||
throws IOException, JsonProcessingException
|
||||
{
|
||||
try {
|
||||
return new ProfileKeyCredentialResponse(Base64.decode(jsonParser.getValueAsString()));
|
||||
} catch (InvalidInputException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user