build-aux
*dbus*gen*
src/daemon/gsignond
+test/db/testdb
+test/passwordplugin/passwordplugintest
stamp-h1
*service
AC_SUBST(GSIGNOND_CFLAGS)
AC_SUBST(GSIGNOND_LIBS)
+# AM_PATH_CHECK() is deprecated, but check documentation fails to tell that :-/
+PKG_CHECK_MODULES([CHECK], [check >= 0.9.4], [have_check=yes], [have_check=no])
+AC_SUBST(CHECK_CFLAGS)
+AC_SUBST(CHECK_LIBS)
+
DBUS_SERVICES_DIR="`pkg-config --variable session_bus_services_dir dbus-1`"
AC_SUBST(DBUS_SERVICES_DIR)
DBUS_INTERFACES_DIR="`pkg-config --variable interfaces_dir dbus-1`"
src/plugins/password/Makefile
test/Makefile
test/db/Makefile
+test/passwordplugin/Makefile
])
--- /dev/null
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of gsignond
+ *
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Contact: Alexander Kanavin <alex.kanavin@gmail.com>
+ *
+ * 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
+ */
+
+#ifndef __GSIGNOND_DICTIONARY_H__
+#define __GSIGNOND_DICTIONARY_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GSIGNOND_TYPE_DICTIONARY (G_TYPE_HASH_TABLE)
+
+#define GSIGNOND_DICTIONARY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GSIGNOND_TYPE_DICTIONARY, \
+ GSignondDictionary))
+#define GSIGNOND_IS_DICTIONARY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+ GSIGNOND_TYPE_DICTIONARY))
+
+typedef GHashTable GSignondDictionary;
+
+GType
+gsignond_dictionary_get_type (void);
+
+GSignondDictionary *
+gsignond_dictionary_new (void);
+
+void
+gsignond_dictionary_free (GSignondDictionary *dict);
+
+GSignondDictionary *
+gsignond_dictionary_copy (GSignondDictionary *other);
+
+GSignondDictionary *
+gsignond_dictionary_new_from_variant (GVariant *variant);
+
+GVariant *
+gsignond_dictionary_to_variant (GSignondDictionary *self);
+
+GVariant *
+gsignond_dictionary_get (GSignondDictionary *dict, gchar *key);
+
+void
+gsignond_dictionary_set (GSignondDictionary *dict,
+ gchar *key, GVariant *value);
+
+G_END_DECLS
+
+#endif /* __GSIGNOND_DICTIONARY_H__ */
G_BEGIN_DECLS
-#define G_LOG_DOMAIN "gsignond"
+#define GSIGNOND_ERROR_DOMAIN "gsignond"
/**
* GSIGNOND_ERROR:
typedef enum {
GSIGNOND_ERROR_NONE,
- /* Add error codes */
+
+ GSIGNOND_ERROR_UNKNOWN = 1, /**< Catch-all for errors not distinguished
+ by another code. */
+ GSIGNOND_ERROR_INTERNAL_SERVER = 2, /**< Signon Daemon internal error. */
+ GSIGNOND_ERROR_INTERNAL_COMMUNICATION = 3, /**< Communication with Signon Daemon
+ error. */
+ GSIGNOND_ERROR_PERMISSION_DENIED = 4, /**< The operation cannot be performed due to
+ insufficient client permissions. */
+ GSIGNOND_ERROR_ENCRYPTION_FAILURE, /**< Failure during data
+ encryption/decryption. */
+ GSIGNOND_ERROR_AUTH_SERVICE_ERR = 100, /* Placeholder to rearrange enumeration
+ - AuthService specific */
+ GSIGNOND_ERROR_METHOD_NOT_KNOWN, /**< The method with this name is not
+ found. */
+ GSIGNOND_ERROR_SERVICE_NOT_AVAILABLE, /**< The service is temporarily
+ unavailable. */
+ GSIGNOND_ERROR_INVALID_QUERY, /**< Parameters for the query are invalid. */
+ GSIGNOND_ERROR_IDENTITY_ERR = 200, /* Placeholder to rearrange enumeration
+ - Identity specific */
+ GSIGNOND_ERROR_METHOD_NOT_AVAILABLE, /**< The requested method is not available. */
+ GSIGNOND_ERROR_IDENTITY_NOT_FOUND, /**< The identity matching this Identity
+ object was not found on the service. */
+ GSIGNOND_ERROR_STORE_FAILED, /**< Storing credentials failed. */
+ GSIGNOND_ERROR_REMOVE_FAILED, /**< Removing credentials failed. */
+ GSIGNOND_ERROR_SIGN_OUT_FAILED, /**< SignOut failed. */
+ GSIGNOND_ERROR_IDENTITY_OPERATION_CANCELED, /**< Identity operation was canceled by
+ user. */
+ GSIGNOND_ERROR_CREDENTIALS_NOT_AVAILABLE, /**< Query failed. */
+ GSIGNOND_ERROR_REFERENCE_NOT_FOUND, /**< Trying to remove nonexistent
+ reference. */
+ GSIGNOND_ERROR_AUTH_SESSION_ERR = 300, /* Placeholder to rearrange enumeration
+ - AuthSession/AuthPluginInterface
+ specific */
+ GSIGNOND_ERROR_MECHANISM_NOT_AVAILABLE, /**< The requested mechanism is not
+ available. */
+ GSIGNOND_ERROR_MISSING_DATA, /**< The SessionData object does not contain
+ necessary information. */
+ GSIGNOND_ERROR_INVALID_CREDENTIALS, /**< The supplied credentials are invalid for
+ the mechanism implementation. */
+ GSIGNOND_ERROR_NOT_AUTHORIZED, /**< Authorization failed. */
+ GSIGNOND_ERROR_WRONG_STATE, /**< An operation method has been called in
+ a wrong state. */
+ GSIGNOND_ERROR_OPERATION_NOT_SUPPORTED, /**< The operation is not supported by the
+ mechanism implementation. */
+ GSIGNOND_ERROR_NO_CONNECTION, /**< No Network connetion. */
+ GSIGNOND_ERROR_NETWORK, /**< Network connetion failed. */
+ GSIGNOND_ERROR_SSL, /**< Ssl connection failed. */
+ GSIGNOND_ERROR_RUNTIME, /**< Casting SessionData into subclass
+ failed */
+ GSIGNOND_ERROR_SESSION_CANCELED, /**< Challenge was cancelled. */
+ GSIGNOND_ERROR_TIMED_OUT, /**< Challenge was timed out. */
+ GSIGNOND_ERROR_USER_INTERACTION, /**< User interaction dialog failed */
+ GSIGNOND_ERROR_OPERATION_FAILED, /**< Temporary failure in authentication. */
+ GSIGNOND_ERROR_ENCRYPTION_FAILED, /**< @deprecated Failure during data
+ encryption/decryption. */
+ GSIGNOND_ERROR_TOS_NOT_ACCEPTED, /**< User declined Terms of Service. */
+ GSIGNOND_ERROR_FORGOT_PASSWORD, /**< User requested reset password
+ sequence. */
+ GSIGNOND_ERROR_METHOD_OR_MECHANISM_NOT_ALLOWED, /**< Method or mechanism not allowed for
+ this identity. */
+ GSIGNOND_ERROR_INCORRECT_DATE, /**< Date time incorrect on device. */
+ GSIGNOND_ERROR_USER_ERR = 400 /* Placeholder to rearrange enumeration
+ - User space specific */
+
} GSignondError;
#define gsignond_gerr(error, handler) \
#include <glib.h>
#include <glib-object.h>
+#include <gsignond/gsignond-session-data.h>
G_BEGIN_DECLS
-#define GSIGNOND_TYPE_PLUGIN (gsignond_plugin_get_type ())
-#define GSIGNOND_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSIGNOND_TYPE_PLUGIN, GSignondPlugin))
-#define GSIGNOND_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSIGNOND_TYPE_PLUGIN))
-#define GSIGNOND_PLUGIN_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GSIGNOND_TYPE_PLUGIN, GSignondPluginInterface))
+#define GSIGNOND_TYPE_PLUGIN (gsignond_plugin_get_type ())
+#define GSIGNOND_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSIGNOND_TYPE_PLUGIN, GSignondPlugin))
+#define GSIGNOND_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSIGNOND_TYPE_PLUGIN))
+#define GSIGNOND_PLUGIN_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GSIGNOND_TYPE_PLUGIN, GSignondPluginInterface))
typedef struct _GSignondPlugin GSignondPlugin; /* dummy object */
typedef struct _GSignondPluginInterface GSignondPluginInterface;
struct _GSignondPluginInterface {
GTypeInterface parent;
- void (*cancel) (GSignondPlugin *self);
- void (*abort) (GSignondPlugin *self);
- void (*process) (GSignondPlugin *self, const GVariant *session_data, const gchar *mechanism);
- void (*user_action_finished) (GSignondPlugin *self, const GVariant *session_data);
- void (*refresh) (GSignondPlugin *self, const GVariant *session_data);
+ void (*cancel) (GSignondPlugin *self);
+ void (*abort) (GSignondPlugin *self);
+ void (*process) (GSignondPlugin *self,
+ GSignondSessionData *session_data,
+ const gchar *mechanism);
+ void (*user_action_finished) (GSignondPlugin *self,
+ GSignondSessionData *session_data);
+ void (*refresh) (GSignondPlugin *self,
+ GSignondSessionData *session_data);
};
GType gsignond_plugin_get_type (void);
/* Methods */
void gsignond_plugin_cancel (GSignondPlugin *self);
void gsignond_plugin_abort (GSignondPlugin *self);
-void gsignond_plugin_process (GSignondPlugin *self, const GVariant *session_data, const gchar *mechanism);
-void gsignond_plugin_user_action_finished (GSignondPlugin *self, const GVariant *session_data);
-void gsignond_plugin_refresh (GSignondPlugin *self, const GVariant *session_data);
+void gsignond_plugin_process (GSignondPlugin *self,
+ GSignondSessionData *session_data,
+ const gchar *mechanism);
+void gsignond_plugin_user_action_finished (GSignondPlugin *self,
+ GSignondSessionData *session_data);
+void gsignond_plugin_refresh (GSignondPlugin *self,
+ GSignondSessionData *session_data);
/* Signals */
-void gsignond_plugin_result (GSignondPlugin *self, const GVariant *session_data);
-void gsignond_plugin_store (GSignondPlugin *self, const GVariant *session_data);
-void gsignond_plugin_error (GSignondPlugin *self, int error); //FIXME: what is the error type?
-void gsignond_plugin_user_action_required (GSignondPlugin *self, const GVariant *session_data);
-void gsignond_plugin_refreshed (GSignondPlugin *self, const GVariant *session_data);
-void gsignond_plugin_status_changed (GSignondPlugin *self, const gchar *status, const gchar *message);
+void gsignond_plugin_result (GSignondPlugin *self,
+ GSignondSessionData *session_data);
+void gsignond_plugin_store (GSignondPlugin *self,
+ GSignondSessionData *session_data);
+void gsignond_plugin_error (GSignondPlugin *self, GError *error);
+void gsignond_plugin_user_action_required (GSignondPlugin *self,
+ GSignondSessionData *session_data);
+void gsignond_plugin_refreshed (GSignondPlugin *self,
+ GSignondSessionData *session_data);
+void gsignond_plugin_status_changed (GSignondPlugin *self,
+ const gchar *status,
+ const gchar *message);
G_END_DECLS
--- /dev/null
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of gsignond
+ *
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Contact: Alexander Kanavin <alex.kanavin@gmail.com>
+ *
+ * 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
+ */
+
+#ifndef __GSIGNOND_SESSION_DATA_H__
+#define __GSIGNOND_SESSION_DATA_H__
+
+#include <gsignond/gsignond-dictionary.h>
+
+G_BEGIN_DECLS
+
+#define GSIGNOND_TYPE_SESSION_DATA (GSIGNOND_TYPE_DICTIONARY)
+
+#define GSIGNOND_SESSION_DATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GSIGNOND_TYPE_SESSION_DATA, \
+ GSignondSessionData))
+#define GSIGNOND_IS_SESSION_DATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+ GSIGNOND_TYPE_SESSION_DATA))
+
+typedef GSignondDictionary GSignondSessionData;
+
+/*!
+ * Error codes for ui interaction.
+ */
+typedef enum {
+ GSIGNOND_QUERY_ERROR_NONE = 0, /**< No errors. */
+ GSIGNOND_QUERY_ERROR_GENERAL, /**< Generic error during interaction. */
+ GSIGNOND_QUERY_ERROR_NO_SIGNONUI, /**< Cannot send request to signon-ui. */
+ GSIGNOND_QUERY_ERROR_BAD_PARAMETERS, /**< Signon-Ui cannot create dialog based on
+ the given UiSessionData. */
+ GSIGNOND_QUERY_ERROR_CANCELED, /**< User canceled action. Plugin should not
+ retry automatically after this. */
+ GSIGNOND_QUERY_ERROR_NOT_AVAILABLE, /**< Requested ui is not available. For
+ example browser cannot be started. */
+ GSIGNOND_QUERY_ERROR_BAD_URL, /**< Given url was not valid. */
+ GSIGNOND_QUERY_ERROR_BAD_CAPTCHA, /**< Given captcha image was not valid. */
+ GSIGNOND_QUERY_ERROR_BAD_CAPTCHA_URL, /**< Given url for capctha loading was not
+ valid. */
+ GSIGNOND_QUERY_ERROR_REFRESH_FAILED, /**< Refresh failed. */
+ GSIGNOND_QUERY_ERROR_FORBIDDEN, /**< Showing ui forbidden by ui policy. */
+ GSIGNOND_QUERY_ERROR_FORGOT_PASSWORD /**< User pressed forgot password. */
+ //TODO add more errors
+} GSignondQueryError;
+
+
+//FIXME: all the other standard sessiondata and uisessiondata fields
+//should be added
+const gchar*
+gsignond_session_data_get_username(GSignondSessionData* data);
+
+void
+gsignond_session_data_set_username(GSignondSessionData* data,
+ const gchar* username);
+
+const gchar*
+gsignond_session_data_get_secret(GSignondSessionData* data);
+
+void
+gsignond_session_data_set_secret(GSignondSessionData* data,
+ const gchar* secret);
+
+gboolean
+gsignond_session_data_get_query_username(GSignondSessionData* data);
+
+void
+gsignond_session_data_set_query_username(GSignondSessionData* data,
+ gboolean query_username);
+
+gboolean
+gsignond_session_data_get_query_password(GSignondSessionData* data);
+
+void
+gsignond_session_data_set_query_password(GSignondSessionData* data,
+ gboolean query_password);
+
+GSignondQueryError gsignond_session_data_get_query_error(
+ GSignondSessionData* data);
+
+void
+gsignond_session_data_set_query_error(GSignondSessionData* data,
+ GSignondQueryError error);
+
+G_END_DECLS
+
+#endif /* __GSIGNOND_SESSION_DATA_H__ */
gsignond-config.c \
gsignond-error.c \
gsignond-plugin-interface.c \
+ gsignond-dictionary.c \
+ gsignond-session-data.c \
$(NULL)
CLEANFILES =
--- /dev/null
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of gsignond
+ *
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Contact: Alexander Kanavin <alex.kanavin@gmail.com>
+ *
+ * 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 <gsignond/gsignond-dictionary.h>
+
+/**
+ * gsignond_dictionary_new_from_variant:
+ * @variant: instance of #GVariant
+ *
+ * Converts the variant to GSignondDictionary.
+ *
+ * Returns: (transfer full) object if successful, NULL otherwise.
+ */
+GSignondDictionary *
+gsignond_dictionary_new_from_variant (GVariant *variant)
+{
+ GSignondDictionary *dict = NULL;
+ GVariantIter iter;
+ gchar *key = NULL;
+ GVariant *value = NULL;
+
+ g_return_val_if_fail (variant != NULL, NULL);
+
+ dict = gsignond_dictionary_new ();
+ g_variant_iter_init (&iter, variant);
+ while (g_variant_iter_next (&iter, "{sv}", &key, &value))
+ {
+ g_hash_table_insert (dict, key, value);
+ }
+
+ return dict;
+}
+
+/**
+ * gsignond_dictionary_to_variant:
+ * @dict: instance of #GSignondDictionary
+ *
+ * Converts the GSignondDictionary to variant.
+ *
+ * Returns: (transfer full) #GVariant object if successful, NULL otherwise.
+ */
+GVariant *
+gsignond_dictionary_to_variant (GSignondDictionary *dict)
+{
+ GVariantBuilder builder;
+ GHashTableIter iter;
+ GVariant *vdict = NULL;
+ const gchar *key = NULL;
+ GVariant *value = NULL;
+
+ g_return_val_if_fail (dict != NULL, NULL);
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+ g_hash_table_iter_init (&iter, dict);
+ while (g_hash_table_iter_next (&iter,
+ (gpointer)&key,
+ (gpointer)&value))
+ {
+ g_variant_builder_add (&builder, "{sv}",
+ key,
+ value);
+ }
+ vdict = g_variant_builder_end (&builder);
+ return vdict;
+}
+
+/**
+ * gsignond_dictionary_new:
+ *
+ * Creates new instance of GSignondDictionary.
+ *
+ * Returns: (transfer full) #GSignondDictionary object if successful,
+ * NULL otherwise.
+ */
+GSignondDictionary *
+gsignond_dictionary_new (void)
+{
+ return g_hash_table_new_full ((GHashFunc)g_str_hash,
+ (GEqualFunc)g_str_equal,
+ (GDestroyNotify)g_free,
+ (GDestroyNotify)g_variant_unref);
+}
+
+/**
+ * gsignond_dictionary_free:
+ * @dict: instance of #GSignondDictionary
+ *
+ * Frees the memory allocated by dict structure.
+ *
+ */
+void
+gsignond_dictionary_free (GSignondDictionary *dict)
+{
+ g_return_if_fail (dict != NULL);
+ g_hash_table_unref (dict);
+}
+
+/**
+ * gsignond_dictionary_get:
+ * @dict: instance of #GSignondDictionary
+ *
+ * Retrieves a value from the dictionary.
+ *
+ * Returns: the value; NULL is returned in case of failure.
+ */
+GVariant *
+gsignond_dictionary_get (GSignondDictionary *dict, gchar *key)
+{
+ g_return_val_if_fail (dict != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ return g_hash_table_lookup (dict, key);
+}
+
+/**
+ * gsignond_dictionary_set:
+ * @dict: instance of #GSignondDictionary
+ *
+ * @key: key to be set
+ * @value: value to be set
+ *
+ * Adds or replaces key-value pair in the dictionary.
+ *
+ * Returns: TRUE if successful, FALSE otherwise.
+ */
+void
+gsignond_dictionary_set (GSignondDictionary *dict,
+ gchar *key, GVariant *value)
+{
+ g_return_if_fail (dict != NULL);
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (value != NULL);
+
+ g_variant_ref_sink(value);
+
+ g_hash_table_replace (
+ dict,
+ g_strdup(key),
+ value);
+
+ return;
+}
+
+/**
+ * gsignond_dictionary_copy:
+ * @other: instance of #GSignondDictionary
+ *
+ * Creates a copy of the dictionary.
+ *
+ * Returns: (transfer full) #GSignondDictionary object if successful,
+ * NULL otherwise.
+ */
+GSignondDictionary *
+gsignond_dictionary_copy (GSignondDictionary *other)
+{
+ GSignondDictionary *dict = NULL;
+ GHashTableIter iter;
+ gchar *key = NULL;
+ GVariant *value = NULL;
+
+ g_return_val_if_fail (other != NULL, NULL);
+
+ dict = gsignond_dictionary_new ();
+
+ g_hash_table_iter_init (&iter, other);
+ while (g_hash_table_iter_next (&iter,
+ (gpointer)&key,
+ (gpointer)&value))
+ {
+ gsignond_dictionary_set (dict, key, value);
+ }
+
+
+ return dict;
+}
{
static GQuark quark = 0;
if (quark == 0) {
- quark = g_quark_from_static_string (G_LOG_DOMAIN);
+ quark = g_quark_from_static_string (GSIGNOND_ERROR_DOMAIN);
}
return quark;
}
{
signals[RESULT] = g_signal_new ("result", G_TYPE_FROM_CLASS (g_class),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
- 1, G_TYPE_VARIANT);
+ 1, GSIGNOND_TYPE_SESSION_DATA);
signals[STORE] = g_signal_new ("store", G_TYPE_FROM_CLASS (g_class),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
- 1, G_TYPE_VARIANT);
+ 1, GSIGNOND_TYPE_SESSION_DATA);
signals[ERROR] = g_signal_new ("error", G_TYPE_FROM_CLASS (g_class),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
- 1, G_TYPE_INT);
+ 1, G_TYPE_ERROR);
- signals[USER_ACTION_REQUIRED] = g_signal_new ("user-action-required", G_TYPE_FROM_CLASS (g_class),
+ signals[USER_ACTION_REQUIRED] = g_signal_new ("user-action-required",
+ G_TYPE_FROM_CLASS (g_class),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
- 1, G_TYPE_VARIANT);
+ 1, GSIGNOND_TYPE_SESSION_DATA);
signals[REFRESHED] = g_signal_new ("refreshed", G_TYPE_FROM_CLASS (g_class),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
- 1, G_TYPE_VARIANT);
+ 1, GSIGNOND_TYPE_SESSION_DATA);
- signals[STATUS_CHANGED] = g_signal_new ("status-changed", G_TYPE_FROM_CLASS (g_class),
+ signals[STATUS_CHANGED] = g_signal_new ("status-changed",
+ G_TYPE_FROM_CLASS (g_class),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
2, G_TYPE_STRING, G_TYPE_STRING);
g_object_interface_install_property (g_class,
- g_param_spec_string ("type", "Type", "Plugin type", "none", G_PARAM_READABLE));
+ g_param_spec_string ("type", "Type", "Plugin type", "none",
+ G_PARAM_READABLE));
g_object_interface_install_property (g_class,
- g_param_spec_boxed ("mechanisms", "Mechanisms", "List of plugin mechanisms", G_TYPE_STRV, G_PARAM_READABLE));
+ g_param_spec_boxed ("mechanisms", "Mechanisms",
+ "List of plugin mechanisms",
+ G_TYPE_STRV, G_PARAM_READABLE));
}
GSIGNOND_PLUGIN_GET_INTERFACE (self)->abort (self);
}
-void gsignond_plugin_process (GSignondPlugin *self, const GVariant *session_data, const gchar *mechanism)
+void gsignond_plugin_process (GSignondPlugin *self,
+ GSignondSessionData *session_data,
+ const gchar *mechanism)
{
g_return_if_fail (GSIGNOND_IS_PLUGIN (self));
GSIGNOND_PLUGIN_GET_INTERFACE (self)->process (self, session_data, mechanism);
}
-void gsignond_plugin_user_action_finished (GSignondPlugin *self, const GVariant *session_data)
+void gsignond_plugin_user_action_finished (GSignondPlugin *self,
+ GSignondSessionData *session_data)
{
g_return_if_fail (GSIGNOND_IS_PLUGIN (self));
- GSIGNOND_PLUGIN_GET_INTERFACE (self)->user_action_finished (self, session_data);
+ GSIGNOND_PLUGIN_GET_INTERFACE (self)->user_action_finished (self,
+ session_data);
}
-void gsignond_plugin_refresh (GSignondPlugin *self, const GVariant *session_data)
+void gsignond_plugin_refresh (GSignondPlugin *self,
+ GSignondSessionData *session_data)
{
g_return_if_fail (GSIGNOND_IS_PLUGIN (self));
GSIGNOND_PLUGIN_GET_INTERFACE (self)->refresh (self, session_data);
}
-void gsignond_plugin_result (GSignondPlugin *self, const GVariant *session_data)
+void gsignond_plugin_result (GSignondPlugin *self,
+ GSignondSessionData *session_data)
{
g_signal_emit (self, signals[RESULT], 0, session_data);
}
-void gsignond_plugin_store (GSignondPlugin *self, const GVariant *session_data)
+void gsignond_plugin_store (GSignondPlugin *self,
+ GSignondSessionData *session_data)
{
g_signal_emit (self, signals[STORE], 0, session_data);
}
-void gsignond_plugin_error (GSignondPlugin *self, int error)
+void gsignond_plugin_error (GSignondPlugin *self, GError *error)
{
g_signal_emit (self, signals[ERROR], 0, error);
}
-void gsignond_plugin_user_action_required (GSignondPlugin *self, const GVariant *session_data)
+void gsignond_plugin_user_action_required (GSignondPlugin *self,
+ GSignondSessionData *session_data)
{
g_signal_emit (self, signals[USER_ACTION_REQUIRED], 0, session_data);
}
-void gsignond_plugin_refreshed (GSignondPlugin *self, const GVariant *session_data)
+void gsignond_plugin_refreshed (GSignondPlugin *self,
+ GSignondSessionData *session_data)
{
g_signal_emit (self, signals[REFRESHED], 0, session_data);
}
-void gsignond_plugin_status_changed (GSignondPlugin *self, const gchar *status, const gchar *message)
+void gsignond_plugin_status_changed (GSignondPlugin *self, const gchar *status,
+ const gchar *message)
{
g_signal_emit (self, signals[STATUS_CHANGED], 0, status, message);
}
--- /dev/null
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of gsignond
+ *
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Contact: Alexander Kanavin <alex.kanavin@gmail.com>
+ *
+ * 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 <gsignond/gsignond-session-data.h>
+
+const gchar*
+gsignond_session_data_get_username(GSignondSessionData* data)
+{
+ GVariant* variant = gsignond_dictionary_get(data, "username");
+ if (variant == NULL)
+ return NULL;
+ return g_variant_get_string(variant, NULL);
+}
+
+void
+gsignond_session_data_set_username(GSignondSessionData* data,
+ const gchar* username)
+{
+ gsignond_dictionary_set(data, "username", g_variant_new_string(username));
+}
+
+const gchar*
+gsignond_session_data_get_secret(GSignondSessionData* data)
+{
+ GVariant* variant = gsignond_dictionary_get(data, "secret");
+ if (variant == NULL)
+ return NULL;
+ return g_variant_get_string(variant, NULL);
+
+}
+
+void
+gsignond_session_data_set_secret(GSignondSessionData* data,
+ const gchar* secret)
+{
+ gsignond_dictionary_set(data, "secret", g_variant_new_string(secret));
+}
+
+gboolean
+gsignond_session_data_get_query_username(GSignondSessionData* data)
+{
+ GVariant* variant = gsignond_dictionary_get(data, "query_username");
+ if (variant == NULL)
+ return FALSE;
+ return g_variant_get_boolean(variant);
+}
+
+void
+gsignond_session_data_set_query_username(GSignondSessionData* data,
+ gboolean query_username)
+{
+ gsignond_dictionary_set(data, "query_username",
+ g_variant_new_boolean(query_username));
+}
+
+gboolean
+gsignond_session_data_get_query_password(GSignondSessionData* data)
+{
+ GVariant* variant = gsignond_dictionary_get(data, "query_password");
+ if (variant == NULL)
+ return FALSE;
+ return g_variant_get_boolean(variant);
+}
+
+void
+gsignond_session_data_set_query_password(GSignondSessionData* data,
+ gboolean query_password)
+{
+ gsignond_dictionary_set(data, "query_password",
+ g_variant_new_boolean(query_password));
+}
+
+GSignondQueryError gsignond_session_data_get_query_error(
+ GSignondSessionData* data)
+{
+ GVariant* variant = gsignond_dictionary_get(data, "query_error");
+ if (variant == NULL)
+ return GSIGNOND_QUERY_ERROR_NONE;
+ return g_variant_get_int32(variant);
+}
+
+void
+gsignond_session_data_set_query_error(GSignondSessionData* data,
+ GSignondQueryError error)
+{
+ gsignond_dictionary_set(data, "query_error",
+ g_variant_new_int32(error));
+}
$(GSIGNOND_CFLAGS) \
$(NULL)
-libpasswordplugin_la_LIBS = \
- $(GSIGNOND_LIBS)
+libpasswordplugin_la_LIBADD = \
+ $(top_builddir)/src/common/libgsignond-common.la \
+ $(GSIGNOND_LIBS) \
$(NULL)
libpasswordplugin_la_SOURCES = \
#include <gsignond/gsignond-plugin-interface.h>
#include "gsignond-password-plugin.h"
+#include <gsignond/gsignond-error.h>
static void gsignond_plugin_interface_init (GSignondPluginInterface *iface);
-G_DEFINE_TYPE_WITH_CODE (GSignondPasswordPlugin, gsignond_password_plugin, G_TYPE_OBJECT,
+G_DEFINE_TYPE_WITH_CODE (GSignondPasswordPlugin, gsignond_password_plugin,
+ G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GSIGNOND_TYPE_PLUGIN,
gsignond_plugin_interface_init));
static void gsignond_password_plugin_cancel (GSignondPlugin *self)
{
-// g_print ("Baz implementation of Ibaz interface Action: 0x%x.\n",
-// self->instance_member);
+ GError* error = g_error_new(GSIGNOND_ERROR,
+ GSIGNOND_ERROR_SESSION_CANCELED,
+ "Session canceled");
+ gsignond_plugin_error (self, error);
+ g_error_free(error);
}
static void gsignond_password_plugin_abort (GSignondPlugin *self)
}
-static void gsignond_password_plugin_process (GSignondPlugin *self, const GVariant *session_data, const gchar *mechanism)
+static void gsignond_password_plugin_process (
+ GSignondPlugin *self, GSignondSessionData *session_data,
+ const gchar *mechanism)
{
+ const gchar* username = gsignond_session_data_get_username(session_data);
+ const gchar* secret = gsignond_session_data_get_secret(session_data);
+ if (secret != NULL) {
+ GSignondSessionData *response = gsignond_dictionary_new();
+ if (username != NULL)
+ gsignond_session_data_set_username(response, username);
+ gsignond_session_data_set_secret(response, secret);
+ gsignond_plugin_result(self, response);
+ gsignond_dictionary_free(response);
+ return;
+ }
+
+ GSignondSessionData *user_action_data = gsignond_dictionary_new();
+ if (username == NULL)
+ gsignond_session_data_set_query_username(user_action_data, TRUE);
+ else
+ gsignond_session_data_set_username(user_action_data, username);
+ gsignond_session_data_set_query_password(user_action_data, TRUE);
+ gsignond_plugin_user_action_required(self, user_action_data);
+ gsignond_dictionary_free(user_action_data);
}
-static void gsignond_password_plugin_user_action_finished (GSignondPlugin *self, const GVariant *session_data)
+static void gsignond_password_plugin_user_action_finished (
+ GSignondPlugin *self,
+ GSignondSessionData *session_data)
{
+ GSignondQueryError query_error = gsignond_session_data_get_query_error(
+ session_data);
+ const gchar* username = gsignond_session_data_get_username(session_data);
+ const gchar* secret = gsignond_session_data_get_secret(session_data);
+ if (query_error == GSIGNOND_QUERY_ERROR_NONE &&
+ username != NULL &&
+ secret != NULL) {
+ GSignondSessionData *response = gsignond_dictionary_new();
+ gsignond_session_data_set_username(response, username);
+ gsignond_session_data_set_secret(response, secret);
+ gsignond_plugin_result(self, response);
+ gsignond_dictionary_free(response);
+ return;
+ } else if (query_error == GSIGNOND_QUERY_ERROR_CANCELED) {
+ GError* error = g_error_new(GSIGNOND_ERROR,
+ GSIGNOND_ERROR_SESSION_CANCELED,
+ "Session canceled");
+ gsignond_plugin_error (self, error);
+ g_error_free(error);
+ } else {
+ gchar* error_message = g_strdup_printf("userActionFinished error: %d",
+ query_error);
+ GError* error = g_error_new(GSIGNOND_ERROR,
+ GSIGNOND_ERROR_USER_INTERACTION,
+ error_message);
+ gsignond_plugin_error (self, error);
+ g_free(error_message);
+ g_error_free(error);
+ }
}
-static void gsignond_password_plugin_refresh (GSignondPlugin *self, const GVariant *session_data)
+static void gsignond_password_plugin_refresh (
+ GSignondPlugin *self,
+ GSignondSessionData *session_data)
{
-
+ gsignond_plugin_refreshed(self, session_data);
}
static void
static void
gsignond_password_plugin_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
switch (property_id)
{
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
}
static void
gsignond_password_plugin_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
GSignondPasswordPlugin *password_plugin = GSIGNOND_PASSWORD_PLUGIN (object);
gchar *mechanisms[] = { "password", NULL };
switch (prop_id)
{
- case PROP_TYPE:
- g_value_set_string (value, "password");
- break;
- case PROP_MECHANISMS:
- g_value_set_boxed (value, mechanisms);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
+ case PROP_TYPE:
+ g_value_set_string (value, "password");
+ break;
+ case PROP_MECHANISMS:
+ g_value_set_boxed (value, mechanisms);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
}
}
gobject_class->get_property = gsignond_password_plugin_get_property;
g_object_class_override_property (gobject_class, PROP_TYPE, "type");
- g_object_class_override_property (gobject_class, PROP_MECHANISMS, "mechanisms");
+ g_object_class_override_property (gobject_class, PROP_MECHANISMS,
+ "mechanisms");
}
\ No newline at end of file
-SUBDIRS = db
+SUBDIRS = db passwordplugin
--- /dev/null
+TESTS = passwordplugintest
+check_PROGRAMS = passwordplugintest
+passwordplugintest_SOURCES = passwordplugintest.c
+passwordplugintest_CFLAGS = \
+ $(GSIGNOND_CFLAGS) \
+ $(CHECK_CFLAGS) \
+ -I$(top_srcdir)/src/plugins/password \
+ -I$(top_srcdir)/include/
+
+passwordplugintest_LDADD = \
+ $(top_builddir)/src/common/libgsignond-common.la \
+ $(top_builddir)/src/plugins/password/libpasswordplugin.la \
+ $(GSIGNOND_LIBS) \
+ $(CHECK_LIBS)
\ No newline at end of file
--- /dev/null
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of gsignond
+ *
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Contact: Alexander Kanavin <alex.kanavin@gmail.com>
+ *
+ * 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 <check.h>
+#include <stdlib.h>
+#include "gsignond-password-plugin.h"
+#include <gsignond/gsignond-session-data.h>
+#include <gsignond/gsignond-plugin-interface.h>
+#include <gsignond/gsignond-error.h>
+
+
+START_TEST (test_session_data)
+{
+ GSignondSessionData* data;
+ GSignondSessionData* data_from_variant;
+ GSignondSessionData* data_from_copy;
+ GVariant* variant;
+
+ data = gsignond_dictionary_new();
+ fail_if(data == NULL);
+
+ fail_unless(gsignond_session_data_get_username(data) == NULL);
+ fail_unless(gsignond_session_data_get_secret(data) == NULL);
+ fail_unless(gsignond_session_data_get_query_username(data) == FALSE);
+ fail_unless(gsignond_session_data_get_query_password(data) == FALSE);
+
+ gsignond_session_data_set_username(data, "megauser");
+ gsignond_session_data_set_secret(data, "megapassword");
+ gsignond_session_data_set_query_username(data, TRUE);
+ gsignond_session_data_set_query_password(data, TRUE);
+
+ fail_unless(g_strcmp0(gsignond_session_data_get_username(data),
+ "megauser") == 0);
+ fail_unless(g_strcmp0(gsignond_session_data_get_secret(data),
+ "megapassword") == 0);
+ fail_unless(gsignond_session_data_get_query_username(data) == TRUE);
+ fail_unless(gsignond_session_data_get_query_password(data) == TRUE);
+
+ gsignond_session_data_set_username(data, "usermega");
+ fail_unless(g_strcmp0(gsignond_session_data_get_username(data),
+ "usermega") == 0);
+
+ data_from_copy = gsignond_dictionary_copy(data);
+ fail_if(data_from_copy == NULL);
+
+ fail_unless(g_strcmp0(gsignond_session_data_get_username(data_from_copy),
+ "usermega") == 0);
+ fail_unless(g_strcmp0(gsignond_session_data_get_secret(data_from_copy),
+ "megapassword") == 0);
+ fail_unless(gsignond_session_data_get_query_username(data_from_copy) == TRUE);
+ fail_unless(gsignond_session_data_get_query_password(data_from_copy) == TRUE);
+
+ variant = gsignond_dictionary_to_variant(data);
+ fail_if(variant == NULL);
+ data_from_variant = gsignond_dictionary_new_from_variant(variant);
+ fail_if(data_from_variant == NULL);
+
+ fail_unless(g_strcmp0(gsignond_session_data_get_username(data_from_variant),
+ "usermega") == 0);
+ fail_unless(g_strcmp0(gsignond_session_data_get_secret(data_from_variant),
+ "megapassword") == 0);
+ fail_unless(gsignond_session_data_get_query_username(data_from_variant) == TRUE);
+ fail_unless(gsignond_session_data_get_query_password(data_from_variant) == TRUE);
+
+ g_variant_unref(variant);
+ gsignond_dictionary_free(data_from_variant);
+ gsignond_dictionary_free(data_from_copy);
+ gsignond_dictionary_free(data);
+}
+END_TEST
+
+START_TEST (test_passwordplugin_create)
+{
+ gpointer plugin;
+ gchar* type;
+ gchar** mechanisms;
+
+ plugin = g_object_new(GSIGNOND_TYPE_PASSWORD_PLUGIN, NULL);
+ fail_if(plugin == NULL);
+
+ g_object_get(plugin, "type", &type, "mechanisms", &mechanisms, NULL);
+
+ fail_unless(g_strcmp0(type, "password") == 0);
+ fail_unless(g_strcmp0(mechanisms[0], "password") == 0);
+ fail_unless(mechanisms[1] == NULL);
+
+ g_free(type);
+ g_strfreev(mechanisms);
+ g_object_unref(plugin);
+}
+END_TEST
+
+static void result_callback(GSignondPlugin* plugin, GSignondSessionData* result,
+ gpointer user_data)
+{
+ GSignondSessionData** user_data_p = user_data;
+ *user_data_p = gsignond_dictionary_copy(result);
+}
+
+static void user_action_required_callback(GSignondPlugin* plugin,
+ GSignondSessionData* ui_request,
+ gpointer user_data)
+{
+ GSignondSessionData** user_data_p = user_data;
+ *user_data_p = gsignond_dictionary_copy(ui_request);
+}
+
+static void error_callback(GSignondPlugin* plugin, GError* error,
+ gpointer user_data)
+{
+ GError** user_data_p = user_data;
+ *user_data_p = g_error_copy(error);
+}
+
+
+START_TEST (test_passwordplugin_process)
+{
+ gpointer plugin;
+
+ plugin = g_object_new(GSIGNOND_TYPE_PASSWORD_PLUGIN, NULL);
+ fail_if(plugin == NULL);
+
+ GSignondSessionData* result = NULL;
+ GSignondSessionData* ui_action = NULL;
+ GError* error = NULL;
+
+ g_signal_connect(plugin, "result", G_CALLBACK(result_callback), &result);
+ g_signal_connect(plugin, "user-action-required",
+ G_CALLBACK(user_action_required_callback), &ui_action);
+ g_signal_connect(plugin, "error", G_CALLBACK(error_callback), &error);
+
+ GSignondSessionData* data = gsignond_dictionary_new();
+
+ // username empty, password not empty
+ gsignond_session_data_set_secret(data, "megapassword");
+ gsignond_plugin_process(plugin, data, "password");
+ fail_if(result == NULL);
+ fail_if(ui_action != NULL);
+ fail_if(error != NULL);
+ fail_if(gsignond_session_data_get_username(result) != NULL);
+ fail_if(g_strcmp0(
+ gsignond_session_data_get_secret(result), "megapassword") != 0);
+ gsignond_dictionary_free(result);
+ result = NULL;
+
+ // username and password not empty
+ gsignond_session_data_set_username(data, "megauser");
+ gsignond_plugin_process(plugin, data, "password");
+ fail_if(result == NULL);
+ fail_if(ui_action != NULL);
+ fail_if(error != NULL);
+ fail_if(g_strcmp0(
+ gsignond_session_data_get_username(result), "megauser") != 0);
+ fail_if(g_strcmp0(
+ gsignond_session_data_get_secret(result), "megapassword") != 0);
+ gsignond_dictionary_free(result);
+ result = NULL;
+
+ //username and password empty
+ gsignond_dictionary_free(data);
+ data = gsignond_dictionary_new();
+ gsignond_plugin_process(plugin, data, "password");
+ fail_if(result != NULL);
+ fail_if(ui_action == NULL);
+ fail_if(error != NULL);
+ fail_if(gsignond_session_data_get_query_username(ui_action) == FALSE);
+ fail_if(gsignond_session_data_get_query_password(ui_action) == FALSE);
+ gsignond_dictionary_free(ui_action);
+ ui_action = NULL;
+
+ //username not empty, password empty
+ gsignond_session_data_set_username(data, "megauser");
+ gsignond_plugin_process(plugin, data, "password");
+ fail_if(result != NULL);
+ fail_if(ui_action == NULL);
+ fail_if(error != NULL);
+ fail_if(gsignond_session_data_get_query_username(ui_action) == TRUE);
+ fail_if(gsignond_session_data_get_query_password(ui_action) == FALSE);
+ gsignond_dictionary_free(ui_action);
+ ui_action = NULL;
+
+ gsignond_dictionary_free(data);
+ g_object_unref(plugin);
+}
+END_TEST
+
+START_TEST (test_passwordplugin_user_action_finished)
+{
+ gpointer plugin;
+
+ plugin = g_object_new(GSIGNOND_TYPE_PASSWORD_PLUGIN, NULL);
+ fail_if(plugin == NULL);
+
+ GSignondSessionData* result = NULL;
+ GSignondSessionData* ui_action = NULL;
+ GError* error = NULL;
+
+ g_signal_connect(plugin, "result", G_CALLBACK(result_callback), &result);
+ g_signal_connect(plugin, "user-action-required",
+ G_CALLBACK(user_action_required_callback), &ui_action);
+ g_signal_connect(plugin, "error", G_CALLBACK(error_callback), &error);
+
+ GSignondSessionData* data = gsignond_dictionary_new();
+
+ //empty data
+ gsignond_plugin_user_action_finished(plugin, data);
+ fail_if(result != NULL);
+ fail_if(ui_action != NULL);
+ fail_if(error == NULL);
+ fail_unless(g_error_matches(error, GSIGNOND_ERROR,
+ GSIGNOND_ERROR_USER_INTERACTION));
+ g_error_free(error);
+ error = NULL;
+
+ // correct values
+ gsignond_session_data_set_username(data, "megauser");
+ gsignond_session_data_set_secret(data, "megapassword");
+ gsignond_session_data_set_query_error(data, GSIGNOND_QUERY_ERROR_NONE);
+ gsignond_plugin_user_action_finished(plugin, data);
+ fail_if(result == NULL);
+ fail_if(ui_action != NULL);
+ fail_if(error != NULL);
+ fail_if(g_strcmp0(
+ gsignond_session_data_get_username(result), "megauser") != 0);
+ fail_if(g_strcmp0(
+ gsignond_session_data_get_secret(result), "megapassword") != 0);
+ gsignond_dictionary_free(result);
+ result = NULL;
+
+ // user canceled
+ gsignond_session_data_set_query_error(data, GSIGNOND_QUERY_ERROR_CANCELED);
+ gsignond_plugin_user_action_finished(plugin, data);
+ fail_if(result != NULL);
+ fail_if(ui_action != NULL);
+ fail_if(error == NULL);
+ fail_unless(g_error_matches(error, GSIGNOND_ERROR,
+ GSIGNOND_ERROR_SESSION_CANCELED));
+ g_error_free(error);
+ error = NULL;
+
+ // error in ui request
+ gsignond_session_data_set_query_error(data, GSIGNOND_QUERY_ERROR_GENERAL);
+ gsignond_plugin_user_action_finished(plugin, data);
+ fail_if(result != NULL);
+ fail_if(ui_action != NULL);
+ fail_if(error == NULL);
+ fail_unless(g_error_matches(error, GSIGNOND_ERROR,
+ GSIGNOND_ERROR_USER_INTERACTION));
+ g_error_free(error);
+ error = NULL;
+
+ gsignond_dictionary_free(data);
+ g_object_unref(plugin);
+}
+END_TEST
+
+START_TEST (test_passwordplugin_refresh)
+{
+ gpointer plugin;
+
+ plugin = g_object_new(GSIGNOND_TYPE_PASSWORD_PLUGIN, NULL);
+ fail_if(plugin == NULL);
+
+ GSignondSessionData* result = NULL;
+ GError* error = NULL;
+
+ g_signal_connect(plugin, "refreshed", G_CALLBACK(result_callback), &result);
+ g_signal_connect(plugin, "error", G_CALLBACK(error_callback), &error);
+
+ GSignondSessionData* data = gsignond_dictionary_new();
+ gsignond_plugin_refresh(plugin, data);
+ fail_if(result == NULL);
+ fail_if(error != NULL);
+ gsignond_dictionary_free(result);
+ result = NULL;
+
+ gsignond_dictionary_free(data);
+ g_object_unref(plugin);
+}
+END_TEST
+
+
+Suite* passwordplugin_suite (void)
+{
+ Suite *s = suite_create ("Password plugin");
+
+ /* Core test case */
+ TCase *tc_core = tcase_create ("Tests");
+ tcase_add_test (tc_core, test_session_data);
+ tcase_add_test (tc_core, test_passwordplugin_create);
+ tcase_add_test (tc_core, test_passwordplugin_process);
+ tcase_add_test (tc_core, test_passwordplugin_user_action_finished);
+ tcase_add_test (tc_core, test_passwordplugin_refresh);
+ suite_add_tcase (s, tc_core);
+ return s;
+}
+
+int main (void)
+{
+ int number_failed;
+
+ g_type_init();
+
+ Suite *s = passwordplugin_suite();
+ SRunner *sr = srunner_create(s);
+ srunner_run_all(sr, CK_NORMAL);
+ number_failed = srunner_ntests_failed(sr);
+ srunner_free(sr);
+ return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
\ No newline at end of file