kopia lustrzana https://github.com/ryukoposting/Signal-Android
After review, everything looks good. Update MobileCoin Payments Beta country codes.
This reverts commit 0cb53f40f4
.
fork-5.53.8
rodzic
aa872d29bc
commit
270ab34c6a
|
@ -171,7 +171,7 @@ android {
|
||||||
buildConfigField "String[]", "LANGUAGES", "new String[]{\"" + autoResConfig().collect { s -> s.replace('-r', '_') }.join('", "') + '"}'
|
buildConfigField "String[]", "LANGUAGES", "new String[]{\"" + autoResConfig().collect { s -> s.replace('-r', '_') }.join('", "') + '"}'
|
||||||
buildConfigField "int", "CANONICAL_VERSION_CODE", "$canonicalVersionCode"
|
buildConfigField "int", "CANONICAL_VERSION_CODE", "$canonicalVersionCode"
|
||||||
buildConfigField "String", "DEFAULT_CURRENCIES", "\"EUR,AUD,GBP,CAD,CNY\""
|
buildConfigField "String", "DEFAULT_CURRENCIES", "\"EUR,AUD,GBP,CAD,CNY\""
|
||||||
buildConfigField "int[]", "MOBILE_COIN_REGIONS", "new int[]{44,49,33,41}"
|
buildConfigField "int[]", "MOBILE_COIN_BLACKLIST", "new int[]{98,963,53,850,7}"
|
||||||
buildConfigField "String", "GIPHY_API_KEY", "\"3o6ZsYH6U6Eri53TXy\""
|
buildConfigField "String", "GIPHY_API_KEY", "\"3o6ZsYH6U6Eri53TXy\""
|
||||||
buildConfigField "String", "RECAPTCHA_PROOF_URL", "\"https://signalcaptchas.org/challenge/generate.html\""
|
buildConfigField "String", "RECAPTCHA_PROOF_URL", "\"https://signalcaptchas.org/challenge/generate.html\""
|
||||||
|
|
||||||
|
|
|
@ -108,15 +108,15 @@ public final class PaymentsValues extends SignalStoreValues {
|
||||||
public PaymentsAvailability getPaymentsAvailability() {
|
public PaymentsAvailability getPaymentsAvailability() {
|
||||||
Context context = ApplicationDependencies.getApplication();
|
Context context = ApplicationDependencies.getApplication();
|
||||||
|
|
||||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
if (!TextSecurePreferences.isPushRegistered(context) ||
|
||||||
|
!GeographicalRestrictions.e164Allowed(TextSecurePreferences.getLocalNumber(context)))
|
||||||
|
{
|
||||||
return PaymentsAvailability.NOT_IN_REGION;
|
return PaymentsAvailability.NOT_IN_REGION;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FeatureFlags.payments()) {
|
if (FeatureFlags.payments()) {
|
||||||
if (mobileCoinPaymentsEnabled()) {
|
if (mobileCoinPaymentsEnabled()) {
|
||||||
return PaymentsAvailability.WITHDRAW_AND_SEND;
|
return PaymentsAvailability.WITHDRAW_AND_SEND;
|
||||||
} else if (!GeographicalRestrictions.e164Allowed(TextSecurePreferences.getLocalNumber(context))) {
|
|
||||||
return PaymentsAvailability.NOT_IN_REGION;
|
|
||||||
} else {
|
} else {
|
||||||
return PaymentsAvailability.REGISTRATION_AVAILABLE;
|
return PaymentsAvailability.REGISTRATION_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,185 +1,49 @@
|
||||||
package org.thoughtcrime.securesms.payments;
|
package org.thoughtcrime.securesms.payments;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
|
|
||||||
import com.google.i18n.phonenumbers.NumberParseException;
|
import com.google.i18n.phonenumbers.NumberParseException;
|
||||||
import com.google.i18n.phonenumbers.PhoneNumberUtil;
|
import com.google.i18n.phonenumbers.PhoneNumberUtil;
|
||||||
import com.google.i18n.phonenumbers.Phonenumber;
|
|
||||||
|
|
||||||
import org.signal.core.util.MapUtil;
|
|
||||||
import org.signal.core.util.logging.Log;
|
import org.signal.core.util.logging.Log;
|
||||||
import org.thoughtcrime.securesms.BuildConfig;
|
import org.thoughtcrime.securesms.BuildConfig;
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import io.reactivex.rxjava3.annotations.NonNull;
|
|
||||||
|
|
||||||
public final class GeographicalRestrictions {
|
public final class GeographicalRestrictions {
|
||||||
|
|
||||||
private static final String TAG = Log.tag(GeographicalRestrictions.class);
|
private static final String TAG = Log.tag(GeographicalRestrictions.class);
|
||||||
|
|
||||||
private static final Validator BUILD_CONFIG_VALIDATOR = new BuildConfigWhitelistValidator();
|
private GeographicalRestrictions() {}
|
||||||
|
|
||||||
private GeographicalRestrictions() {
|
private static final Set<Integer> BLACKLIST;
|
||||||
|
|
||||||
|
static {
|
||||||
|
Set<Integer> set = new HashSet<>(BuildConfig.MOBILE_COIN_BLACKLIST.length);
|
||||||
|
|
||||||
|
for (int i = 0; i < BuildConfig.MOBILE_COIN_BLACKLIST.length; i++) {
|
||||||
|
set.add(BuildConfig.MOBILE_COIN_BLACKLIST[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
BLACKLIST = Collections.unmodifiableSet(set);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean regionAllowed(int regionCode) {
|
||||||
|
return !BLACKLIST.contains(regionCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean e164Allowed(@Nullable String e164) {
|
public static boolean e164Allowed(@Nullable String e164) {
|
||||||
return selectValidator(FeatureFlags.mobileCoinBlacklist()).e164Allowed(e164);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
static boolean e164Allowed(@Nullable String e164, @Nullable String featureFlagBlacklist) {
|
|
||||||
return selectValidator(featureFlagBlacklist).e164Allowed(e164);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static @NonNull Validator selectValidator(@Nullable String featureFlagBlacklist) {
|
|
||||||
String[] blacklist = parseBlacklist(featureFlagBlacklist);
|
|
||||||
if (blacklist == null || blacklist.length == 0) {
|
|
||||||
return BUILD_CONFIG_VALIDATOR;
|
|
||||||
} else {
|
|
||||||
return new FeatureFlagBlacklistValidator(blacklist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static @Nullable String[] parseBlacklist(@Nullable String featureFlagBlacklist) {
|
|
||||||
if (Util.isEmpty(featureFlagBlacklist)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] parts = featureFlagBlacklist.split(",");
|
|
||||||
if (parts.length == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parts;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class FeatureFlagBlacklistValidator implements Validator {
|
|
||||||
|
|
||||||
private final Set<Integer> blacklistCountries;
|
|
||||||
private final Map<Integer, Set<Integer>> blacklistRegions;
|
|
||||||
|
|
||||||
private FeatureFlagBlacklistValidator(@NonNull String[] blacklist) {
|
|
||||||
Set<Integer> countries = new HashSet<>(blacklist.length);
|
|
||||||
Map<Integer, Set<Integer>> regions = new HashMap<>();
|
|
||||||
|
|
||||||
for (final String entry : blacklist) {
|
|
||||||
try {
|
|
||||||
String[] parts = entry.trim().split(" ");
|
|
||||||
Integer countryCode = Integer.parseInt(parts[0].trim());
|
|
||||||
|
|
||||||
if (parts.length == 1) {
|
|
||||||
countries.add(countryCode);
|
|
||||||
} else if (parts.length == 2) {
|
|
||||||
Integer regionCode = Integer.parseInt(parts[1].trim());
|
|
||||||
Set<Integer> regionsForCountry = MapUtil.getOrDefault(regions, countryCode, new HashSet<>());
|
|
||||||
|
|
||||||
regionsForCountry.add(regionCode);
|
|
||||||
regions.put(countryCode, regionsForCountry);
|
|
||||||
} else {
|
|
||||||
Log.w(TAG, "Bad entry: " + entry.trim());
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
Log.w(TAG, "Failure parsing part", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final Integer countryCode : regions.keySet()) {
|
|
||||||
Set<Integer> regionCodes = regions.get(countryCode);
|
|
||||||
if (regionCodes != null) {
|
|
||||||
regions.put(countryCode, Collections.unmodifiableSet(regionCodes));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
blacklistCountries = Collections.unmodifiableSet(countries);
|
|
||||||
blacklistRegions = Collections.unmodifiableMap(regions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean e164Allowed(@Nullable String e164) {
|
|
||||||
try {
|
|
||||||
Phonenumber.PhoneNumber phoneNumber = PhoneNumberUtil.getInstance().parse(e164, null);
|
|
||||||
|
|
||||||
int countryCode = phoneNumber.getCountryCode();
|
|
||||||
if (blacklistCountries.contains(countryCode)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blacklistRegions.containsKey(countryCode)) {
|
|
||||||
Set<Integer> regionsInCountry = blacklistRegions.get(countryCode);
|
|
||||||
if (regionsInCountry == null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nationalDestinationCodeLength = PhoneNumberUtil.getInstance().getLengthOfNationalDestinationCode(phoneNumber);
|
|
||||||
if (nationalDestinationCodeLength > 0) {
|
|
||||||
String nationalSignificantNumber = PhoneNumberUtil.getInstance().getNationalSignificantNumber(phoneNumber);
|
|
||||||
int nationalDestinationCode = Integer.parseInt(nationalSignificantNumber.substring(0, nationalDestinationCodeLength));
|
|
||||||
|
|
||||||
if (regionsInCountry.contains(nationalDestinationCode)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int areaCodeLength = PhoneNumberUtil.getInstance().getLengthOfGeographicalAreaCode(phoneNumber);
|
|
||||||
if (areaCodeLength > 0) {
|
|
||||||
String nationalSignificantNumber = PhoneNumberUtil.getInstance().getNationalSignificantNumber(phoneNumber);
|
|
||||||
int areaCode = Integer.parseInt(nationalSignificantNumber.substring(0, areaCodeLength));
|
|
||||||
|
|
||||||
if (regionsInCountry.contains(areaCode)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (NumberParseException e) {
|
|
||||||
Log.w(TAG, e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class BuildConfigWhitelistValidator implements Validator {
|
|
||||||
private static final Set<Integer> REGION_CODE_SET;
|
|
||||||
|
|
||||||
static {
|
|
||||||
Set<Integer> set = new HashSet<>(BuildConfig.MOBILE_COIN_REGIONS.length);
|
|
||||||
|
|
||||||
for (int i = 0; i < BuildConfig.MOBILE_COIN_REGIONS.length; i++) {
|
|
||||||
set.add(BuildConfig.MOBILE_COIN_REGIONS[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
REGION_CODE_SET = Collections.unmodifiableSet(set);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean regionAllowed(int regionCode) {
|
|
||||||
return REGION_CODE_SET.contains(regionCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean e164Allowed(@Nullable String e164) {
|
|
||||||
try {
|
try {
|
||||||
int countryCode = PhoneNumberUtil.getInstance()
|
int countryCode = PhoneNumberUtil.getInstance()
|
||||||
.parse(e164, null)
|
.parse(e164, null)
|
||||||
.getCountryCode();
|
.getCountryCode();
|
||||||
|
|
||||||
return regionAllowed(countryCode);
|
return GeographicalRestrictions.regionAllowed(countryCode);
|
||||||
} catch (NumberParseException e) {
|
} catch (NumberParseException e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private interface Validator {
|
|
||||||
boolean e164Allowed(@Nullable String e164);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.util;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.annotation.WorkerThread;
|
import androidx.annotation.WorkerThread;
|
||||||
|
|
||||||
|
@ -89,7 +88,6 @@ public final class FeatureFlags {
|
||||||
private static final String DONOR_BADGES_MEGAPHONE = "android.donorBadges.megaphone";
|
private static final String DONOR_BADGES_MEGAPHONE = "android.donorBadges.megaphone";
|
||||||
private static final String DONOR_BADGES_DISPLAY = "android.donorBadges.display";
|
private static final String DONOR_BADGES_DISPLAY = "android.donorBadges.display";
|
||||||
private static final String CDSH = "android.cdsh";
|
private static final String CDSH = "android.cdsh";
|
||||||
private static final String MOBILECOIN_BLACKLIST = "android.mobilecoin.blacklist";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We will only store remote values for flags in this set. If you want a flag to be controllable
|
* We will only store remote values for flags in this set. If you want a flag to be controllable
|
||||||
|
@ -130,8 +128,7 @@ public final class FeatureFlags {
|
||||||
SENDER_KEY_MAX_AGE,
|
SENDER_KEY_MAX_AGE,
|
||||||
DONOR_BADGES,
|
DONOR_BADGES,
|
||||||
DONOR_BADGES_MEGAPHONE,
|
DONOR_BADGES_MEGAPHONE,
|
||||||
DONOR_BADGES_DISPLAY,
|
DONOR_BADGES_DISPLAY
|
||||||
MOBILECOIN_BLACKLIST
|
|
||||||
);
|
);
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@ -437,10 +434,6 @@ public final class FeatureFlags {
|
||||||
return Environment.IS_STAGING && getBoolean(CDSH, false);
|
return Environment.IS_STAGING && getBoolean(CDSH, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @Nullable String mobileCoinBlacklist() {
|
|
||||||
return getString(MOBILECOIN_BLACKLIST, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Only for rendering debug info. */
|
/** Only for rendering debug info. */
|
||||||
public static synchronized @NonNull Map<String, Object> getMemoryValues() {
|
public static synchronized @NonNull Map<String, Object> getMemoryValues() {
|
||||||
return new TreeMap<>(REMOTE_VALUES);
|
return new TreeMap<>(REMOTE_VALUES);
|
||||||
|
|
|
@ -13,8 +13,6 @@ import static org.junit.Assume.assumeTrue;
|
||||||
|
|
||||||
public final class GeographicalRestrictionsTest {
|
public final class GeographicalRestrictionsTest {
|
||||||
|
|
||||||
private static final String INVALID_BLACKLIST = "asdfkljsdhfla";
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
Log.initialize(new EmptyLogger());
|
Log.initialize(new EmptyLogger());
|
||||||
|
@ -22,57 +20,28 @@ public final class GeographicalRestrictionsTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void bad_number_not_allowed() {
|
public void bad_number_not_allowed() {
|
||||||
assertFalse(GeographicalRestrictions.e164Allowed("bad_number", null));
|
assertFalse(GeographicalRestrictions.e164Allowed("bad_number"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void null_not_allowed() {
|
public void null_not_allowed() {
|
||||||
assertFalse(GeographicalRestrictions.e164Allowed(null, null));
|
assertFalse(GeographicalRestrictions.e164Allowed(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void uk_allowed() {
|
public void uk_allowed() {
|
||||||
assertTrue(GeographicalRestrictions.e164Allowed("+441617151234", null));
|
assertTrue(GeographicalRestrictions.e164Allowed("+441617151234"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void us_not_allowed_in_release() {
|
public void crimea_not_allowed() {
|
||||||
assumeFalse(BuildConfig.DEBUG);
|
assertFalse(GeographicalRestrictions.e164Allowed("+79782222222"));
|
||||||
assertFalse(GeographicalRestrictions.e164Allowed("+15407011234", null));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenAnInvalidBlackList_whenIE164AllowedAUkNumber_thenIExpectTrue() {
|
public void blacklist_not_allowed() {
|
||||||
assertTrue(GeographicalRestrictions.e164Allowed("+441617151234", INVALID_BLACKLIST));
|
for (int code : BuildConfig.MOBILE_COIN_BLACKLIST) {
|
||||||
}
|
assertFalse(GeographicalRestrictions.regionAllowed(code));
|
||||||
|
}
|
||||||
@Test
|
|
||||||
public void givenAValidBlacklistWithRegionBlock_whenIE164AllowedANumberInThatRegion_thenIExpectFalse() {
|
|
||||||
assertFalse(GeographicalRestrictions.e164Allowed("+73652222222", "7 365"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAValidBlacklistWithInvalidRegionBlock_whenIE164AllowedANumberInThatRegion_thenIExpectTrue() {
|
|
||||||
assertTrue(GeographicalRestrictions.e164Allowed("+73652222222", "4,7 365 2"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAValidBlacklist_whenIE164AllowedANumberNotInTheBlacklist_thenIExpectTrue() {
|
|
||||||
assertTrue(GeographicalRestrictions.e164Allowed("+73632222222", "4,7 365,44,33"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAValidBlacklist_whenIE164AllowedANumberInTheBlacklist_thenIExpectFalse() {
|
|
||||||
assertFalse(GeographicalRestrictions.e164Allowed("+73632222222", "4,7,44,33"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAValidBlacklistWithExtraSpaces_whenIE164AllowedANumberInTheBlacklist_thenIExpectFalse() {
|
|
||||||
assertFalse(GeographicalRestrictions.e164Allowed("+73632222222", " 4, 7, 44, 33 "));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenAValidBlacklistWithAreaCode_whenIE164AllowedANumberInTheBlacklistAreaCode_thenIExpectFalse() {
|
|
||||||
assertFalse(GeographicalRestrictions.e164Allowed("+15065550199", "1 506"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue