void XTelepathyPasswordAuthOperation::storeCredentials(const QString &secret)
{
    QString username = m_account->parameters().value(QStringLiteral("account")).toString();
    Accounts::Manager *manager = KAccounts::accountsManager();
    Accounts::Account *account = manager->account(m_accountStorageId);
    SignOn::Identity *identity;

    if (account) {
        Accounts::AccountService *service = new Accounts::AccountService(account, manager->service(QString()), this);
        Accounts::AuthData authData = service->authData();
        identity = SignOn::Identity::existingIdentity(authData.credentialsId(), this);
    } else {
        // there's no valid KAccounts account, so let's try creating one
        QString providerName = QStringLiteral("ktp-");

        providerName.append(m_account->serviceName());

        qDebug() << "Creating account with providerName" << providerName;

        account = manager->createAccount(providerName);
        account->setDisplayName(m_account->displayName());
        account->setValue("uid", m_account->objectPath());
        account->setValue("username", username);
        account->setValue(QStringLiteral("auth/mechanism"), QStringLiteral("password"));
        account->setValue(QStringLiteral("auth/method"), QStringLiteral("password"));

        account->setEnabled(true);

        Accounts::ServiceList services = account->services();
        Q_FOREACH(const Accounts::Service &service, services) {
            account->selectService(service);
            account->setEnabled(true);
        }
    }
/*!
 * \qmlmethod void AccountService::authenticate(jsobject sessionData)
 *
 * Perform the authentication on this account. The \a sessionData dictionary is
 * optional and if not given the value of \l {authData}{authData::parameters} will be used.
 *
 * Each call to this method will cause either of \l authenticated or
 * \l authenticationError signals to be emitted at some time later. Note that
 * the authentication might involve interactions with the network or with the
 * end-user, so don't expect these signals to be emitted immediately.
 *
 * \sa authenticated, authenticationError
 */
void AccountService::authenticate(const QVariantMap &sessionData)
{
    DEBUG() << sessionData;
    if (Q_UNLIKELY(accountService == 0)) {
        QVariantMap error;
        error.insert("code", NoAccountError);
        error.insert("message", QLatin1String("Invalid AccountService"));
        Q_EMIT authenticationError(error);
        return;
    }

    Accounts::AuthData authData = accountService->authData();
    if (identity == 0) {
        quint32 credentialsId = credentialsIdProperty.read().toUInt();
        if (credentialsId == 0)
            credentialsId = authData.credentialsId();
        identity =
            SignOn::Identity::existingIdentity(credentialsId, this);
    }
    if (authSession == 0) {
        authSession = identity->createSession(authData.method());
        QObject::connect(authSession, SIGNAL(response(const SignOn::SessionData&)),
                         this,
                         SLOT(onAuthSessionResponse(const SignOn::SessionData&)));
        QObject::connect(authSession, SIGNAL(error(const SignOn::Error&)),
                         this, SLOT(onAuthSessionError(const SignOn::Error&)));
    }
void GetCredentialsJob::Private::getCredentials()
{
    Accounts::Account *acc = manager->account(id);
    if (!acc) {
        qWarning() << "Unable to find account for id" << id;
        if (repeatedTries < 3) {
            qDebug() << "Retrying in 2s";
            QTimer::singleShot(2000, q, SLOT(getCredentials()));
            repeatedTries++;
        } else {
            qDebug() << repeatedTries << "ending with error";
            q->setError(KJob::UserDefinedError);
            q->setErrorText(QLatin1String("Could not find account"));
            q->emitResult();
        }
        return;
    }

    Accounts::AccountService *service = new Accounts::AccountService(acc, manager->service(serviceType), q);

    Accounts::AuthData serviceAuthData = service->authData();
    authData = serviceAuthData.parameters();
    SignOn::Identity *identity = SignOn::Identity::existingIdentity(acc->credentialsId(), q);

    if (!identity) {
        qWarning() << "Unable to find identity for account id" << id;
        q->setError(KJob::UserDefinedError);
        q->setErrorText(QLatin1String("Could not find credentials"));
        q->emitResult();
        return;
    }

    authData["AccountUsername"] = acc->value(QLatin1String("username")).toString();
    QPointer<SignOn::AuthSession> authSession = identity->createSession(authMethod.isEmpty() ? serviceAuthData.method() : authMethod);
    if (!authSession) {
        qWarning() << "Unable to create auth session for" << authMethod << serviceAuthData.method();
        q->setError(KJob::UserDefinedError);
        q->setErrorText(QLatin1String("Could not create auth session"));
        q->emitResult();
        return;
    }

    QObject::connect(authSession.data(), &SignOn::AuthSession::response,
    [this, identity](const SignOn::SessionData &data) {
        sessionData = data;
        q->emitResult();
    });

    QObject::connect(authSession.data(), &SignOn::AuthSession::error,
    [this](const SignOn::Error &error) {
        qDebug() << error.message();
        q->setError(KJob::UserDefinedError);
        q->setErrorText(error.message());
        q->emitResult();
    });

    authSession->process(serviceAuthData.parameters(), authMechanism.isEmpty() ? serviceAuthData.mechanism() : authMechanism);
}
/*!
 * \qmlproperty jsobject AccountService::authData
 * An object providing information about the authentication.
 * The returned object will have at least these members:
 * \list
 * \li \c method is the authentication method
 * \li \c mechanism is the authentication mechanism (a sub-specification of the
 *     method)
 * \li \c parameters is a dictionary of authentication parameters
 * \li \c credentialsId is the numeric identified of the credentials in the
 * secrets storage. See the \l Credentials element for more info.
 * \endlist
 */
QVariantMap AccountService::authData() const
{
    QVariantMap map;
    if (Q_UNLIKELY(accountService == 0)) return map;

    Accounts::AuthData data = accountService->authData();
    map.insert("method", data.method());
    map.insert("mechanism", data.mechanism());
    map.insert("credentialsId", data.credentialsId());
    map.insert("parameters", data.parameters());
    return map;
}
void CreateAccount::info(const SignOn::IdentityInfo &info)
{
    qDebug() << "Info:";
    qDebug() << "\tId:" << info.id();
    qDebug() << "\tcaption:" << info.caption();
    qDebug() << "\towner:" << info.owner();
    qDebug() << "\tuserName:"******"username", info.userName());
    m_account->setCredentialsId(info.id());

    Accounts::AuthData authData = m_accInfo->authData();
    m_account->setValue("auth/mechanism", authData.mechanism());
    m_account->setValue("auth/method", authData.method());

    QString base("auth/");
    base.append(authData.method());
    base.append("/");
    base.append(authData.mechanism());
    base.append("/");

    QVariantMap data = authData.parameters();
    QMapIterator<QString, QVariant> i(data);
    while (i.hasNext()) {
        i.next();
        m_account->setValue(base + i.key(), i.value());
    }


    Accounts::ServiceList services = m_account->services();
    Q_FOREACH(const Accounts::Service &service, services) {
        m_account->selectService(service);
        m_account->setEnabled(m_disabledServices.contains(service.name()) ? false : true);
    }