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 "int", "CANONICAL_VERSION_CODE", "$canonicalVersionCode"
|
||||
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", "RECAPTCHA_PROOF_URL", "\"https://signalcaptchas.org/challenge/generate.html\""
|
||||
|
||||
|
|
|
@ -108,15 +108,15 @@ public final class PaymentsValues extends SignalStoreValues {
|
|||
public PaymentsAvailability getPaymentsAvailability() {
|
||||
Context context = ApplicationDependencies.getApplication();
|
||||
|
||||
if (!TextSecurePreferences.isPushRegistered(context)) {
|
||||
if (!TextSecurePreferences.isPushRegistered(context) ||
|
||||
!GeographicalRestrictions.e164Allowed(TextSecurePreferences.getLocalNumber(context)))
|
||||
{
|
||||
return PaymentsAvailability.NOT_IN_REGION;
|
||||
}
|
||||
|
||||
if (FeatureFlags.payments()) {
|
||||
if (mobileCoinPaymentsEnabled()) {
|
||||
return PaymentsAvailability.WITHDRAW_AND_SEND;
|
||||
} else if (!GeographicalRestrictions.e164Allowed(TextSecurePreferences.getLocalNumber(context))) {
|
||||
return PaymentsAvailability.NOT_IN_REGION;
|
||||
} else {
|
||||
return PaymentsAvailability.REGISTRATION_AVAILABLE;
|
||||
}
|
||||
|
|
|
@ -1,185 +1,49 @@
|
|||
package org.thoughtcrime.securesms.payments;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.google.i18n.phonenumbers.NumberParseException;
|
||||
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.thoughtcrime.securesms.BuildConfig;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import io.reactivex.rxjava3.annotations.NonNull;
|
||||
|
||||
public final class GeographicalRestrictions {
|
||||
|
||||
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) {
|
||||
return selectValidator(FeatureFlags.mobileCoinBlacklist()).e164Allowed(e164);
|
||||
}
|
||||
try {
|
||||
int countryCode = PhoneNumberUtil.getInstance()
|
||||
.parse(e164, null)
|
||||
.getCountryCode();
|
||||
|
||||
@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);
|
||||
return GeographicalRestrictions.regionAllowed(countryCode);
|
||||
} catch (NumberParseException e) {
|
||||
Log.w(TAG, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
int countryCode = PhoneNumberUtil.getInstance()
|
||||
.parse(e164, null)
|
||||
.getCountryCode();
|
||||
|
||||
return regionAllowed(countryCode);
|
||||
} catch (NumberParseException e) {
|
||||
Log.w(TAG, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private interface Validator {
|
||||
boolean e164Allowed(@Nullable String e164);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.util;
|
|||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
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_DISPLAY = "android.donorBadges.display";
|
||||
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
|
||||
|
@ -130,8 +128,7 @@ public final class FeatureFlags {
|
|||
SENDER_KEY_MAX_AGE,
|
||||
DONOR_BADGES,
|
||||
DONOR_BADGES_MEGAPHONE,
|
||||
DONOR_BADGES_DISPLAY,
|
||||
MOBILECOIN_BLACKLIST
|
||||
DONOR_BADGES_DISPLAY
|
||||
);
|
||||
|
||||
@VisibleForTesting
|
||||
|
@ -437,10 +434,6 @@ public final class FeatureFlags {
|
|||
return Environment.IS_STAGING && getBoolean(CDSH, false);
|
||||
}
|
||||
|
||||
public static @Nullable String mobileCoinBlacklist() {
|
||||
return getString(MOBILECOIN_BLACKLIST, null);
|
||||
}
|
||||
|
||||
/** Only for rendering debug info. */
|
||||
public static synchronized @NonNull Map<String, Object> getMemoryValues() {
|
||||
return new TreeMap<>(REMOTE_VALUES);
|
||||
|
|
|
@ -13,8 +13,6 @@ import static org.junit.Assume.assumeTrue;
|
|||
|
||||
public final class GeographicalRestrictionsTest {
|
||||
|
||||
private static final String INVALID_BLACKLIST = "asdfkljsdhfla";
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
Log.initialize(new EmptyLogger());
|
||||
|
@ -22,57 +20,28 @@ public final class GeographicalRestrictionsTest {
|
|||
|
||||
@Test
|
||||
public void bad_number_not_allowed() {
|
||||
assertFalse(GeographicalRestrictions.e164Allowed("bad_number", null));
|
||||
assertFalse(GeographicalRestrictions.e164Allowed("bad_number"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void null_not_allowed() {
|
||||
assertFalse(GeographicalRestrictions.e164Allowed(null, null));
|
||||
assertFalse(GeographicalRestrictions.e164Allowed(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uk_allowed() {
|
||||
assertTrue(GeographicalRestrictions.e164Allowed("+441617151234", null));
|
||||
assertTrue(GeographicalRestrictions.e164Allowed("+441617151234"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void us_not_allowed_in_release() {
|
||||
assumeFalse(BuildConfig.DEBUG);
|
||||
assertFalse(GeographicalRestrictions.e164Allowed("+15407011234", null));
|
||||
public void crimea_not_allowed() {
|
||||
assertFalse(GeographicalRestrictions.e164Allowed("+79782222222"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAnInvalidBlackList_whenIE164AllowedAUkNumber_thenIExpectTrue() {
|
||||
assertTrue(GeographicalRestrictions.e164Allowed("+441617151234", INVALID_BLACKLIST));
|
||||
}
|
||||
|
||||
@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"));
|
||||
public void blacklist_not_allowed() {
|
||||
for (int code : BuildConfig.MOBILE_COIN_BLACKLIST) {
|
||||
assertFalse(GeographicalRestrictions.regionAllowed(code));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue