void PendingConnection::onCallFinished(QDBusPendingCallWatcher *watcher)
{
    QDBusPendingReply<QString, QDBusObjectPath> reply = *watcher;

    if (!reply.isError()) {
        QString busName = reply.argumentAt<0>();
        QString objectPath = reply.argumentAt<1>().path();

        debug() << "Got reply to ConnectionManager.CreateConnection - bus name:" <<
            busName << "- object path:" << objectPath;

        PendingReady *readyOp = manager()->connectionFactory()->proxy(busName,
                objectPath, manager()->channelFactory(), manager()->contactFactory());
        mPriv->connection = ConnectionPtr::qObjectCast(readyOp->proxy());
        connect(readyOp,
                SIGNAL(finished(Tp::PendingOperation*)),
                SLOT(onConnectionBuilt(Tp::PendingOperation*)));
    } else {
        debug().nospace() <<
            "CreateConnection failed: " <<
            reply.error().name() << ": " << reply.error().message();
        setFinishedWithError(reply.error());
    }

    watcher->deleteLater();
}
void PendingFileSend::onTransferStateChanged(FileTransferState state,
        FileTransferStateChangeReason stateReason)
{
    PendingFileTransfer::onTransferStateChanged(state, stateReason);

    if (state == FileTransferStateAccepted) {
        Q_ASSERT(!mSendingFile);
        mSendingFile = true;

        OutgoingFileTransferChannelPtr chan =
            OutgoingFileTransferChannelPtr::qObjectCast(channel());
        Q_ASSERT(chan);

        QString uri = chan->uri();
        mFile.setFileName(QUrl(uri).toLocalFile());
        if (!mFile.open(QIODevice::ReadOnly)) {
            qWarning() << "Unable to open" << uri << "for reading, aborting transfer";
            setFinishedWithError(TP_QT4_ERROR_INVALID_ARGUMENT,
                    QLatin1String("Unable to open file for reading"));
            return;
        }

        qDebug() << "Sending" << uri << "to" << chan->targetId();
        chan->provideFile(&mFile);
    }
}
/**
 * Construct a new PendingChannelRequest object that always fails.
 *
 * \param account Account to use.
 * \param errorName The name of a D-Bus error.
 * \param errorMessage The error message.
 */
