mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-21 00:28:02 +01:00
First pass at subscriptions API
This is an incomplete first pass at building the subscriptions API. More API endpoints are still to be added along with controller tests.
This commit is contained in:
@@ -15,7 +15,6 @@ import javax.validation.constraints.NotNull;
|
||||
public class DonationConfiguration {
|
||||
|
||||
private String uri;
|
||||
private String apiKey;
|
||||
private String description;
|
||||
private Set<String> supportedCurrencies;
|
||||
private CircuitBreakerConfiguration circuitBreaker = new CircuitBreakerConfiguration();
|
||||
@@ -32,17 +31,6 @@ public class DonationConfiguration {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
@JsonProperty
|
||||
@NotEmpty
|
||||
public String getApiKey() {
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setApiKey(final String apiKey) {
|
||||
this.apiKey = apiKey;
|
||||
}
|
||||
|
||||
@JsonProperty
|
||||
public String getDescription() {
|
||||
return description;
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2021 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.configuration;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.time.Duration;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
public class DynamoDbClientConfiguration {
|
||||
|
||||
private final String region;
|
||||
private final Duration clientExecutionTimeout;
|
||||
private final Duration clientRequestTimeout;
|
||||
|
||||
@JsonCreator
|
||||
public DynamoDbClientConfiguration(
|
||||
@JsonProperty("region") final String region,
|
||||
@JsonProperty("clientExcecutionTimeout") final Duration clientExecutionTimeout,
|
||||
@JsonProperty("clientRequestTimeout") final Duration clientRequestTimeout) {
|
||||
this.region = region;
|
||||
this.clientExecutionTimeout = clientExecutionTimeout != null ? clientExecutionTimeout : Duration.ofSeconds(30);
|
||||
this.clientRequestTimeout = clientRequestTimeout != null ? clientRequestTimeout : Duration.ofSeconds(10);
|
||||
}
|
||||
|
||||
@NotEmpty
|
||||
public String getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
public Duration getClientExecutionTimeout() {
|
||||
return clientExecutionTimeout;
|
||||
}
|
||||
|
||||
public Duration getClientRequestTimeout() {
|
||||
return clientRequestTimeout;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2021 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.configuration;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.time.Duration;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
public class DynamoDbTables {
|
||||
|
||||
public static class Table {
|
||||
private final String tableName;
|
||||
|
||||
@JsonCreator
|
||||
public Table(
|
||||
@JsonProperty("tableName") final String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
@NotEmpty
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TableWithExpiration extends Table {
|
||||
private final Duration expiration;
|
||||
|
||||
@JsonCreator
|
||||
public TableWithExpiration(
|
||||
@JsonProperty("tableName") final String tableName,
|
||||
@JsonProperty("expiration") final Duration expiration) {
|
||||
super(tableName);
|
||||
this.expiration = expiration;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Duration getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
}
|
||||
|
||||
private final IssuedReceiptsTableConfiguration issuedReceipts;
|
||||
private final TableWithExpiration redeemedReceipts;
|
||||
private final Table subscriptions;
|
||||
|
||||
@JsonCreator
|
||||
public DynamoDbTables(
|
||||
@JsonProperty("issuedReceipts") final IssuedReceiptsTableConfiguration issuedReceipts,
|
||||
@JsonProperty("redeemedReceipts") final TableWithExpiration redeemedReceipts,
|
||||
@JsonProperty("subscriptions") final Table subscriptions) {
|
||||
this.issuedReceipts = issuedReceipts;
|
||||
this.redeemedReceipts = redeemedReceipts;
|
||||
this.subscriptions = subscriptions;
|
||||
}
|
||||
|
||||
@Valid
|
||||
@NotNull
|
||||
public IssuedReceiptsTableConfiguration getIssuedReceipts() {
|
||||
return issuedReceipts;
|
||||
}
|
||||
|
||||
@Valid
|
||||
@NotNull
|
||||
public TableWithExpiration getRedeemedReceipts() {
|
||||
return redeemedReceipts;
|
||||
}
|
||||
|
||||
@Valid
|
||||
@NotNull
|
||||
public Table getSubscriptions() {
|
||||
return subscriptions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2021 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.configuration;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.time.Duration;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
public class IssuedReceiptsTableConfiguration extends DynamoDbTables.TableWithExpiration {
|
||||
|
||||
private final byte[] generator;
|
||||
|
||||
public IssuedReceiptsTableConfiguration(
|
||||
@JsonProperty("tableName") final String tableName,
|
||||
@JsonProperty("expiration") final Duration expiration,
|
||||
@JsonProperty("generator") final byte[] generator) {
|
||||
super(tableName, expiration);
|
||||
this.generator = generator;
|
||||
}
|
||||
|
||||
@NotEmpty
|
||||
public byte[] getGenerator() {
|
||||
return generator;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.configuration;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.time.Duration;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
public class RedeemedReceiptsDynamoDbConfiguration extends DynamoDbConfiguration {
|
||||
|
||||
private Duration expirationTime;
|
||||
|
||||
@NotNull
|
||||
@JsonProperty
|
||||
public Duration getExpirationTime() {
|
||||
return expirationTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2021 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.configuration;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
public class StripeConfiguration {
|
||||
|
||||
private final String apiKey;
|
||||
private final byte[] idempotencyKeyGenerator;
|
||||
|
||||
@JsonCreator
|
||||
public StripeConfiguration(
|
||||
@JsonProperty("apiKey") final String apiKey,
|
||||
@JsonProperty("idempotencyKeyGenerator") final byte[] idempotencyKeyGenerator) {
|
||||
this.apiKey = apiKey;
|
||||
this.idempotencyKeyGenerator = idempotencyKeyGenerator;
|
||||
}
|
||||
|
||||
@NotEmpty
|
||||
public String getApiKey() {
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
@NotEmpty
|
||||
public byte[] getIdempotencyKeyGenerator() {
|
||||
return idempotencyKeyGenerator;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2021 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.configuration;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.dropwizard.validation.ValidationMethod;
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
public class SubscriptionConfiguration {
|
||||
|
||||
private final Duration badgeGracePeriod;
|
||||
private final Map<Long, SubscriptionLevelConfiguration> levels;
|
||||
|
||||
@JsonCreator
|
||||
public SubscriptionConfiguration(
|
||||
@JsonProperty("badgeGracePeriod") @Valid Duration badgeGracePeriod,
|
||||
@JsonProperty("levels") @Valid Map<@NotNull @Min(1) Long, @NotNull @Valid SubscriptionLevelConfiguration> levels) {
|
||||
this.badgeGracePeriod = badgeGracePeriod;
|
||||
this.levels = levels;
|
||||
}
|
||||
|
||||
public Duration getBadgeGracePeriod() {
|
||||
return badgeGracePeriod;
|
||||
}
|
||||
|
||||
public Map<Long, SubscriptionLevelConfiguration> getLevels() {
|
||||
return levels;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
@ValidationMethod(message = "has a mismatch between the levels supported currencies")
|
||||
public boolean isCurrencyListSameAcrossAllLevels() {
|
||||
Optional<SubscriptionLevelConfiguration> any = levels.values().stream().findAny();
|
||||
if (any.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Set<String> currencies = any.get().getPrices().keySet();
|
||||
return levels.values().stream().allMatch(level -> currencies.equals(level.getPrices().keySet()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2021 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.configuration;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.util.Map;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
public class SubscriptionLevelConfiguration {
|
||||
|
||||
private final String badge;
|
||||
private final String product;
|
||||
private final Map<String, SubscriptionPriceConfiguration> prices;
|
||||
|
||||
@JsonCreator
|
||||
public SubscriptionLevelConfiguration(
|
||||
@JsonProperty("badge") @NotEmpty String badge,
|
||||
@JsonProperty("product") @NotEmpty String product,
|
||||
@JsonProperty("prices") @Valid Map<@NotEmpty String, @NotNull @Valid SubscriptionPriceConfiguration> prices) {
|
||||
this.badge = badge;
|
||||
this.product = product;
|
||||
this.prices = prices;
|
||||
}
|
||||
|
||||
public String getBadge() {
|
||||
return badge;
|
||||
}
|
||||
|
||||
public String getProduct() {
|
||||
return product;
|
||||
}
|
||||
|
||||
public Map<String, SubscriptionPriceConfiguration> getPrices() {
|
||||
return prices;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2021 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.configuration;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.math.BigDecimal;
|
||||
import javax.validation.constraints.DecimalMin;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
public class SubscriptionPriceConfiguration {
|
||||
|
||||
private final String id;
|
||||
private final BigDecimal amount;
|
||||
|
||||
@JsonCreator
|
||||
public SubscriptionPriceConfiguration(
|
||||
@JsonProperty("id") @NotEmpty String id,
|
||||
@JsonProperty("amount") @NotNull @DecimalMin("0.01") BigDecimal amount) {
|
||||
this.id = id;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user