Login on startup

This commit is contained in:
Paul Schaub 2019-12-22 05:48:07 +01:00
parent 866772f577
commit 6ae00a936b
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
4 changed files with 134 additions and 40 deletions

View file

@ -8,6 +8,7 @@ import org.mercury_im.messenger.data.repository.Repositories;
import org.mercury_im.messenger.entity.Account;
import org.mercury_im.messenger.store.MercuryRosterStore;
import org.mercury_im.messenger.usecase.AddAccount;
import org.mercury_im.messenger.usecase.ConnectAccountsOnStartup;
import org.mercury_im.messenger.xmpp.MercuryConnection;
import java.util.HashMap;
@ -18,6 +19,10 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import io.reactivex.Scheduler;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
public class Messenger implements ClientStateListener {
public static final String TAG = "MercuryIM";
@ -26,9 +31,20 @@ public class Messenger implements ClientStateListener {
private final Map<UUID, MercuryConnection> connections = new HashMap<>();
private Repositories repositories;
private CompositeDisposable disposable = new CompositeDisposable();
@Inject
public Messenger(Repositories repositories) {
this.repositories = repositories;
initialLogin();
}
public void initialLogin() {
disposable.add(repositories.getAccountRepository().observeAllAccounts().firstOrError()
.subscribeOn(Schedulers.newThread())
.subscribe(initialAccounts -> ConnectAccountsOnStartup
.with(this, initialAccounts)
.execute()));
}
public void addConnection(MercuryConnection connection) {

View file

@ -1,17 +1,11 @@
package org.mercury_im.messenger.usecase;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.sasl.SASLErrorException;
import org.mercury_im.messenger.Messenger;
import org.mercury_im.messenger.data.repository.AccountRepository;
import org.mercury_im.messenger.entity.Account;
import org.mercury_im.messenger.entity.IAccount;
import org.mercury_im.messenger.xmpp.MercuryConnection;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import io.reactivex.Completable;
@ -23,13 +17,6 @@ public class AddAccount {
private static final Logger LOGGER = Logger.getLogger(AddAccount.class.getName());
public enum ConnectionResult {
success,
credential_error,
server_error,
other_error
}
private Account account;
private MercuryConnection connection;
@ -87,11 +74,8 @@ public class AddAccount {
}
private Completable logIntoAccount() {
return Completable.fromAction(
() -> {
getOrCreateConnection();
doAuthenticateIfNecessary();
})
return Completable.fromAction(this::getOrCreateConnection)
.andThen(LogIntoAccount.with(connection).executeAndPossiblyThrow())
.subscribeOn(Schedulers.io());
}
@ -102,27 +86,5 @@ public class AddAccount {
}
}
private ConnectionResult authenticateIfNecessary() {
try {
doAuthenticateIfNecessary();
return ConnectionResult.success;
} catch (SASLErrorException e) {
LOGGER.log(Level.WARNING, "SASL Error while connecting to account " + account.getAddress(), e);
return ConnectionResult.credential_error;
} catch (SmackException.ConnectionException e) {
LOGGER.log(Level.WARNING, "Connectivity error while connecting to account " + account.getAddress(), e);
return ConnectionResult.server_error;
}
catch (IOException | XMPPException | SmackException | InterruptedException e) {
LOGGER.log(Level.WARNING, "Error connecting to account " + account.getAddress(), e);
return ConnectionResult.other_error;
}
}
private void doAuthenticateIfNecessary()
throws InterruptedException, XMPPException, SmackException, IOException {
if (!connection.getConnection().isAuthenticated()) {
((AbstractXMPPConnection) connection.getConnection()).connect().login();
}
}
}

View file

@ -0,0 +1,47 @@
package org.mercury_im.messenger.usecase;
import org.mercury_im.messenger.Messenger;
import org.mercury_im.messenger.entity.Account;
import org.mercury_im.messenger.xmpp.MercuryConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
public class ConnectAccountsOnStartup {
private static final Logger LOGGER = Logger.getLogger(ConnectAccountsOnStartup.class.getName());
private final Messenger messenger;
private final List<Account> accounts = new ArrayList<>();
private CompositeDisposable disposable = new CompositeDisposable();
private ConnectAccountsOnStartup(Messenger messenger, List<Account> initialAccounts) {
this.messenger = messenger;
this.accounts.addAll(initialAccounts);
}
public static ConnectAccountsOnStartup with(Messenger messenger, List<Account> initialAccounts) {
return new ConnectAccountsOnStartup(messenger, initialAccounts);
}
public void execute() {
for (Account account : accounts) {
if (account.isEnabled()) {
MercuryConnection connection = new MercuryConnection(account);
disposable.add(LogIntoAccount.with(connection)
.executeAndPossiblyThrow()
.subscribeOn(Schedulers.newThread())
.doOnComplete(() -> messenger.addConnection(connection))
.subscribe(
() -> LOGGER.log(Level.INFO, "Successfully logged into account " + account.getAddress()),
error -> LOGGER.log(Level.SEVERE, "Error logging into account " + account.getAddress(), error)));
}
}
}
}

View file

@ -0,0 +1,69 @@
package org.mercury_im.messenger.usecase;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.sasl.SASLErrorException;
import org.mercury_im.messenger.xmpp.MercuryConnection;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import io.reactivex.Completable;
import io.reactivex.Single;
public class LogIntoAccount {
public enum ConnectionResult {
success,
credential_error,
server_error,
other_error
}
private static final Logger LOGGER = Logger.getLogger(LogIntoAccount.class.getName());
private final MercuryConnection connection;
private LogIntoAccount(MercuryConnection connection) {
this.connection = connection;
}
public static LogIntoAccount with(MercuryConnection connection) {
return new LogIntoAccount(connection);
}
public Completable executeAndPossiblyThrow() {
return Completable.fromAction(this::doAuthenticateIfNecessary);
}
public Single<ConnectionResult> execute() {
return Single.fromCallable(this::authenticateIfNecessary);
}
private ConnectionResult authenticateIfNecessary() {
try {
doAuthenticateIfNecessary();
return ConnectionResult.success;
} catch (SASLErrorException e) {
LOGGER.log(Level.WARNING, "SASL Error while connecting to account " + connection.getAccount().getAddress(), e);
return ConnectionResult.credential_error;
} catch (SmackException.ConnectionException e) {
LOGGER.log(Level.WARNING, "Connectivity error while connecting to account " + connection.getAccount().getAddress(), e);
return ConnectionResult.server_error;
}
catch (IOException | XMPPException | SmackException | InterruptedException e) {
LOGGER.log(Level.WARNING, "Error connecting to account " + connection.getAccount().getAddress(), e);
return ConnectionResult.other_error;
}
}
private void doAuthenticateIfNecessary()
throws InterruptedException, XMPPException, SmackException, IOException {
if (!connection.getConnection().isAuthenticated()) {
((AbstractXMPPConnection) connection.getConnection()).connect().login();
}
}
}