PendingChannelRequest::PendingChannelRequest(const AccountPtr &account,
        const QString &errorName, const QString &errorMessage)
    : PendingOperation(ConnectionPtr()),
      mPriv(new Private(account->dbusConnection()))
{
    setFinishedWithError(errorName, errorMessage);
}
void PendingDBusTubeConnection::onConnectionFinished(PendingOperation *op)
{
    if (isFinished()) {
        // The operation has already failed
        return;
    }

    if (op->isError()) {
        // Fail
        setFinishedWithError(op->errorName(), op->errorMessage());
        return;
    }

    debug() << "Accept/Offer tube finished successfully";

    // Now get the address and set it
    PendingString *ps = qobject_cast<PendingString*>(op);
    debug() << "Got address " << ps->result();
    mPriv->tube->setAddress(ps->result());

    // It might have been already opened - check
    if (mPriv->tube->state() == TubeChannelStateOpen) {
        onStateChanged(mPriv->tube->state());
    } else {
        // Wait until the tube gets opened on the other side
        connect(mPriv->tube.data(), SIGNAL(stateChanged(Tp::TubeChannelState)),
                this, SLOT(onStateChanged(Tp::TubeChannelState)));
    }
}
Example #5
0
void SaslAuthOp::gotProperties(Tp::PendingOperation *op)
{
    if (m_mechanisms.isEmpty()) {
        if (op->isError()) {
            qWarning() << "Unable to retrieve available SASL mechanisms";
            m_channel->requestClose();
            setFinishedWithError(op->errorName(), op->errorMessage());
            return;
        }

        Tp::PendingVariantMap *pvm = qobject_cast<Tp::PendingVariantMap*>(op);
        m_properties = qdbus_cast<QVariantMap>(pvm->result());
        m_mechanisms = qdbus_cast<QStringList>(m_properties.value(QLatin1String("AvailableMechanisms")));
        qDebug() << m_mechanisms;
    }

    uint status = qdbus_cast<uint>(m_properties.value(QLatin1String("SASLStatus")));
    QString error = qdbus_cast<QString>(m_properties.value(QLatin1String("SASLError")));
    QVariantMap errorDetails = qdbus_cast<QVariantMap>(m_properties.value(QLatin1String("SASLErrorDetails")));

    if (m_mechanisms.contains(QLatin1String("X-OAUTH2"))) {
        qDebug() << "Starting X-OAuth2 auth";
        m_mechanisms.removeAll(QStringLiteral("X-OAUTH2"));
        XTelepathySSOGoogleOperation *authop = new XTelepathySSOGoogleOperation(m_account, m_accountStorageId, m_saslIface);
        connect(authop,
                SIGNAL(finished(Tp::PendingOperation*)),
                SLOT(onAuthOperationFinished(Tp::PendingOperation*)));

        authop->onSASLStatusChanged(status, error, errorDetails);
    } else if (m_mechanisms.contains(QLatin1String("X-TELEPATHY-PASSWORD"))) {
        qDebug() << "Starting Password auth";
        m_mechanisms.removeAll(QStringLiteral("X-TELEPATHY-PASSWORD"));
        Q_EMIT ready(this);
        XTelepathyPasswordAuthOperation *authop = new XTelepathyPasswordAuthOperation(m_account, m_accountStorageId, m_saslIface, qdbus_cast<bool>(m_properties.value(QLatin1String("CanTryAgain"))));
        connect(authop,
                SIGNAL(finished(Tp::PendingOperation*)),
                SLOT(onAuthOperationFinished(Tp::PendingOperation*)));

        authop->onSASLStatusChanged(status, error, errorDetails);
    } else {
        qWarning() << "X-TELEPATHY-PASSWORD, X-OAUTH2 are the only supported SASL mechanism and are not available:" << m_mechanisms;
        m_channel->requestClose();
        setFinishedWithError(TP_QT_ERROR_NOT_IMPLEMENTED,
                QLatin1String("X-TELEPATHY-PASSWORD, X-OAUTH2 are the only supported SASL mechanism and are not available:"));
        return;
    }
}
void PendingClear::finish()
{
    if (errorName.isEmpty()) {
        setFinished();
    } else {
        setFinishedWithError(errorName, errorMessage);
    }
}
PendingStreamTubeConnection::PendingStreamTubeConnection(
        const QString& errorName,
        const QString& errorMessage,
        const IncomingStreamTubeChannelPtr &channel)
    : PendingOperation(channel),
      mPriv(new PendingStreamTubeConnection::Private(this))
{
    setFinishedWithError(errorName, errorMessage);
}
PendingDBusTubeConnection::PendingDBusTubeConnection(
        const QString &errorName,
        const QString &errorMessage,
        const DBusTubeChannelPtr &object)
    : PendingOperation(object)
    , mPriv(new PendingDBusTubeConnection::Private(this))
{
    setFinishedWithError(errorName, errorMessage);
}
void PendingDBusTubeConnection::onChannelInvalidated(DBusProxy* proxy,
        const QString& errorName, const QString& errorMessage)
{
    Q_UNUSED(proxy);

    if (isFinished()) {
        // The operation has already finished
        return;
    }

    setFinishedWithError(errorName, errorMessage);
}
void PendingConnection::onConnectionBuilt(Tp::PendingOperation *op)
{
    Q_ASSERT(op->isFinished());

    if (op->isError()) {
        warning() << "Making connection ready using the factory failed:" <<
            op->errorName() << op->errorMessage();
        setFinishedWithError(op->errorName(), op->errorMessage());
    } else {
        setFinished();
        debug() << "New connection" << mPriv->connection->objectPath() << "built";
    }
}
void PendingStreamTubeConnection::onChannelInvalidated(DBusProxy *proxy,
        const QString &errorName, const QString &errorMessage)
{
    Q_UNUSED(proxy);

    if (isFinished()) {
        return;
    }

    warning().nospace() << "StreamTube.Accept failed because channel was invalidated with " <<
        errorName << ": " << errorMessage;

    setFinishedWithError(errorName, errorMessage);
}
Example #12
0
void SaslAuthOp::onAuthOperationFinished(Tp::PendingOperation *op)
{
    if (op->isError()) {
        if (!m_mechanisms.isEmpty()) {
            // if we have other mechanisms left, try again with different one
            gotProperties(0);
        } else {
            setFinishedWithError(op->errorName(), op->errorMessage());
            m_channel->requestClose();
        }
    } else {
        setFinished();
        m_channel->requestClose();
    }
}
void PendingContactInfo::onCallFinished(QDBusPendingCallWatcher *watcher)
{
    QDBusPendingReply<Tp::ContactInfoFieldList> reply = *watcher;

    if (!reply.isError()) {
        mPriv->info = Contact::InfoFields(reply.value());
        debug() << "Got reply to ContactInfo.RequestContactInfo";
        setFinished();
    } else {
        debug().nospace() <<
            "ContactInfo.RequestContactInfo failed: " <<
            reply.error().name() << ": " << reply.error().message();
        setFinishedWithError(reply.error());
    }

    watcher->deleteLater();
}
void PendingStreamTubeConnection::onAcceptFinished(PendingOperation *op)
{
    if (isFinished()) {
        return;
    }

    if (op->isError()) {
        warning().nospace() << "StreamTube.Accept failed with " <<
            op->errorName() << ": " << op->errorMessage();
        setFinishedWithError(op->errorName(), op->errorMessage());
        return;
    }

    debug() << "StreamTube.Accept returned successfully";

    PendingVariant *pv = qobject_cast<PendingVariant *>(op);
    // Build the address
    if (mPriv->type == SocketAddressTypeIPv4) {
        SocketAddressIPv4 addr = qdbus_cast<SocketAddressIPv4>(pv->result());
        debug().nospace() << "Got address " << addr.address << ":" << addr.port;
        mPriv->hostAddress = QHostAddress(addr.address);
        mPriv->port = addr.port;
    } else if (mPriv->type == SocketAddressTypeIPv6) {
        SocketAddressIPv6 addr = qdbus_cast<SocketAddressIPv6>(pv->result());
        debug().nospace() << "Got address " << addr.address << ":" << addr.port;
        mPriv->hostAddress = QHostAddress(addr.address);
        mPriv->port = addr.port;
    } else {
        // Unix socket
        mPriv->socketPath = QLatin1String(qdbus_cast<QByteArray>(pv->result()));
        debug() << "Got socket " << mPriv->socketPath;
    }

    // It might have been already opened - check
    if (mPriv->tube->state() == TubeChannelStateOpen) {
        onTubeStateChanged(mPriv->tube->state());
    } else {
        // Wait until the tube gets opened on the other side
        connect(mPriv->tube.data(), SIGNAL(stateChanged(Tp::TubeChannelState)),
                this, SLOT(onTubeStateChanged(Tp::TubeChannelState)));
    }
}
void PendingStreamTubeConnection::onTubeStateChanged(TubeChannelState state)
{
    debug() << "Tube state changed to " << state;
    if (state == TubeChannelStateOpen) {
        // The tube is ready, populate its properties
        if (mPriv->type == SocketAddressTypeIPv4 || mPriv->type == SocketAddressTypeIPv6) {
            mPriv->tube->setIpAddress(qMakePair<QHostAddress, quint16>(mPriv->hostAddress,
                    mPriv->port));
        } else {
            // Unix socket
            mPriv->tube->setLocalAddress(mPriv->socketPath);
        }

        // Mark the operation as finished
        setFinished();
    } else if (state != TubeChannelStateLocalPending) {
        // Something happened
        setFinishedWithError(QLatin1String("Connection refused"),
                QLatin1String("The connection to this tube was refused"));
    }
}
void XTelepathyPasswordAuthOperation::onSASLStatusChanged(uint status, const QString &reason,
        const QVariantMap &details)
{
    if (status == Tp::SASLStatusNotStarted) {
        qDebug() << "Requesting password";
        // if we have non-null id AND if the last attempt didn't fail,
        // proceed with the credentials receieved from the SSO;
        // otherwise prompt the user
        if (!m_lastLoginFailedConfig.hasKey(m_account->objectPath())) {
            GetCredentialsJob *credentialsJob = new GetCredentialsJob(m_accountStorageId, QStringLiteral("password"), QStringLiteral("password"), this);
            connect(credentialsJob, &GetCredentialsJob::finished, [this](KJob *job){
                if (job->error()) {
                    qWarning() << "Credentials job error:" << job->errorText();
                    qDebug() << "Prompting for password";
                    promptUser();
                } else {
                    m_canFinish = true;
                    QByteArray secret = qobject_cast<GetCredentialsJob*>(job)->credentialsData().value("Secret").toByteArray();
                    m_saslIface->StartMechanismWithData(QLatin1String("X-TELEPATHY-PASSWORD"), secret);
                }
            });
            credentialsJob->start();
        } else {
            promptUser();
        }
    } else if (status == Tp::SASLStatusServerSucceeded) {
        qDebug() << "Authentication handshake";
        m_saslIface->AcceptSASL();
    } else if (status == Tp::SASLStatusSucceeded) {
        qDebug() << "Authentication succeeded";
        if (m_lastLoginFailedConfig.hasKey(m_account->objectPath())) {
            m_lastLoginFailedConfig.deleteEntry(m_account->objectPath());
        }
        if (m_canFinish) {
            // if the credentials storage has finished, just finish
            setFinished();
        } else {
            // ...otherwise set this to true and it will finish
            // when credentials are finished
            m_canFinish = true;
        }
    } else if (status == Tp::SASLStatusInProgress) {
        qDebug() << "Authenticating...";
    } else if (status == Tp::SASLStatusServerFailed) {
        qDebug() << "Error authenticating - reason:" << reason << "- details:" << details;

        if (m_canTryAgain) {
            qDebug() << "Retrying...";
            promptUser();
        } else {
            qWarning() << "Authentication failed and cannot try again";
            m_lastLoginFailedConfig.writeEntry(m_account->objectPath(), "1");

            // We cannot try again, but we can request again to set the account
            // online. A new channel will be created, but since we set the
            // lastLoginFailed entry, next time we will prompt for password
            // and the user won't see any difference except for an
            // authentication error notification
            Tp::Presence requestedPresence = m_account->requestedPresence();
            m_account->setRequestedPresence(requestedPresence);
            QString errorMessage = details[QLatin1String("server-message")].toString();
            setFinishedWithError(reason, errorMessage.isEmpty() ? i18n("Authentication error") : errorMessage);
        }
    }
}
Example #17
0
void PendingOperation::onPreviousFailed(PendingOperation *operation, const QVariantHash &details)
{
    Q_UNUSED(operation)
    setFinishedWithError(details);
}
/**
 * Construct a new PendingConnection object that will fail immediately.
 *
 * \param error Name of the error to fail with.
 * \param errorMessage Detail message for the error.
 */
PendingConnection::PendingConnection(const QString &error, const QString &errorMessage)
    : PendingOperation(ConnectionManagerPtr()),
      mPriv(new Private)
{
    setFinishedWithError(error, errorMessage);
}