refactor processFailure and processChallange into methods

This commit is contained in:
Daniel Gultsch 2022-09-07 10:31:11 +02:00
parent e8bce17940
commit d4ec1eaf38

View file

@ -559,61 +559,13 @@ public class XmppConnection implements Runnable {
throw new StateChangingException(Account.State.TLS_ERROR); throw new StateChangingException(Account.State.TLS_ERROR);
} else if (nextTag.isStart("failure")) { } else if (nextTag.isStart("failure")) {
final Element failure = tagReader.readElement(nextTag); final Element failure = tagReader.readElement(nextTag);
final SaslMechanism.Version version; processFailure(failure);
try {
version = SaslMechanism.Version.of(failure);
} catch (final IllegalArgumentException e) {
throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER);
}
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": login failure " + version);
if (failure.hasChild("temporary-auth-failure")) {
throw new StateChangingException(Account.State.TEMPORARY_AUTH_FAILURE);
} else if (failure.hasChild("account-disabled")) {
final String text = failure.findChildContent("text");
if (Strings.isNullOrEmpty(text)) {
throw new StateChangingException(Account.State.UNAUTHORIZED);
}
final Matcher matcher = Patterns.AUTOLINK_WEB_URL.matcher(text);
if (matcher.find()) {
final HttpUrl url;
try {
url = HttpUrl.get(text.substring(matcher.start(), matcher.end()));
} catch (final IllegalArgumentException e) {
throw new StateChangingException(Account.State.UNAUTHORIZED);
}
if (url.isHttps()) {
this.redirectionUrl = url;
throw new StateChangingException(Account.State.PAYMENT_REQUIRED);
}
}
}
throw new StateChangingException(Account.State.UNAUTHORIZED);
} else if (nextTag.isStart("continue", Namespace.SASL_2)) { } else if (nextTag.isStart("continue", Namespace.SASL_2)) {
// two step sasl2 - we dont support this yet
throw new StateChangingException(Account.State.INCOMPATIBLE_CLIENT); throw new StateChangingException(Account.State.INCOMPATIBLE_CLIENT);
} else if (nextTag.isStart("challenge")) { } else if (nextTag.isStart("challenge")) {
final Element challenge = tagReader.readElement(nextTag); final Element challenge = tagReader.readElement(nextTag);
final SaslMechanism.Version version; processChallenge(challenge);
try {
version = SaslMechanism.Version.of(challenge);
} catch (final IllegalArgumentException e) {
throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER);
}
final Element response;
if (version == SaslMechanism.Version.SASL) {
response = new Element("response", Namespace.SASL);
} else if (version == SaslMechanism.Version.SASL_2) {
response = new Element("response", Namespace.SASL_2);
} else {
throw new AssertionError("Missing implementation for " + version);
}
try {
response.setContent(saslMechanism.getResponse(challenge.getContent(), sslSocketOrNull(socket)));
} catch (final SaslMechanism.AuthenticationException e) {
// TODO: Send auth abort tag.
Log.e(Config.LOGTAG, e.toString());
throw new StateChangingException(Account.State.UNAUTHORIZED);
}
tagWriter.writeElement(response);
} else if (nextTag.isStart("enabled", Namespace.STREAM_MANAGEMENT)) { } else if (nextTag.isStart("enabled", Namespace.STREAM_MANAGEMENT)) {
final Element enabled = tagReader.readElement(nextTag); final Element enabled = tagReader.readElement(nextTag);
processEnabled(enabled); processEnabled(enabled);
@ -690,6 +642,31 @@ public class XmppConnection implements Runnable {
} }
} }
private void processChallenge(Element challenge) throws IOException {
final SaslMechanism.Version version;
try {
version = SaslMechanism.Version.of(challenge);
} catch (final IllegalArgumentException e) {
throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER);
}
final Element response;
if (version == SaslMechanism.Version.SASL) {
response = new Element("response", Namespace.SASL);
} else if (version == SaslMechanism.Version.SASL_2) {
response = new Element("response", Namespace.SASL_2);
} else {
throw new AssertionError("Missing implementation for " + version);
}
try {
response.setContent(saslMechanism.getResponse(challenge.getContent(), sslSocketOrNull(socket)));
} catch (final SaslMechanism.AuthenticationException e) {
// TODO: Send auth abort tag.
Log.e(Config.LOGTAG, e.toString());
throw new StateChangingException(Account.State.UNAUTHORIZED);
}
tagWriter.writeElement(response);
}
private boolean processSuccess(final Element success) private boolean processSuccess(final Element success)
throws IOException, XmlPullParserException { throws IOException, XmlPullParserException {
final SaslMechanism.Version version; final SaslMechanism.Version version;
@ -798,6 +775,38 @@ public class XmppConnection implements Runnable {
} }
} }
private void processFailure(final Element failure) throws StateChangingException {
final SaslMechanism.Version version;
try {
version = SaslMechanism.Version.of(failure);
} catch (final IllegalArgumentException e) {
throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER);
}
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": login failure " + version);
if (failure.hasChild("temporary-auth-failure")) {
throw new StateChangingException(Account.State.TEMPORARY_AUTH_FAILURE);
} else if (failure.hasChild("account-disabled")) {
final String text = failure.findChildContent("text");
if (Strings.isNullOrEmpty(text)) {
throw new StateChangingException(Account.State.UNAUTHORIZED);
}
final Matcher matcher = Patterns.AUTOLINK_WEB_URL.matcher(text);
if (matcher.find()) {
final HttpUrl url;
try {
url = HttpUrl.get(text.substring(matcher.start(), matcher.end()));
} catch (final IllegalArgumentException e) {
throw new StateChangingException(Account.State.UNAUTHORIZED);
}
if (url.isHttps()) {
this.redirectionUrl = url;
throw new StateChangingException(Account.State.PAYMENT_REQUIRED);
}
}
}
throw new StateChangingException(Account.State.UNAUTHORIZED);
}
private static SSLSocket sslSocketOrNull(final Socket socket) { private static SSLSocket sslSocketOrNull(final Socket socket) {
if (socket instanceof SSLSocket) { if (socket instanceof SSLSocket) {
return (SSLSocket) socket; return (SSLSocket) socket;