From 7e517f4ebea63982e17d61ac432dce01fbf1bea2 Mon Sep 17 00:00:00 2001 From: Alexander Kanavin Date: Tue, 16 Jul 2013 19:59:56 +0300 Subject: [PATCH] examples: initial commit --- .gitignore | 1 + Makefile.am | 2 +- configure.ac | 1 + examples/Makefile.am | 11 ++ examples/gsso-example.c | 402 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 416 insertions(+), 1 deletion(-) create mode 100644 examples/Makefile.am create mode 100644 examples/gsso-example.c diff --git a/.gitignore b/.gitignore index 4b0b3f3..3a8c66f 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ config.* /docs/reference/version.xml /docs/reference/xml/ gtk-doc.make +examples/gsso-example /INSTALL /libgsignon-glib/signon-errors-map.c /libgsignon-glib/signon-marshal.c diff --git a/Makefile.am b/Makefile.am index 5fdae8f..1df8c31 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ ACLOCAL_AMFLAGS = -I m4 AM_DISTCHECK_CONFIGURE_FLAGS = \ --enable-gtk-doc \ --enable-introspection=yes -SUBDIRS = libgsignon-glib docs +SUBDIRS = libgsignon-glib docs examples if ENABLE_PYTHON SUBDIRS += pygobject diff --git a/configure.ac b/configure.ac index ba01cbd..bce7ccb 100644 --- a/configure.ac +++ b/configure.ac @@ -143,5 +143,6 @@ AC_CONFIG_FILES([ docs/reference/version.xml tests/Makefile pygobject/Makefile + examples/Makefile ]) AC_OUTPUT diff --git a/examples/Makefile.am b/examples/Makefile.am new file mode 100644 index 0000000..f8aac6b --- /dev/null +++ b/examples/Makefile.am @@ -0,0 +1,11 @@ +## Process this file with automake to produce Makefile.in + +bin_PROGRAMS = gsso-example + +gsso_example_SOURCES = gsso-example.c +gsso_example_CPPFLAGS = \ + -I$(top_srcdir) \ + $(DEPS_CFLAGS) +gsso_example_LDADD = \ + $(DEPS_LIBS) \ + $(top_builddir)/libgsignon-glib/libgsignon-glib.la diff --git a/examples/gsso-example.c b/examples/gsso-example.c new file mode 100644 index 0000000..458c12e --- /dev/null +++ b/examples/gsso-example.c @@ -0,0 +1,402 @@ +/* + * Copyright (C) 2013 Intel Corporation. + * + * Contact: Alexander Kanavin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include +#include +#include "libgsignon-glib/signon-auth-service.h" +#include "libgsignon-glib/signon-identity.h" + +static void +signon_query_methods_cb (SignonAuthService *auth_service, gchar **methods, + GError *error, gpointer user_data) +{ + if (error) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_main_loop_quit (user_data); + return; + } + + gchar **pmethods = methods; + + g_print("Available authentication methods:\n"); + while (*pmethods) + { + g_print("\t%s\n", *pmethods); + pmethods++; + } + if (methods) g_strfreev (methods); + g_main_loop_quit (user_data); +} + +static void query_auth_methods(GMainLoop* main_loop) +{ + SignonAuthService* auth_service = signon_auth_service_new(); + + signon_auth_service_query_methods (auth_service, + (SignonQueryMethodsCb)signon_query_methods_cb, main_loop); + g_main_loop_run(main_loop); + + g_object_unref(auth_service); +} + +static void +signon_query_mechanisms_cb (SignonAuthService *auth_service, gchar *method, + gchar **mechanisms, GError *error, gpointer user_data) +{ + if (error) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_main_loop_quit (user_data); + return; + } + + gchar **pmechanisms = mechanisms; + + g_print("Available authentication mechanisms for method %s:\n", method); + while (*pmechanisms) + { + g_print("\t%s\n", *pmechanisms); + pmechanisms++; + } + if (mechanisms) g_strfreev (mechanisms); + g_main_loop_quit (user_data); +} + +static void query_auth_mechanisms(GMainLoop* main_loop, const gchar* method) +{ + SignonAuthService* auth_service = signon_auth_service_new(); + + signon_auth_service_query_mechanisms (auth_service, method, + (SignonQueryMechanismCb)signon_query_mechanisms_cb, + main_loop); + g_main_loop_run(main_loop); + + g_object_unref(auth_service); +} + +static void signon_query_identities_cb (SignonAuthService *auth_service, + SignonIdentityList *identity_list, const GError *error, gpointer user_data) +{ + GList *iter = identity_list; + + if (error) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_main_loop_quit (user_data); + return; + } + + g_print("Available identities:\n"); + while (iter) + { + SignonIdentityInfo *info = (SignonIdentityInfo *) iter->data; + const gchar *caption = signon_identity_info_get_caption (info); + + g_print ("\tid=%d caption='%s'\n", + signon_identity_info_get_id (info), + signon_identity_info_get_caption (info)); + + iter = g_list_next (iter); + } + g_list_free_full (identity_list, (GDestroyNotify)signon_identity_info_free); + + g_main_loop_quit (user_data); +} + +static void query_auth_identities(GMainLoop* main_loop) +{ + SignonAuthService* auth_service = signon_auth_service_new(); + + signon_auth_service_query_identities (auth_service, NULL, NULL, + (SignonQueryIdentitiesCb)signon_query_identities_cb, main_loop); + g_main_loop_run(main_loop); + + g_object_unref(auth_service); +} + +static void signon_store_identity_cb(SignonIdentity *self, + guint32 id, + const GError *error, + gpointer user_data) +{ + if (error) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_main_loop_quit (user_data); + return; + } + + g_print("Identity stored with id %d\n", id); + g_main_loop_quit (user_data); +} + +static void create_auth_identity(GMainLoop* main_loop, const gchar* identity_caption, + const gchar* identity_method) +{ + const gchar* all_mechanisms[] = { "*", NULL }; + + SignonIdentity* identity = signon_identity_new(NULL); + SignonIdentityInfo* identity_info = signon_identity_info_new(); + signon_identity_info_set_caption(identity_info, identity_caption); + signon_identity_info_set_method(identity_info, identity_method, all_mechanisms); + if (g_strcmp0(identity_method, "password") == 0) + signon_identity_info_set_secret(identity_info, NULL, TRUE); + + signon_identity_store_credentials_with_info (identity, identity_info, + (SignonIdentityStoreCredentialsCb)signon_store_identity_cb, + main_loop); + g_main_loop_run(main_loop); + + g_object_unref(identity); + signon_identity_info_free(identity_info); +} + +static void signon_remove_identity_cb(SignonIdentity *self, + const GError *error, + gpointer user_data) +{ + if (error) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_main_loop_quit (user_data); + return; + } + + g_print("Identity removed\n"); + g_main_loop_quit (user_data); +} + + +static void remove_auth_identity(GMainLoop* main_loop, gint identity_id) +{ + SignonIdentity* identity = signon_identity_new_from_db(identity_id, NULL); + signon_identity_remove (identity, + (SignonIdentityRemovedCb)signon_remove_identity_cb, + main_loop); + g_main_loop_run(main_loop); + + g_object_unref(identity); +} + +static void auth_session_process_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + g_debug("%s", G_STRFUNC); + SignonAuthSession *auth_session = SIGNON_AUTH_SESSION (source_object); + GVariant *v_reply; + char *str_reply = NULL; + GError *error = NULL; + + v_reply = signon_auth_session_process_finish (auth_session, res, &error); + if (error) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_error_free(error); + g_main_loop_quit (user_data); + return; + } + + str_reply = g_variant_print (v_reply, TRUE); + g_print("Got response: %s\n", str_reply); + g_free (str_reply); + g_variant_unref(v_reply); + + g_main_loop_quit (user_data); +} + + +static void get_google_token(GMainLoop* main_loop, gint identity_id, + const gchar* client_id, + const gchar* client_secret) +{ + if (!client_id || !client_secret) { + g_print("Must provide a client ID and secret (get them at https://code.google.com/apis/console/ )\n"); + exit(1); + } + + SignonIdentity* identity = signon_identity_new_from_db(identity_id, NULL); + SignonAuthSession* session = signon_identity_create_session(identity, "oauth", NULL); + + GVariantBuilder builder; + GVariant* session_data; + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&builder, "{sv}", + "ClientId", g_variant_new_string (client_id)); + g_variant_builder_add (&builder, "{sv}", + "ClientSecret", g_variant_new_string (client_secret)); + g_variant_builder_add (&builder, "{sv}", + "UiPolicy", g_variant_new_uint32 (SIGNON_POLICY_DEFAULT)); + g_variant_builder_add (&builder, "{sv}", + "ResponseType", g_variant_new_string ("code")); + g_variant_builder_add (&builder, "{sv}", + "AuthHost", g_variant_new_string ("accounts.google.com")); + g_variant_builder_add (&builder, "{sv}", + "AuthPath", g_variant_new_string ("/o/oauth2/auth")); + g_variant_builder_add (&builder, "{sv}", + "RedirectUri", g_variant_new_string("https://localhost")); + g_variant_builder_add (&builder, "{sv}", + "Scope", g_variant_new_string ("email")); + g_variant_builder_add (&builder, "{sv}", + "ForceClientAuthViaRequestBody", g_variant_new_boolean(TRUE)); + g_variant_builder_add (&builder, "{sv}", + "TokenHost", g_variant_new_string("accounts.google.com")); + g_variant_builder_add (&builder, "{sv}", + "TokenPath", g_variant_new_string("/o/oauth2/token")); + session_data = g_variant_builder_end (&builder); + + signon_auth_session_process_async (session, + session_data, + "oauth2", + NULL, + auth_session_process_cb, + main_loop); + + g_print("Geting token\n"); + g_main_loop_run (main_loop); + + g_object_unref(session); + g_object_unref(identity); +} + +static void get_password(GMainLoop* main_loop, gint identity_id) +{ + SignonIdentity* identity = signon_identity_new_from_db(identity_id, NULL); + SignonAuthSession* session = signon_identity_create_session(identity, "password", NULL); + + GVariantBuilder builder; + GVariant* session_data; + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + session_data = g_variant_builder_end (&builder); + + signon_auth_session_process_async (session, + session_data, + "password", + NULL, + auth_session_process_cb, + main_loop); + + g_print("Geting password\n"); + g_main_loop_run (main_loop); + + g_object_unref(session); + g_object_unref(identity); +} + +int +main (int argc, char *argv[]) +{ + + GError *error = NULL; + GOptionContext *context; + GMainLoop* main_loop = NULL; + + gboolean query_methods = FALSE; + gchar* query_mechanisms_method = NULL; + gboolean query_identities = FALSE; + gchar* create_identity_caption = NULL; + gchar* create_identity_method = NULL; + gint remove_identity_id = 0; + + GOptionEntry main_entries[] = + { + { "query-methods", 0, 0, G_OPTION_ARG_NONE, &query_methods, "Query available authentication methods", NULL}, + { "query-mechanisms", 0, 0, G_OPTION_ARG_STRING, &query_mechanisms_method, "Query available mechanisms for an authentication method", "method"}, + { "query-identities", 0, 0, G_OPTION_ARG_NONE, &query_identities, "Query available authentication identities", NULL}, + { "create-identity", 0, 0, G_OPTION_ARG_STRING, &create_identity_caption, "Create a new authentication identity", "caption"}, + { "identity-method", 0, 0, G_OPTION_ARG_STRING, &create_identity_method, "Method to use when creating identity", "method"}, + { "remove-identity", 0, 0, G_OPTION_ARG_INT, &remove_identity_id, "Remove an authentication identity", "id"}, + { NULL } + }; + + gchar* client_id = NULL; + gchar* client_secret = NULL; + gint google_identity_id = 0; + + GOptionEntry oauth_entries[] = + { + { "get-google-token", 0, 0, G_OPTION_ARG_INT, &google_identity_id, "Get an OAuth2 access token from Google", "identity-id"}, + { "client-id", 0, 0, G_OPTION_ARG_STRING, &client_id, "Client ID", "id" }, + { "client-secret", 0, 0, G_OPTION_ARG_STRING, &client_secret, "Client secret", "secret" }, + { NULL } + }; + + gint password_identity_id = 0; + + GOptionEntry password_entries[] = + { + { "get-password", 0, 0, G_OPTION_ARG_INT, &password_identity_id, "Get an identity's username and password using 'password' plugin", "identity-id"}, + { NULL } + }; + + +#if !GLIB_CHECK_VERSION (2, 36, 0) + g_type_init (); +#endif + + context = g_option_context_new ("- gSSO application example"); + g_option_context_add_main_entries (context, main_entries, NULL); + GOptionGroup* oauth_group = g_option_group_new("oauth", "OAuth-specific options", "OAuth-specific options", NULL, NULL); + g_option_group_add_entries(oauth_group, oauth_entries); + g_option_context_add_group (context, oauth_group); + + GOptionGroup* password_group = g_option_group_new("password", "Password-specific options", "Password-specific options", NULL, NULL); + g_option_group_add_entries(password_group, password_entries); + g_option_context_add_group (context, password_group); + + if (!g_option_context_parse (context, &argc, &argv, &error)) { + g_print ("option parsing failed: %s\n", error->message); + g_option_context_free(context); + exit (1); + } + g_option_context_free(context); + + main_loop = g_main_loop_new(NULL, FALSE); + + if (query_methods) { + query_auth_methods(main_loop); + } else if (query_mechanisms_method) { + query_auth_mechanisms(main_loop, query_mechanisms_method); + } else if (query_identities) { + query_auth_identities(main_loop); + } else if (create_identity_caption) { + create_auth_identity(main_loop, create_identity_caption, create_identity_method); + } else if (remove_identity_id > 0) { + remove_auth_identity(main_loop, remove_identity_id); + } else if (google_identity_id > 0) { + get_google_token(main_loop, google_identity_id, client_id, client_secret); + } else if (password_identity_id > 0) { + get_password(main_loop, password_identity_id); + } + + g_main_loop_unref(main_loop); + if (client_id) + g_free (client_id); + if (client_secret) + g_free(client_secret); + if (query_mechanisms_method) + g_free(query_mechanisms_method); + if (create_identity_caption) + g_free(create_identity_caption); + if (create_identity_caption) + g_free(create_identity_method); +} -- 2.7.4