133 lines
4.5 KiB
Java
133 lines
4.5 KiB
Java
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.jxmpp.jid.BareJid;
|
|
import org.jxmpp.jid.impl.JidCreate;
|
|
import org.jxmpp.stringprep.XmppStringprepException;
|
|
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.exception.IllegalUsernameException;
|
|
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;
|
|
import io.reactivex.schedulers.Schedulers;
|
|
|
|
public class AddAccount {
|
|
|
|
private static final Logger LOGGER = Logger.getLogger(AddAccount.class.getName());
|
|
|
|
private String username;
|
|
private String server;
|
|
private BareJid address;
|
|
private String password;
|
|
private Account account;
|
|
|
|
private final AccountRepository accountRepository;
|
|
private final Messenger messenger;
|
|
|
|
public AddAccount(AccountRepository accountRepository, Messenger messenger) {
|
|
this.accountRepository = accountRepository;
|
|
this.messenger = messenger;
|
|
}
|
|
|
|
public void setAddress(String address) {
|
|
try {
|
|
this.address = JidCreate.entityBareFrom(address);
|
|
} catch (XmppStringprepException e) {
|
|
this.address = null;
|
|
throw new IllegalUsernameException(e);
|
|
}
|
|
}
|
|
|
|
public boolean isAddressSet() {
|
|
return address != null;
|
|
}
|
|
|
|
public void setPassword(String password) {
|
|
this.password = password;
|
|
}
|
|
|
|
public boolean isPasswordSet() {
|
|
return password != null;
|
|
}
|
|
|
|
public Single<Account> insertAccountIntoDatabase() {
|
|
Account account = new IAccount();
|
|
account.setAddress(address.asUnescapedString());
|
|
account.setPassword(password);
|
|
return accountRepository.insertAccount(account).doAfterSuccess(this::setAccount);
|
|
}
|
|
|
|
private void setAccount(Account account) {
|
|
this.account = account;
|
|
}
|
|
|
|
public Single<ConnectionResult> enableAccountAndLogin(Account account) {
|
|
return enableAccount(account).andThen(login(account));
|
|
}
|
|
|
|
private Completable enableAccount(Account account) {
|
|
account.setEnabled(true);
|
|
return accountRepository.upsertAccount(account)
|
|
.doAfterSuccess(this::setAccount)
|
|
.ignoreElement();
|
|
}
|
|
|
|
private Single<ConnectionResult> login(Account account) {
|
|
return Single.fromCallable(() -> {
|
|
MercuryConnection connection = getOrCreateConnection(account);
|
|
return authenticateIfNecessary(connection);
|
|
}).subscribeOn(Schedulers.io());
|
|
}
|
|
|
|
private MercuryConnection getOrCreateConnection(Account account) {
|
|
MercuryConnection connection = messenger.getConnection(account);
|
|
if (connection == null) {
|
|
connection = new MercuryConnection(account);
|
|
messenger.addConnection(connection);
|
|
}
|
|
return connection;
|
|
}
|
|
|
|
private ConnectionResult authenticateIfNecessary(MercuryConnection connection) {
|
|
try {
|
|
doAuthenticateIfNecessary(connection);
|
|
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(MercuryConnection connection)
|
|
throws InterruptedException, XMPPException, SmackException, IOException {
|
|
if (!connection.getConnection().isAuthenticated()) {
|
|
((AbstractXMPPConnection) connection.getConnection()).connect().login();
|
|
}
|
|
}
|
|
|
|
public enum ConnectionResult {
|
|
success,
|
|
credential_error,
|
|
server_error,
|
|
other_error
|
|
}
|
|
}
|