summaryrefslogtreecommitdiff
path: root/app/src/main/java/se/leap/bitmaskclient/base
diff options
context:
space:
mode:
authorcyberta <cyberta@riseup.net>2025-04-15 01:00:08 +0000
committercyberta <cyberta@riseup.net>2025-04-15 01:00:08 +0000
commita9f2c30d415e1349616101a11ddfa0719995ef8d (patch)
tree70838b6149deb178fc31a45cd8f38e55c110c1be /app/src/main/java/se/leap/bitmaskclient/base
parent1b668a3163ce2d824486f045a9f0a0b1ee29256f (diff)
show error dialog in case invite code scanning fails
Diffstat (limited to 'app/src/main/java/se/leap/bitmaskclient/base')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java86
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java2
2 files changed, 77 insertions, 11 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java b/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java
index e3175010..fe30a324 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Introducer.java
@@ -1,15 +1,30 @@
package se.leap.bitmaskclient.base.models;
+import static se.leap.bitmaskclient.base.models.Introducer.IntroducerException.ADDRESS_FORMAT;
+import static se.leap.bitmaskclient.base.models.Introducer.IntroducerException.AUTH_MISSING;
+import static se.leap.bitmaskclient.base.models.Introducer.IntroducerException.CERTIFICATE_LENGTH;
+import static se.leap.bitmaskclient.base.models.Introducer.IntroducerException.CERTIFICATE_MISSING;
+import static se.leap.bitmaskclient.base.models.Introducer.IntroducerException.FQDN_INVALID;
+import static se.leap.bitmaskclient.base.models.Introducer.IntroducerException.FQDN_LENGTH;
+import static se.leap.bitmaskclient.base.models.Introducer.IntroducerException.FQDN_MISSING;
+import static se.leap.bitmaskclient.base.models.Introducer.IntroducerException.UNKNOWN_TYPE;
+
+import android.content.Context;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
+import androidx.annotation.Nullable;
+
import java.io.UnsupportedEncodingException;
import java.net.IDN;
import java.net.URISyntaxException;
import java.net.URLEncoder;
+import java.util.IllegalFormatException;
import java.util.Locale;
+import se.leap.bitmaskclient.R;
+
public class Introducer implements Parcelable {
private final String type;
private final String address;
@@ -69,45 +84,52 @@ public class Introducer implements Parcelable {
public boolean validate() {
if (!"obfsvpnintro".equals(type)) {
- throw new IllegalArgumentException("Unknown type: " + type);
+ throw new IntroducerException(UNKNOWN_TYPE, "Unknown type: ", type);
}
if (!address.contains(":") || address.split(":").length != 2) {
- throw new IllegalArgumentException("Expected address in format ipaddr:port");
+ throw new IntroducerException(ADDRESS_FORMAT, "Expected address in format ipaddr:port");
}
if (certificate.length() != 70) {
- throw new IllegalArgumentException("Wrong certificate length: " + certificate.length());
+ throw new IntroducerException(CERTIFICATE_LENGTH, "Wrong certificate length: ", String.valueOf(certificate.length()));
}
if (!"localhost".equals(fullyQualifiedDomainName) && fullyQualifiedDomainName.split("\\.").length < 2) {
- throw new IllegalArgumentException("Expected a FQDN, got: " + fullyQualifiedDomainName);
+ throw new IntroducerException(FQDN_LENGTH, "Expected a FQDN, got: ", fullyQualifiedDomainName);
}
if (auth == null || auth.isEmpty()) {
- throw new IllegalArgumentException("Auth token is missing");
+ throw new IntroducerException(AUTH_MISSING, "Auth token is missing");
}
return true;
}
- public static Introducer fromUrl(String introducerUrl) throws URISyntaxException, IllegalArgumentException {
+ /**
+ * Helper method to create an Introducer model object, containing the information how to query a menshen API via a proxy
+ * @param introducerUrl String representing an 'invite code'
+ * @return Introducer model
+ * @throws NullPointerException in case the parameter introducerUrl is null
+ * @throws IntroducerException in case the parameter introducerUrl is invalid
+ */
+ public static Introducer fromUrl(String introducerUrl) throws NullPointerException, IntroducerException {
Uri uri = Uri.parse(introducerUrl);
String fqdn = uri.getQueryParameter("fqdn");
if (fqdn == null || fqdn.isEmpty()) {
- throw new IllegalArgumentException("FQDN not found in the introducer URL");
+ throw new IntroducerException(FQDN_MISSING, "FQDN not found in the introducer URL");
}
if (!isAscii(fqdn)) {
- throw new IllegalArgumentException("FQDN is not ASCII: " + fqdn);
+ throw new IntroducerException(FQDN_INVALID, "FQDN is not ASCII: " + fqdn, fqdn);
}
boolean kcp = "1".equals(uri.getQueryParameter( "kcp"));
String cert = uri.getQueryParameter( "cert");
if (cert == null || cert.isEmpty()) {
- throw new IllegalArgumentException("Cert not found in the introducer URL");
+ throw new IntroducerException(CERTIFICATE_MISSING, "Cert not found in the introducer URL");
}
String auth = uri.getQueryParameter( "auth");
if (auth == null || auth.isEmpty()) {
- throw new IllegalArgumentException("Authentication token not found in the introducer URL");
+ throw new IntroducerException(AUTH_MISSING, "Authentication token not found in the introducer URL");
}
return new Introducer(uri.getScheme(), uri.getAuthority(), cert, fqdn, kcp, auth);
}
@@ -129,4 +151,48 @@ public class Introducer implements Parcelable {
return String.format(Locale.US, "%s://%s?fqdn=%s&kcp=%d&cert=%s&auth=%s", type, address, URLEncoder.encode(fullyQualifiedDomainName, "UTF-8"), kcpEnabled ? 1 : 0, URLEncoder.encode(certificate, "UTF-8"), URLEncoder.encode(auth, "UTF-8"));
}
+ public static class IntroducerException extends IllegalArgumentException {
+ public static final int UNKNOWN_TYPE = 100;
+ public static final int ADDRESS_FORMAT = 200;
+ public static final int CERTIFICATE_LENGTH = 300;
+ public static final int CERTIFICATE_MISSING = 310;
+ public static final int FQDN_LENGTH = 400;
+ public static final int FQDN_MISSING = 410;
+ public static final int FQDN_INVALID = 420;
+ public static final int AUTH_MISSING = 500;
+
+ private final Object[] args;
+ private final int type;
+
+ public IntroducerException(int type, String defaultMsg, Object... args) {
+ super(args == null ? defaultMsg : String.format(defaultMsg, args));
+ this.type = type;
+ this.args = args;
+ }
+
+
+ @Nullable
+ public String getLocalizedMessage(Context context) {
+ if (context == null) {
+ return getMessage();
+ }
+ try {
+ return switch (type) {
+ case UNKNOWN_TYPE -> context.getString(R.string.error_invite_unknown_type, args);
+ case ADDRESS_FORMAT -> context.getString(R.string.error_invite_address_format);
+ case CERTIFICATE_LENGTH -> context.getString(R.string.error_invite_certificate_length, args);
+ case CERTIFICATE_MISSING -> context.getString(R.string.error_invite_certificate_missing);
+ case FQDN_LENGTH -> context.getString(R.string.error_invite_fqdn_length, args);
+ case FQDN_MISSING -> context.getString(R.string.error_invite_fqdn_missing);
+ case FQDN_INVALID -> context.getString(R.string.error_invite_fqdn_invalid, args);
+ case AUTH_MISSING -> context.getString(R.string.error_invite_auth_missing);
+ default -> getMessage();
+ };
+ } catch (IllegalFormatException e) {
+ e.printStackTrace();
+ return getMessage();
+ }
+
+ }
+ }
} \ No newline at end of file
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java b/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java
index b4ec23e6..1708fe83 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java
@@ -983,7 +983,7 @@ public final class Provider implements Parcelable {
return introducer;
}
- public void setIntroducer(String introducerUrl) throws URISyntaxException, IllegalArgumentException {
+ public void setIntroducer(String introducerUrl) throws NullPointerException, IllegalArgumentException {
this.introducer = Introducer.fromUrl(introducerUrl);
}