mirror of
https://github.com/signalapp/Signal-Server
synced 2026-08-19 18:47:46 +01:00
Add Profiles OpenAPI annotations
This commit is contained in:
committed by
Jon Chambers
parent
b7d455ed11
commit
136cddf6e2
+58
-7
@@ -11,6 +11,10 @@ import com.google.common.base.Preconditions;
|
||||
import io.dropwizard.auth.Auth;
|
||||
import io.micrometer.core.instrument.Metrics;
|
||||
import io.micrometer.core.instrument.Tags;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
@@ -72,7 +76,6 @@ import org.whispersystems.textsecuregcm.entities.BaseProfileResponse;
|
||||
import org.whispersystems.textsecuregcm.entities.BatchIdentityCheckRequest;
|
||||
import org.whispersystems.textsecuregcm.entities.BatchIdentityCheckResponse;
|
||||
import org.whispersystems.textsecuregcm.entities.CreateProfileRequest;
|
||||
import org.whispersystems.textsecuregcm.entities.CredentialProfileResponse;
|
||||
import org.whispersystems.textsecuregcm.entities.ExpiringProfileKeyCredentialProfileResponse;
|
||||
import org.whispersystems.textsecuregcm.entities.ProfileAvatarUploadAttributes;
|
||||
import org.whispersystems.textsecuregcm.entities.VersionedProfileResponse;
|
||||
@@ -151,6 +154,18 @@ public class ProfileController {
|
||||
@PUT
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Operation(
|
||||
summary = "Update profile",
|
||||
description = "Updates an account’s profile. Must be authenticated.")
|
||||
@ApiResponse(responseCode = "200", description = "The profile was updated successfully.",
|
||||
content = @Content(schema = @Schema(
|
||||
implementation = ProfileAvatarUploadAttributes.class,
|
||||
description = "If the request changed the avatar, the response body contains an upload form.")))
|
||||
@ApiResponse(responseCode = "400", description = "Invalid create profile request.")
|
||||
@ApiResponse(responseCode = "401", description = "Account authentication check failed.")
|
||||
@ApiResponse(responseCode = "403", description = "The request contained a payment address, but payments are not supported in the region of the account’s phone number.")
|
||||
@ApiResponse(responseCode = "412", description = "The requesting account has the profiles_v2 capability")
|
||||
@ApiResponse(responseCode = "422", description = "Invalid request format")
|
||||
public Response setProfile(@Auth AuthenticatedDevice auth, @NotNull @Valid CreateProfileRequest request) {
|
||||
|
||||
final Account account = accountsManager.getByAccountIdentifier(auth.accountIdentifier())
|
||||
@@ -214,8 +229,16 @@ public class ProfileController {
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/{identifier}/{version}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Operation(
|
||||
summary = "Get versioned profile",
|
||||
description = "Retrieves a specific version of an account's profile. Requires either authentication or an unidentified access key.")
|
||||
@ApiResponse(responseCode = "200", description = "Profile retrieved successfully.", useReturnTypeSchema = true)
|
||||
@ApiResponse(responseCode = "400", description = "Malformed identifier")
|
||||
@ApiResponse(responseCode = "401", description = "Not authorized to access this profile.")
|
||||
@ApiResponse(responseCode = "404", description = "Profile or account not found.")
|
||||
@ApiResponse(responseCode = "429", description = "Rate limit exceeded.")
|
||||
@ManagedAsync
|
||||
public VersionedProfileResponse getProfile(
|
||||
@Auth Optional<AuthenticatedDevice> maybeAuthenticatedDevice,
|
||||
@@ -241,9 +264,21 @@ public class ProfileController {
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/{identifier}/{version}/{credentialRequest}")
|
||||
public CredentialProfileResponse getProfile(
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Operation(
|
||||
summary = "Get profile with credential",
|
||||
description = "Retrieves a specific version of an account's profile along with an expiring profile key credential. Requires either authentication or an unidentified access key."
|
||||
)
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "Account found. Profile information will be limited and credential will be null if the version was not found",
|
||||
useReturnTypeSchema = true)
|
||||
@ApiResponse(responseCode = "400", description = "Invalid credential type or credential request.")
|
||||
@ApiResponse(responseCode = "401", description = "Not authorized to access this profile.")
|
||||
@ApiResponse(responseCode = "404", description = "Profile or account not found.")
|
||||
@ApiResponse(responseCode = "429", description = "Rate limit exceeded.")
|
||||
public ExpiringProfileKeyCredentialProfileResponse getProfile(
|
||||
@Auth Optional<AuthenticatedDevice> maybeAuthenticatedDevice,
|
||||
@HeaderParam(HeaderUtils.UNIDENTIFIED_ACCESS_KEY) Optional<Anonymous> accessKey,
|
||||
@Context ContainerRequestContext containerRequestContext,
|
||||
@@ -276,8 +311,16 @@ public class ProfileController {
|
||||
// Although clients should generally be using versioned profiles wherever possible, there are still a few lingering
|
||||
// use cases for getting profiles without a version (e.g. getting a contact's unidentified access key checksum).
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/{identifier}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Operation(
|
||||
summary = "Get unversioned profile",
|
||||
description = "Retrieves basic profile information without a specific version. Supports ACI and PNI identifiers. Requires authentication, an unidentified access key, or a group send token.")
|
||||
@ApiResponse(responseCode = "200", description = "Unversioned profile retrieved successfully.", useReturnTypeSchema = true)
|
||||
@ApiResponse(responseCode = "400", description = "Invalid request (e.g., multiple authorization types provided).")
|
||||
@ApiResponse(responseCode = "401", description = "Not authorized to access this profile.")
|
||||
@ApiResponse(responseCode = "404", description = "Account not found.")
|
||||
@ApiResponse(responseCode = "429", description = "Rate limit exceeded.")
|
||||
@ManagedAsync
|
||||
public BaseProfileResponse getUnversionedProfile(
|
||||
@Auth Optional<AuthenticatedDevice> maybeAuthenticatedDevice,
|
||||
@@ -318,9 +361,17 @@ public class ProfileController {
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/identity_check/batch")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/identity_check/batch")
|
||||
@Operation(
|
||||
summary = "Batch identity key check",
|
||||
description = "Checks identity key fingerprints for multiple accounts. Returns accounts where the fingerprint does not match. Should not be authenticated.")
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "Batch check completed successfully. Response may contain accounts with mismatched fingerprints.",
|
||||
content = @Content(schema = @Schema(implementation = BatchIdentityCheckResponse.class)))
|
||||
@ApiResponse(responseCode = "400", description = "Invalid request format or validation failed.")
|
||||
public CompletableFuture<BatchIdentityCheckResponse> runBatchIdentityCheck(@NotNull @Valid BatchIdentityCheckRequest request) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
List<BatchIdentityCheckResponse.Element> responseElements = Collections.synchronizedList(new ArrayList<>());
|
||||
@@ -410,7 +461,7 @@ public class ProfileController {
|
||||
final Optional<VersionedProfile> maybeProfile = profilesManager.get(account.getUuid(), version);
|
||||
|
||||
if (maybeProfile.isEmpty()) {
|
||||
// Hypothesis: this should basically never happen since clients can't delete versions
|
||||
// this can happen if an account re-registers, which includes some device-transfer scenarios
|
||||
Metrics.counter(
|
||||
VERSION_NOT_FOUND_COUNTER_NAME,
|
||||
Tags.of(
|
||||
|
||||
+8
@@ -8,6 +8,7 @@ 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 io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.signal.libsignal.protocol.IdentityKey;
|
||||
import org.whispersystems.textsecuregcm.identity.ServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.util.ByteArrayBase64WithPaddingAdapter;
|
||||
@@ -17,27 +18,34 @@ import org.whispersystems.textsecuregcm.util.IdentityKeyAdapter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Schema(description = "Unversioned profile containing basic information")
|
||||
public class BaseProfileResponse {
|
||||
|
||||
@Schema(description = "The account's public identity key (unpadded base64)")
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = IdentityKeyAdapter.Serializer.class)
|
||||
@JsonDeserialize(using = IdentityKeyAdapter.Deserializer.class)
|
||||
private IdentityKey identityKey;
|
||||
|
||||
@Schema(description = "Checksum for unidentified access authentication (padded base64)")
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||
private byte[] unidentifiedAccess;
|
||||
|
||||
@Schema(description = "Whether unidentified access is unrestricted for this account")
|
||||
@JsonProperty
|
||||
private boolean unrestrictedUnidentifiedAccess;
|
||||
|
||||
@Schema(description = "Device capabilities and whether they are enabled")
|
||||
@JsonProperty
|
||||
private Map<String, Boolean> capabilities;
|
||||
|
||||
@Schema(description = "List of badges displayed on the profile")
|
||||
@JsonProperty
|
||||
private List<Badge> badges;
|
||||
|
||||
@Schema(description = "Service identifier (ACI or PNI)")
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = ServiceIdentifierAdapter.ServiceIdentifierSerializer.class)
|
||||
@JsonDeserialize(using = ServiceIdentifierAdapter.ServiceIdentifierDeserializer.class)
|
||||
|
||||
+18
-11
@@ -7,29 +7,36 @@ package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import java.util.List;
|
||||
import org.whispersystems.textsecuregcm.identity.ServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.util.ExactlySize;
|
||||
import org.whispersystems.textsecuregcm.util.ServiceIdentifierAdapter;
|
||||
|
||||
public record BatchIdentityCheckRequest(@Valid @NotNull @Size(max = 1000) List<Element> elements) {
|
||||
@Schema(description = "Request to check identity key fingerprints for multiple accounts")
|
||||
public record BatchIdentityCheckRequest(
|
||||
@Schema(description = "List of accounts to check")
|
||||
@Valid @NotNull @Size(max = 1000) List<Element> elements) {
|
||||
|
||||
/**
|
||||
* @param uuid account id or phone number id
|
||||
* @param fingerprint most significant 4 bytes of SHA-256 of the 33-byte identity key field (32-byte curve25519 public
|
||||
* key prefixed with 0x05)
|
||||
*/
|
||||
public record Element(@NotNull
|
||||
@JsonSerialize(using = ServiceIdentifierAdapter.ServiceIdentifierSerializer.class)
|
||||
@JsonDeserialize(using = ServiceIdentifierAdapter.ServiceIdentifierDeserializer.class)
|
||||
ServiceIdentifier uuid,
|
||||
@Schema(description = "A service identifier and expected identity key fingerprint")
|
||||
public record Element(
|
||||
@Schema(description = "Identifier (ACI or PNI)")
|
||||
@NotNull
|
||||
@JsonSerialize(using = ServiceIdentifierAdapter.ServiceIdentifierSerializer.class)
|
||||
@JsonDeserialize(using = ServiceIdentifierAdapter.ServiceIdentifierDeserializer.class)
|
||||
ServiceIdentifier uuid,
|
||||
|
||||
@NotNull
|
||||
@ExactlySize(4)
|
||||
byte[] fingerprint) {
|
||||
}
|
||||
@Schema(description = "Expected identity key fingerprint (4 bytes, most significant bytes of SHA-256 hash of 33-byte identity key field)")
|
||||
@NotNull
|
||||
@ExactlySize(4)
|
||||
byte[] fingerprint) {
|
||||
}
|
||||
}
|
||||
|
||||
+18
-10
@@ -8,6 +8,7 @@ package org.whispersystems.textsecuregcm.entities;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.util.List;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
@@ -16,17 +17,24 @@ import org.whispersystems.textsecuregcm.identity.ServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.util.IdentityKeyAdapter;
|
||||
import org.whispersystems.textsecuregcm.util.ServiceIdentifierAdapter;
|
||||
|
||||
public record BatchIdentityCheckResponse(@Valid List<Element> elements) {
|
||||
@Schema(description = "Response containing accounts with mismatched identity key fingerprints")
|
||||
public record BatchIdentityCheckResponse(
|
||||
@Schema(description = "List of accounts where fingerprint did not match (empty if all matched)")
|
||||
@Valid List<Element> elements) {
|
||||
|
||||
public record Element(@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
@JsonSerialize(using = ServiceIdentifierAdapter.ServiceIdentifierSerializer.class)
|
||||
@JsonDeserialize(using = ServiceIdentifierAdapter.ServiceIdentifierDeserializer.class)
|
||||
@NotNull
|
||||
ServiceIdentifier uuid,
|
||||
@Schema(description = "An account with a mismatched identity key fingerprint")
|
||||
public record Element(
|
||||
@Schema(description = "Service identifier (ACI or PNI)")
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
@JsonSerialize(using = ServiceIdentifierAdapter.ServiceIdentifierSerializer.class)
|
||||
@JsonDeserialize(using = ServiceIdentifierAdapter.ServiceIdentifierDeserializer.class)
|
||||
@NotNull
|
||||
ServiceIdentifier uuid,
|
||||
|
||||
@NotNull
|
||||
@JsonSerialize(using = IdentityKeyAdapter.Serializer.class)
|
||||
@JsonDeserialize(using = IdentityKeyAdapter.Deserializer.class)
|
||||
IdentityKey identityKey) {
|
||||
@Schema(description = "The actual identity key for this account")
|
||||
@NotNull
|
||||
@JsonSerialize(using = IdentityKeyAdapter.Serializer.class)
|
||||
@JsonDeserialize(using = IdentityKeyAdapter.Deserializer.class)
|
||||
IdentityKey identityKey) {
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -8,6 +8,7 @@ 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 io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
@@ -17,52 +18,63 @@ import org.whispersystems.textsecuregcm.util.ByteArrayBase64WithPaddingAdapter;
|
||||
import org.whispersystems.textsecuregcm.util.ExactlySize;
|
||||
import org.whispersystems.textsecuregcm.util.ValidHexString;
|
||||
|
||||
@Schema(description = "Request to create or update a versioned profile")
|
||||
public record CreateProfileRequest(
|
||||
@Schema(description = "Profile key commitment")
|
||||
@JsonProperty
|
||||
@NotNull
|
||||
@JsonDeserialize(using = ProfileKeyCommitmentAdapter.Deserializing.class)
|
||||
@JsonSerialize(using = ProfileKeyCommitmentAdapter.Serializing.class)
|
||||
ProfileKeyCommitment commitment,
|
||||
|
||||
@Schema(description = "Profile version identifier (hex-encoding of the public key)")
|
||||
@JsonProperty
|
||||
@NotEmpty
|
||||
@ValidHexString
|
||||
@ExactlySize({64})
|
||||
String version,
|
||||
|
||||
@Schema(description = "Encrypted profile name. Padded base64.")
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||
@ExactlySize({81, 285})
|
||||
byte[] name,
|
||||
|
||||
@Schema(description = "Encrypted about emoji. Padded base64.")
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||
@ExactlySize({0, 60})
|
||||
byte[] aboutEmoji,
|
||||
|
||||
@Schema(description = "Encrypted about text. Padded base64.")
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||
@ExactlySize({0, 156, 282, 540})
|
||||
byte[] about,
|
||||
|
||||
@Schema(description = "Encrypted payment address. Padded base64.")
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||
@ExactlySize({0, 582})
|
||||
byte[] paymentAddress,
|
||||
|
||||
@Schema(description = "Whether the profile has an avatar")
|
||||
@JsonProperty("avatar")
|
||||
boolean hasAvatar,
|
||||
|
||||
@Schema(description = "Whether the avatar is unchanged from the previous version")
|
||||
@JsonProperty
|
||||
boolean sameAvatar,
|
||||
|
||||
@Schema(description = "List of badge IDs to display on the profile")
|
||||
@JsonProperty("badgeIds")
|
||||
Optional<List<String>> badges,
|
||||
|
||||
@Schema(description = "Encrypted phone number sharing preference. Padded base64.")
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2021 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonUnwrapped;
|
||||
|
||||
public abstract class CredentialProfileResponse {
|
||||
|
||||
@JsonUnwrapped
|
||||
private VersionedProfileResponse versionedProfileResponse;
|
||||
|
||||
protected CredentialProfileResponse() {
|
||||
}
|
||||
|
||||
protected CredentialProfileResponse(final VersionedProfileResponse versionedProfileResponse) {
|
||||
this.versionedProfileResponse = versionedProfileResponse;
|
||||
}
|
||||
|
||||
public VersionedProfileResponse getVersionedProfileResponse() {
|
||||
return versionedProfileResponse;
|
||||
}
|
||||
}
|
||||
+13
-2
@@ -6,13 +6,20 @@
|
||||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonUnwrapped;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import javax.annotation.Nullable;
|
||||
import org.signal.libsignal.zkgroup.profiles.ExpiringProfileKeyCredentialResponse;
|
||||
|
||||
public class ExpiringProfileKeyCredentialProfileResponse extends CredentialProfileResponse {
|
||||
@Schema(description = "Profile response with an expiring profile key credential")
|
||||
public class ExpiringProfileKeyCredentialProfileResponse {
|
||||
|
||||
@JsonUnwrapped
|
||||
private VersionedProfileResponse versionedProfileResponse;
|
||||
|
||||
@Schema(description = "Expiring profile key credential response. Null if profile version was not found")
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = ExpiringProfileKeyCredentialResponseAdapter.Serializing.class)
|
||||
@JsonDeserialize(using = ExpiringProfileKeyCredentialResponseAdapter.Deserializing.class)
|
||||
@@ -25,7 +32,7 @@ public class ExpiringProfileKeyCredentialProfileResponse extends CredentialProfi
|
||||
public ExpiringProfileKeyCredentialProfileResponse(final VersionedProfileResponse versionedProfileResponse,
|
||||
@Nullable final ExpiringProfileKeyCredentialResponse credential) {
|
||||
|
||||
super(versionedProfileResponse);
|
||||
this.versionedProfileResponse = versionedProfileResponse;
|
||||
this.credential = credential;
|
||||
}
|
||||
|
||||
@@ -33,4 +40,8 @@ public class ExpiringProfileKeyCredentialProfileResponse extends CredentialProfi
|
||||
public ExpiringProfileKeyCredentialResponse getCredential() {
|
||||
return credential;
|
||||
}
|
||||
|
||||
public VersionedProfileResponse getVersionedProfileResponse() {
|
||||
return versionedProfileResponse;
|
||||
}
|
||||
}
|
||||
|
||||
+18
-11
@@ -6,44 +6,51 @@
|
||||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "Profile avatar upload form (S3 Post Policy, AWS Signature version 4)")
|
||||
public class ProfileAvatarUploadAttributes {
|
||||
|
||||
@Schema(description = "Object key for the avatar")
|
||||
@JsonProperty
|
||||
private String key;
|
||||
|
||||
@Schema(description = "Credential for the upload")
|
||||
@JsonProperty
|
||||
private String credential;
|
||||
|
||||
@Schema(description = "Access control list setting")
|
||||
@JsonProperty
|
||||
private String acl;
|
||||
|
||||
@Schema(description = "Signing algorithm")
|
||||
@JsonProperty
|
||||
private String algorithm;
|
||||
|
||||
@Schema(description = "Date in AWS format")
|
||||
@JsonProperty
|
||||
private String date;
|
||||
|
||||
@Schema(description = "Base64-encoded upload policy")
|
||||
@JsonProperty
|
||||
private String policy;
|
||||
|
||||
@Schema(description = "Signature calculated over the policy")
|
||||
@JsonProperty
|
||||
private String signature;
|
||||
|
||||
public ProfileAvatarUploadAttributes() {}
|
||||
|
||||
public ProfileAvatarUploadAttributes(String key, String credential,
|
||||
String acl, String algorithm,
|
||||
String date, String policy,
|
||||
String signature)
|
||||
{
|
||||
this.key = key;
|
||||
public ProfileAvatarUploadAttributes(String key, String credential, String acl, String algorithm, String date,
|
||||
String policy, String signature) {
|
||||
|
||||
this.key = key;
|
||||
this.credential = credential;
|
||||
this.acl = acl;
|
||||
this.algorithm = algorithm;
|
||||
this.date = date;
|
||||
this.policy = policy;
|
||||
this.signature = signature;
|
||||
this.acl = acl;
|
||||
this.algorithm = algorithm;
|
||||
this.date = date;
|
||||
this.policy = policy;
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
|
||||
+9
@@ -9,36 +9,45 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonUnwrapped;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import org.whispersystems.textsecuregcm.util.ByteArrayBase64WithPaddingAdapter;
|
||||
|
||||
@Schema(description = "Versioned profile containing encrypted fields. Versioned fields may be empty if the version was not found.")
|
||||
public record VersionedProfileResponse(
|
||||
|
||||
@Schema(description = "Base profile information")
|
||||
@JsonUnwrapped
|
||||
BaseProfileResponse baseProfileResponse,
|
||||
|
||||
@Schema(description = "Encrypted profile name. Padded base64.")
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||
byte[] name,
|
||||
|
||||
@Schema(description = "Encrypted about text. Padded base64.")
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||
byte[] about,
|
||||
|
||||
@Schema(description = "Encrypted about emoji. Padded base64.")
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||
byte[] aboutEmoji,
|
||||
|
||||
@Schema(description = "Avatar CDN path")
|
||||
@JsonProperty
|
||||
String avatar,
|
||||
|
||||
@Schema(description = "Encrypted payment address. Padded base64.")
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||
byte[] paymentAddress,
|
||||
|
||||
@Schema(description = "Encrypted phone number sharing preference. Padded base64.")
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||
|
||||
Reference in New Issue
Block a user