virtual std::string getOAuth2Bearer(const PasswordUpdateCallback &passwordUpdateCallback)
    {
        SE_LOG_DEBUG(NULL, "retrieving OAuth2 token");

        if (!m_accessToken.empty() && !m_invalidateCache) {
            return m_accessToken;
        }

        // Retry login if even the refreshed token failed.
        g_hash_table_insert(m_sessionData, g_strdup("ForceTokenRefresh"),
                            g_variant_ref_sink(g_variant_new_boolean(m_invalidateCache)));

        // We get assigned a plain pointer to an instance that we'll own,
        // so we have to use the "steal" variant to enable that assignment.
        GVariantStealCXX resultDataVar;
        GErrorCXX gerror;
        GVariantCXX sessionDataVar(HashTable2Variant(m_sessionData));
        PlainGStr buffer(g_variant_print(sessionDataVar, true));
        SE_LOG_DEBUG(NULL, "asking for OAuth2 token with method %s, mechanism %s and parameters %s",
                     signon_auth_session_get_method(m_authSession),
                     m_mechanism.c_str(),
                     buffer.get());

#define signon_auth_session_process_async_finish signon_auth_session_process_finish
        SYNCEVO_GLIB_CALL_SYNC(resultDataVar, gerror, signon_auth_session_process_async,
                               m_authSession, sessionDataVar, m_mechanism.c_str(), NULL);
        buffer.reset(resultDataVar ? g_variant_print(resultDataVar, true) : NULL);
        SE_LOG_DEBUG(NULL, "OAuth2 token result: %s, %s",
                     buffer.get() ? buffer.get() : "<<null>>",
                     gerror ? gerror->message : "???");
        if (!resultDataVar || gerror) {
            SE_THROW_EXCEPTION_STATUS(StatusException,
                                      StringPrintf("could not obtain OAuth2 token: %s", gerror ? gerror->message : "???"),
                                      STATUS_FORBIDDEN);
        }
        GHashTableCXX resultData(Variant2HashTable(resultDataVar));
        GVariant *tokenVar = static_cast<GVariant *>(g_hash_table_lookup(resultData, (gpointer)"AccessToken"));
        if (!tokenVar) {
            SE_THROW("no AccessToken in OAuth2 response");
        }
        std::string newToken = g_variant_get_string(tokenVar, NULL);
        if (newToken.empty()) {
            SE_THROW("AccessToken did not contain a string value");
        } else if (m_invalidateCache && newToken == m_accessToken) {
            SE_THROW("Got the same invalid AccessToken");
        }
        m_accessToken = newToken;
        return m_accessToken;
    }
예제 #2
0
/**
 * signon_identity_create_session:
 * @self: the #SignonIdentity.
 * @method: method.
 * @error: pointer to a location which will receive the error, if any.
 *
 * Creates an authentication session for this identity.
 *
 * Returns: (transfer full): a new #SignonAuthSession.
 */
SignonAuthSession *
signon_identity_create_session(SignonIdentity *self,
                               const gchar *method,
                               GError **error)
{
    g_return_val_if_fail (SIGNON_IS_IDENTITY (self), NULL);

    SignonIdentityPrivate *priv = self->priv;
    g_return_val_if_fail (priv != NULL, NULL);

    DEBUG ("%s %d", G_STRFUNC, __LINE__);

    if (method == NULL)
    {
        DEBUG ("NULL method as input. Aborting.");
        g_set_error(error,
                    signon_error_quark(),
                    SIGNON_ERROR_UNKNOWN,
                    "NULL input method.");
        return NULL;
    }

    GSList *list = priv->sessions;
    while (list)
    {
        SignonAuthSession *session = SIGNON_AUTH_SESSION (priv->sessions->data);
        const gchar *sessionMethod = signon_auth_session_get_method (session);
        if (g_strcmp0(sessionMethod, method) == 0)
        {
            DEBUG ("Auth Session with method `%s` already created.", method);
            g_set_error (error,
                         signon_error_quark(),
                         SIGNON_ERROR_METHOD_NOT_AVAILABLE,
                         "Authentication session for this method already requested.");
            return NULL;
        }

        list = list->next;
    }

    SignonAuthSession *session = signon_auth_session_new (priv->id,
                                                          method,
                                                          error);
    if (session)
    {
        DEBUG ("%s %d", G_STRFUNC, __LINE__);
        priv->sessions = g_slist_append(priv->sessions, session);
        g_object_weak_ref (G_OBJECT(session),
                           identity_session_object_destroyed_cb,
                           self);
        /*
         * if you want to delete the identity
         * you MUST delete all authsessions
         * first
         * */
        g_object_ref (self);
        priv->signed_out = FALSE;
    }

    return session;
}