From a4e828aba5f3a85b27738b7f7956e8267a960245 Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Sat, 16 Dec 2017 22:14:00 +0100 Subject: XmppConnection: refactor registration code. 'Open Website' on PAYMENT_REQUIRED failure --- .../de/pixart/messenger/xmpp/XmppConnection.java | 119 +++++++++++---------- 1 file changed, 65 insertions(+), 54 deletions(-) (limited to 'src/main/java/de/pixart/messenger/xmpp') diff --git a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java index 00a8d5008..b7233b848 100644 --- a/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java +++ b/src/main/java/de/pixart/messenger/xmpp/XmppConnection.java @@ -20,6 +20,7 @@ import java.net.ConnectException; import java.net.IDN; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.net.MalformedURLException; import java.net.Socket; import java.net.URL; import java.net.UnknownHostException; @@ -145,7 +146,7 @@ public class XmppConnection implements Runnable { private EditAccountActivity mEditAccountActivity = null; private SaslMechanism saslMechanism; - private String webRegistrationUrl = null; + private URL redirectionUrl = null; private String verifiedHostname = null; private class MyKeyManager implements X509KeyManager { @@ -196,8 +197,7 @@ public class XmppConnection implements Runnable { public void onIqPacketReceived(Account account, IqPacket packet) { if (packet.getType() == IqPacket.TYPE.RESULT) { account.setOption(Account.OPTION_REGISTER, false); - forceCloseSocket(); - changeStatus(Account.State.REGISTRATION_SUCCESSFUL); + throw new StateChangingError(Account.State.REGISTRATION_SUCCESSFUL); } else { final List PASSWORD_TOO_WEAK_MSGS = Arrays.asList( "The password is too weak", @@ -221,8 +221,7 @@ public class XmppConnection implements Runnable { } } Log.d(Config.LOGTAG, "Delete account because of error " + error); - changeStatus(state); - forceCloseSocket(); + throw new StateChangingError(state); } } }; @@ -573,15 +572,21 @@ public class XmppConnection implements Runnable { final Element failure = tagReader.readElement(nextTag); if (Namespace.SASL.equals(failure.getNamespace())) { final String text = failure.findChildContent("text"); - if (failure.hasChild("account-disabled") - && text != null - && text.contains("renew") - && Config.MAGIC_CREATE_DOMAIN != null - && text.contains(Config.MAGIC_CREATE_DOMAIN)) { - throw new StateChangingException(Account.State.PAYMENT_REQUIRED); - } else { - throw new StateChangingException(Account.State.UNAUTHORIZED); + if (failure.hasChild("account-disabled") && text != null) { + Matcher matcher = Patterns.AUTOLINK_WEB_URL.matcher(text); + if (matcher.find()) { + try { + URL url = new URL(text.substring(matcher.start(), matcher.end())); + if (url.getProtocol().equals("https")) { + this.redirectionUrl = url; + throw new StateChangingException(Account.State.PAYMENT_REQUIRED); + } + } catch (MalformedURLException e) { + throw new StateChangingException(Account.State.UNAUTHORIZED); + } + } } + throw new StateChangingException(Account.State.UNAUTHORIZED); } else if (Namespace.TLS.equals(failure.getNamespace())) { throw new StateChangingException(Account.State.TLS_ERROR); } else { @@ -969,10 +974,14 @@ public class XmppConnection implements Runnable { @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { - boolean failed = false; - if (packet.getType() == IqPacket.TYPE.RESULT - && packet.query().hasChild("username") - && (packet.query().hasChild("password"))) { + if (packet.getType() == IqPacket.TYPE.TIMEOUT) { + return; + } + if (packet.getType() == IqPacket.TYPE.ERROR) { + throw new StateChangingError(Account.State.REGISTRATION_FAILED); + } + final Element query = packet.query("jabber:iq:register"); + if (query.hasChild("username") && (query.hasChild("password"))) { final IqPacket register = new IqPacket(IqPacket.TYPE.SET); final Element username = new Element("username").setContent(account.getUsername()); final Element password = new Element("password").setContent(account.getPassword()); @@ -980,73 +989,75 @@ public class XmppConnection implements Runnable { register.query().addChild(password); register.setFrom(account.getJid().toBareJid()); sendUnmodifiedIqPacket(register, registrationResponseListener); - } else if (packet.getType() == IqPacket.TYPE.RESULT - && (packet.query().hasChild("x", "jabber:x:data"))) { - final Data data = Data.parse(packet.query().findChild("x", "jabber:x:data")); - final Element blob = packet.query().findChild("data", "urn:xmpp:bob"); + } else if (query.hasChild("x", "jabber:x:data")) { + final Data data = Data.parse(query.findChild("x", "jabber:x:data")); + final Element blob = query.findChild("data", "urn:xmpp:bob"); final String id = packet.getId(); - - Bitmap captcha = null; + InputStream is; if (blob != null) { try { final String base64Blob = blob.getContent(); final byte[] strBlob = Base64.decode(base64Blob, Base64.DEFAULT); - InputStream stream = new ByteArrayInputStream(strBlob); - captcha = BitmapFactory.decodeStream(stream); + is = new ByteArrayInputStream(strBlob); } catch (Exception e) { - //ignored + is = null; } } else { try { - Field url = data.getFieldByName("url"); - String urlString = url.findChildContent("value"); - URL uri = new URL(urlString); - captcha = BitmapFactory.decodeStream(uri.openConnection().getInputStream()); + Field field = data.getFieldByName("url"); + URL url = field != null && field.getValue() != null ? new URL(field.getValue()) : null; + is = url != null ? url.openStream() : null; } catch (IOException e) { - Log.e(Config.LOGTAG, e.toString()); + is = null; } } - if (captcha != null) { - failed = !mXmppConnectionService.displayCaptchaRequest(account, id, data, captcha); + if (is != null) { + Bitmap captcha = BitmapFactory.decodeStream(is); + try { + if (mXmppConnectionService.displayCaptchaRequest(account, id, data, captcha)) { + return; + } + } catch (Exception e) { + throw new StateChangingError(Account.State.REGISTRATION_FAILED); + } } - } else { - failed = true; - } - - if (failed) { - final Element query = packet.query(); + throw new StateChangingError(Account.State.REGISTRATION_FAILED); + } else if (query.hasChild("instructions") || query.hasChild("x", Namespace.OOB)) { final String instructions = query.findChildContent("instructions"); final Element oob = query.findChild("x", Namespace.OOB); final String url = oob == null ? null : oob.findChildContent("url"); - if (url == null && instructions != null) { + if (url != null) { + setAccountCreationFailed(url); + } else if (instructions != null) { Matcher matcher = Patterns.AUTOLINK_WEB_URL.matcher(instructions); if (matcher.find()) { setAccountCreationFailed(instructions.substring(matcher.start(), matcher.end())); - } else { - setAccountCreationFailed(null); } - } else { - setAccountCreationFailed(url); } + throw new StateChangingError(Account.State.REGISTRATION_FAILED); } } }); } + private void setAccountCreationFailed(String url) { - if (url != null && (url.toLowerCase().startsWith("http://") || url.toLowerCase().startsWith("https://"))) { - changeStatus(Account.State.REGISTRATION_WEB); - this.webRegistrationUrl = url; - } else { - changeStatus(Account.State.REGISTRATION_FAILED); + if (url != null) { + try { + this.redirectionUrl = new URL(url); + if (this.redirectionUrl.getProtocol().equals("https")) { + throw new StateChangingError(Account.State.REGISTRATION_WEB); + } + } catch (MalformedURLException e) { + //fall through + } } - disconnect(true); - Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not register. url=" + url); + throw new StateChangingError(Account.State.REGISTRATION_FAILED); } - public String getWebRegistrationUrl() { - return this.webRegistrationUrl; + public URL getRedirectionUrl() { + return this.redirectionUrl; } public void resetEverything() { @@ -1054,7 +1065,7 @@ public class XmppConnection implements Runnable { resetStreamId(); clearIqCallbacks(); mStanzaQueue.clear(); - this.webRegistrationUrl = null; + this.redirectionUrl = null; synchronized (this.disco) { disco.clear(); } -- cgit v1.2.3