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; }
/** * 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; }