./0000755000004100000410000000000013013271000011226 5ustar www-datawww-data./NEWS0000644000004100000410000000546713013271000011741 0ustar www-datawww-datalibsignon-glib NEWS Version 1.14 ------------ * Migrate to GTask * Fix memory leaks reported by valgrind * Enable CI in gitlab.com * Build: add test coverage reporting * Build: fix parallel builds and out-of-tree builds * Tests: add a test for signon_auth_session_process_async() * Tests: allow running tests with valgrind Version 1.13 ------------ * Build: don't emit a build error on deprecations * Build: ignore deprecations of GSimpleAsyncResult * pkg-config: remove unused variable Fixes: https://gitlab.com/accounts-sso/libsignon-glib/issues/1 * Tests: do not count on mechanisms being ordered * Introspection: mark ACL and realms as string lists, update Vala bindings Version 1.12 ------------ * Introspection: fix transfer type of some methods * Update VALA bindings Version 1.11 ------------ * Disconnect from signals when the remote AuthSession dies http://code.google.com/p/accounts-sso/issues/detail?id=229 * Avoid unreferencing a NULL GVariant * Fix the linking problem when using check Version 1.10 ------------ * Temporarily disable GTKDOC_CHECK, it tries to write a log to /usr/bin * Tests: do not access invalidated objects * Remove calls to g_type_init() * Doc: mention that Identity::signout() clears password and tokens * Check that NEWS has been updated Version 1.9 ----------- * Invoke the callback when errors occur * Add NOCONFIGURE logic to autogen.sh * Fix the check for pyoverridesdir for python3 * Fix a memory leak Version 1.8 ----------- * Add signon_auth_session_process_async http://code.google.com/p/accounts-sso/issues/detail?id=115 * Fix all memory leaks detected by valgrind * Set ID before invoking the client callback http://code.google.com/p/accounts-sso/issues/detail?id=132 * Make tests optional at configure time http://code.google.com/p/accounts-sso/issues/detail?id=124 * Documentation and build system improvements Version 1.7 ----------- * Support GValues of type GVariant http://code.google.com/p/accounts-sso/issues/detail?id=121 Version 1.6 ----------- * Be Python 3 compatible Version 1.5 ----------- * Add workaround for missing GStrv support in PyGObject * Port from dbus-glib to GDBus Version 1.4 ----------- * Update licence is tests Version 1.3 ----------- * AuthSession: let the callback unreference "self" http://code.google.com/p/accounts-sso/issues/detail?id=121 * Several improvements to tests * Distribute Vala bindings * Add Requires.private to pkg-config files Version 1.2 ----------- * Depend on latest signond * Remove support for old D-Bus API * Improve creation of GError instances * Use dbus-test-runner for running tests if available * Support new signond D-Bus API * Several API reference documentation improvements * Add GObject-Introspection for bindings * Add GType information to enums * Tidy public includes * Define SignonIdentityInfo as a new boxed type ./configure.ac0000644000004100000410000000622713013271000013523 0ustar www-datawww-datadnl Process this file with autoconf to produce a configure script. AC_PREREQ([2.64]) AC_INIT([libsignon-glib], [1.14], [https://gitlab.com/accounts-sso/libsignon-glib/issues], [libsignon-glib], [https://gitlab.com/accounts-sso/libsignon-glib]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_SRCDIR([libsignon-glib.pc.in]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([1.11 -Wall check-news nostdinc silent-rules subdir-objects foreign]) AC_PROG_CC AC_PROG_CC_STDC AM_PROG_CC_C_O LT_PREREQ([2.2]) LT_INIT([disable-static]) # Gobject Introspection GOBJECT_INTROSPECTION_CHECK([1.30.0]) PKG_CHECK_MODULES( [DEPS], [gio-2.0 >= 2.36 gio-unix-2.0 glib-2.0 >= 2.32 gobject-2.0 >= 2.35.1 signond >= 8.40]) AC_SUBST(DEPS_CFLAGS) AC_SUBST(DEPS_LIBS) # Build tests. CHECK_REQUIRED="check >= 0.9.4" AC_ARG_ENABLE([tests], [AS_HELP_STRING([--disable-tests], [build with testing support disabled])]) AS_IF([test "x$enable_tests" != "xno"], [PKG_CHECK_EXISTS([$CHECK_REQUIRED], [have_check=yes], [have_check=no])], [have_check=no]) AS_IF([test "x$have_check" = "xyes"], [PKG_CHECK_MODULES([CHECK], [$CHECK_REQUIRED]) AC_SUBST([CHECK_CFLAGS]) AC_SUBST([CHECK_LIBS])], [AS_IF([test "x$enable_tests" = "xyes"], [AC_MSG_ERROR([tests enabled but required dependencies were not found])])]) # gcov coverage reporting m4_include([m4/gcov.m4]) AC_TDD_GCOV AC_SUBST(COVERAGE_CFLAGS) AC_SUBST(COVERAGE_CXXFLAGS) AC_SUBST(COVERAGE_LDFLAGS) AM_CONDITIONAL([ENABLE_TESTS], [test "x$have_check" = "xyes"]) GTK_DOC_CHECK([1.14], [--flavour no-tmpl]) AC_ARG_ENABLE([cast-checks], [AS_HELP_STRING([--disable-cast-checks], [compile with GLib cast checks disabled])], [], [enable_cast_checks=yes]) AS_IF([test "x$enable_cast_checks" = "xno"], [CFLAGS="$CFLAGS -DG_DISABLE_CAST_CHECKS"]) AC_ARG_ENABLE([asserts], [AS_HELP_STRING([--disable-asserts], [compile with GLib assertions disabled])], [], [enable_asserts=yes]) AS_IF([test "x$enable_asserts" = "xno"], [CFLAGS="$CFLAGS -DG_DISABLE_ASSERTS"]) AC_ARG_ENABLE([checks], [AS_HELP_STRING([--disable-checks], [compile with GLib checks disabled])], [], [enable_checks=yes]) AS_IF([test "x$checks" = "xno"], [CFLAGS="$CFLAGS -DG_DISABLE_CHECKS"]) AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], [enable printing of debug messages])]) AS_IF([test "x$enable_debug" = "xyes"], [CFLAGS="$CFLAGS -DENABLE_DEBUG"]) # Python support. PYGOBJECT_REQUIRED=2.90 AC_ARG_ENABLE([python], [AS_HELP_STRING([--enable-python], [Build with python support])]) AS_IF([test "x$enable_python" != "xno"], [PKG_CHECK_EXISTS([pygobject-3.0 >= $PYGOBJECT_REQUIRED], [have_python=yes], [have_python=no])]) AS_IF([test "x$have_python" = "xyes"], [AM_PATH_PYTHON AC_SUBST([pyoverridesdir], [`$PYTHON -c "import gi;print (gi._overridesdir)" 2>/dev/null`])]) AM_CONDITIONAL([ENABLE_PYTHON], [test "x$have_python" = "xyes"]) AC_CONFIG_FILES([ Makefile libsignon-glib/Makefile libsignon-glib.pc docs/Makefile docs/reference/Makefile docs/reference/version.xml tests/Makefile pygobject/Makefile ]) AC_OUTPUT ./docs/0000755000004100000410000000000013013271000012156 5ustar www-datawww-data./docs/reference/0000755000004100000410000000000013013271000014114 5ustar www-datawww-data./docs/reference/libsignon-glib-sections.txt0000644000004100000410000000674013013271000021410 0ustar www-datawww-data
signon-auth-service SignonAuthService SignonAuthService SignonQueryMechanismCb SignonQueryMethodsCb signon_auth_service_new signon_auth_service_query_mechanisms signon_auth_service_query_methods SignonAuthServiceClass SignonAuthServicePrivate SIGNON_AUTH_SERVICE SIGNON_AUTH_SERVICE_CLASS SIGNON_AUTH_SERVICE_GET_CLASS SIGNON_IS_AUTH_SERVICE SIGNON_IS_AUTH_SERVICE_CLASS SIGNON_TYPE_AUTH_SERVICE signon_auth_service_get_type
signon-auth-session SignonAuthSession SIGNON_SESSION_DATA_CAPTION SIGNON_SESSION_DATA_PROXY SIGNON_SESSION_DATA_REALM SIGNON_SESSION_DATA_RENEW_TOKEN SIGNON_SESSION_DATA_SECRET SIGNON_SESSION_DATA_TIMEOUT SIGNON_SESSION_DATA_UI_POLICY SIGNON_SESSION_DATA_USERNAME SIGNON_SESSION_DATA_WINDOW_ID SignonAuthSession SignonAuthSessionProcessCb SignonAuthSessionQueryAvailableMechanismsCb SignonSessionDataUiPolicy signon_auth_session_cancel signon_auth_session_get_method signon_auth_session_new signon_auth_session_process signon_auth_session_process_async signon_auth_session_process_finish signon_auth_session_query_available_mechanisms SignonAuthSessionClass SignonAuthSessionPrivate SIGNON_DEPRECATED SIGNON_DEPRECATED_FOR G_DEPRECATED G_DEPRECATED_FOR SIGNON_AUTH_SESSION SIGNON_AUTH_SESSION_CLASS SIGNON_AUTH_SESSION_GET_CLASS SIGNON_IS_AUTH_SESSION SIGNON_IS_AUTH_SESSION_CLASS SIGNON_TYPE_AUTH_SESSION SIGNON_TYPE_SESSION_DATA_UI_POLICY signon_auth_session_get_type signon_session_data_ui_policy_get_type
signon-errors SignonError signon_error_quark SIGNON_ERROR SIGNON_TYPE_ERROR signon_error_get_type
signon-identity SignonIdentity SignonIdentity SignonIdentityInfoCb SignonIdentityReferenceAddedCb SignonIdentityReferenceRemovedCb SignonIdentityRemovedCb SignonIdentitySignedOutCb SignonIdentityStoreCredentialsCb SignonIdentityVerifyCb SignonIdentityVoidCb signon_identity_add_reference signon_identity_create_session signon_identity_get_last_error signon_identity_new signon_identity_new_from_db signon_identity_query_info signon_identity_remove signon_identity_remove_reference signon_identity_signout signon_identity_store_credentials_with_args signon_identity_store_credentials_with_info signon_identity_verify_secret SignonIdentityClass SignonIdentityPrivate SIGNON_IDENTITY SIGNON_IDENTITY_CLASS SIGNON_IDENTITY_GET_CLASS SIGNON_IS_IDENTITY SIGNON_IS_IDENTITY_CLASS SIGNON_TYPE_IDENTITY signon_identity_get_type
signon-identity-info SignonIdentityInfo SignonIdentityType signon_identity_info_copy signon_identity_info_free signon_identity_info_get_access_control_list signon_identity_info_get_caption signon_identity_info_get_id signon_identity_info_get_identity_type signon_identity_info_get_methods signon_identity_info_get_realms signon_identity_info_get_storing_secret signon_identity_info_get_username signon_identity_info_new signon_identity_info_remove_method signon_identity_info_set_access_control_list signon_identity_info_set_caption signon_identity_info_set_identity_type signon_identity_info_set_method signon_identity_info_set_realms signon_identity_info_set_secret signon_identity_info_set_username SIGNON_TYPE_IDENTITY_TYPE signon_identity_info_get_type signon_identity_type_get_type
./docs/reference/libsignon-glib-docs.xml0000644000004100000410000000551613013271000020472 0ustar www-datawww-data ]> libsignon-glib Reference Manual This document is for libsignon-glib, version &version;. The latest version of this documentation can be built from the source code at https://gitlab.com/accounts-sso/libsignon-glib. libsignon-glib Overview libsignon-glib provides authorization and authentication management for GLib applications. libsignon-glib Objects Object Hierarchy Credential management signond D-Bus API The signond D-Bus APIs are unstable, subject to change and should not be used by client applications, which should use libsignon-glib or libsignon-qt instead. Appendices API Index Index of deprecated symbols Index of new symbols in 1.8 ./docs/reference/version.xml.in0000644000004100000410000000002213013271000016722 0ustar www-datawww-data@PACKAGE_VERSION@ ./docs/reference/Makefile.am0000644000004100000410000000560613013271000016157 0ustar www-datawww-data## Process this file with automake to produce Makefile.in # We require automake 1.6 at least. AUTOMAKE_OPTIONS = 1.6 # This is a blank Makefile.am for using gtk-doc. # Copy this to your project's API docs directory and modify the variables to # suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples # of using the various options. # The name of the module, e.g. 'glib'. DOC_MODULE=libsignon-glib # The top-level SGML file. You can change this if you want to. DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml # The directory containing the source code. Relative to $(srcdir). # gtk-doc will search all .c & .h files beneath here for inline comments # documenting the functions and macros. # e.g. DOC_SOURCE_DIR=../../../gtk DOC_SOURCE_DIR=$(top_srcdir)/libsignon-glib # Extra options to pass to gtkdoc-scangobj. Not normally needed. SCANGOBJ_OPTIONS= # Extra options to supply to gtkdoc-scan. # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" SCAN_OPTIONS=--rebuild-types --deprecated-guards="SIGNON_DISABLE_DEPRECATED" # Extra options to supply to gtkdoc-mkdb. # e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml MKDB_OPTIONS=--source-dir=$(top_srcdir)/libsignon-glib --sgml-mode --output-format=xml --name-space=signon # Extra options to supply to gtkdoc-fixref. Not normally needed. # e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html FIXXREF_OPTIONS= # Used for dependencies. The docs will be rebuilt if any of these change. # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h # e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c HFILE_GLOB=$(top_srcdir)/libsignon-glib/signon-*.h CFILE_GLOB=$(top_srcdir)/libsignon-glib/signon-*.c # Header files to ignore when scanning. # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h IGNORE_HFILES= \ signon-auth-session-client-glib-gen.h \ signon-client-glib-gen.h \ signon-identity-glib-gen.h \ signon-internals.h \ signon-proxy.h \ signon-utils.h \ signon-marshal.h \ sso-auth-service-gen.h \ sso-auth-service.h \ sso-auth-session-gen.h \ sso-identity-gen.h # Images to copy into HTML directory. # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png HTML_IMAGES= # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). # e.g. content_files=running.sgml building.sgml changes-2.0.sgml content_files= # CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. # Only needed if you are using gtkdoc-scangobj to dynamically query widget # signals and properties. # e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) AM_CPPFLAGS=$(DEPS_CFLAGS) GTKDOC_LIBS=$(top_builddir)/libsignon-glib/libsignon-glib.la $(DEPS_LIBS) # This includes the standard gtk-doc make rules, copied by gtkdocize. include $(top_srcdir)/gtk-doc.make # Other files to distribute # e.g. EXTRA_DIST += version.xml.in #EXTRA_DIST += #if ENABLE_GTK_DOC #TESTS = $(GTKDOC_CHECK) #endif ./docs/Makefile.am0000644000004100000410000000002513013271000014207 0ustar www-datawww-dataSUBDIRS = reference ./COPYING0000644000004100000410000006350213013271000012267 0ustar www-datawww-data GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ./autogen.sh0000755000004100000410000000063613013271000013234 0ustar www-datawww-data#!/bin/sh -e srcdir=`dirname $0` test -z "$srcdir" && srcdir=. (test -f $srcdir/libsignon-glib.pc.in ) || { echo -n "Error: Directory "\`$srcdir\`" does not look like the " echo "top-level libsignon-glib directory." exit 1 } cd "$srcdir" gtkdocize --copy --flavour no-tmpl cd "$OLDPWD" autoreconf --install --force --verbose --warnings=all "$srcdir" test -n "$NOCONFIGURE" || "$srcdir/configure" "$@" ./README.md0000644000004100000410000000151513013271000012507 0ustar www-datawww-dataSingle signon authentication library for GLib applications ========================================================== This project is a library for managing single signon credentials which can be used from GLib applications. It is effectively a GLib binding for the D-Bus API provided by [signond][]. It is part of the accounts-sso project: https://gitlab.com/groups/accounts-sso Dependencies ------------ The project depends on GLib (including GIO and GObject), [signond][] and [check][]. Licence ------- The library is licensed under the GNU LGPL version 2.1. Resources --------- [API reference documentation](http://accounts-sso.gitlab.io/libsignon-glib/) [Official source code repository](https://gitlab.com/accounts-sso/libsignon-glib) [signond]: https://gitlab.com/accounts-sso/signond [check]: https://github.com/libcheck/check ./ChangeLog0000644000004100000410000000004613013271000013000 0ustar www-datawww-dataGet the changelog by running git-log. ./Makefile.am.coverage0000644000004100000410000000227613013271000015063 0ustar www-datawww-data # Coverage targets .PHONY: clean-gcda clean-gcda: @echo Removing old coverage results -$(AM_V_at)find -name '*.gcda' -print | xargs -r rm .PHONY: coverage-html generate-coverage-html clean-coverage-html coverage-html: clean-gcda -$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) generate-coverage-html if HAVE_GCOV generate-coverage-html: @echo Collecting coverage data $(AM_V_at)$(LCOV) --directory $(top_builddir) --capture --output-file coverage.info --no-checksum --compat-libtool $(AM_V_at)$(LCOV) --remove coverage.info signon-enum-types.c signon-errors-enum.c signon-marshal.c "sso-*-gen.*" -o coverage.info # autogenerated files $(AM_V_at)LANG=C $(GENHTML) --prefix $(top_builddir) --output-directory coveragereport --title "Code Coverage" --legend --show-details coverage.info clean-coverage-html: clean-gcda -$(AM_V_at)$(LCOV) --directory $(top_builddir) -z -$(AM_V_at)rm -rf coverage.info coveragereport clean-local: clean-coverage-html else generate-coverage-html: $(AM_V_at)echo "Code coverage reporting not available" clean-coverage-html: clean-gcda -$(AM_V_at)rm -rf coverage.info coveragereport clean-local: clean-coverage-html endif # HAVE_GCOV ./pygobject/0000755000004100000410000000000013013271000013214 5ustar www-datawww-data./pygobject/Signon.py0000644000004100000410000000137113013271000015025 0ustar www-datawww-datafrom ..overrides import override from ..importer import modules from gi.repository import GObject Signon = modules['Signon']._introspection_module __all__ = [] class GStrv(list): __gtype__ = GObject.type_from_name('GStrv') class AuthSession(Signon.AuthSession): # Convert list of strings into a GStrv def process(self, session_data, mechanism, callback, userdata): cleaned_data = {} for (key, value) in session_data.items(): if isinstance(value, list): cleaned_data[key] = GStrv(value) else: cleaned_data[key] = value Signon.AuthSession.process(self, cleaned_data, mechanism, callback, userdata) AuthSession = override(AuthSession) __all__.append('AuthSession') ./pygobject/Makefile.am0000644000004100000410000000010213013271000015241 0ustar www-datawww-dataoverridesdir = $(pyoverridesdir) overrides_PYTHON = \ Signon.py ./tests/0000755000004100000410000000000013013271000012370 5ustar www-datawww-data./tests/tests.xml0000644000004100000410000000112713013271000014255 0ustar www-datawww-data /usr/bin/signon-glib-test.sh true true ./tests/signon-glib-test-wrapper.sh0000755000004100000410000000012413013271000017567 0ustar www-datawww-data#!/bin/sh exec "$(pwd)/../libtool" --mode=execute $WRAPPER ./signon-glib-testsuite ./tests/signon-glib-test.sh0000755000004100000410000000207513013271000016120 0ustar www-datawww-data#!/bin/sh # Environment variables for the signon daemon export SSO_LOGGING_LEVEL=2 export SSO_STORAGE_PATH="/tmp" export SSO_DAEMON_TIMEOUT=1 export SSO_IDENTITY_TIMEOUT=3 export SSO_AUTHSESSION_TIMEOUT=3 export SSO_EXTENSIONS_DIR="/tmp" # this disables all extensions #Environment variables for the test application export G_MESSAGES_DEBUG=all # If running the test executable under a wrapper, setup the tests so that the # wrapper can debug them more easily. if [ -n "$WRAPPER" ]; then export G_SLICE=always-malloc export CK_FORK="no" else export G_SLICE=debug-blocks fi TEST_APP="$TESTDIR/signon-glib-test-wrapper.sh" # If dbus-test-runner exists, use it to run the tests in a separate D-Bus # session if command -v dbus-test-runner > /dev/null ; then echo "Using dbus-test-runner" dbus-test-runner -m 180 --keep-env \ -t signond -r \ -t "$TEST_APP" -f com.google.code.AccountsSSO.SingleSignOn else echo "Using existing D-Bus session" pkill signond || true trap "pkill -9 signond" EXIT signond & sleep 2 $TEST_APP fi ./tests/check_signon.c0000644000004100000410000014213013013271000015167 0ustar www-datawww-data/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of libsignon-glib * * Copyright (C) 2009-2011 Nokia Corporation. * Copyright (C) 2011-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 */ /** * @example check_signon.c * Shows how to initialize the framework. */ #define SIGNON_DISABLE_DEPRECATION_WARNINGS #include "libsignon-glib/signon-internals.h" #include "libsignon-glib/signon-auth-service.h" #include "libsignon-glib/signon-auth-session.h" #include "libsignon-glib/signon-identity.h" #include "libsignon-glib/signon-errors.h" #include #include #include #include #include static GMainLoop *main_loop = NULL; static SignonIdentity *identity = NULL; static SignonAuthService *auth_service = NULL; #define SIGNOND_IDLE_TIMEOUT (5 + 2) static gboolean _contains(gchar **list, gchar *item) { gboolean present = FALSE; gint i = 0; while (list[i] != NULL) { if (g_strcmp0 (item, list[i]) == 0) present = TRUE; i++; } return present; } static void end_test () { if (auth_service) { g_object_unref (auth_service); auth_service = NULL; } if (identity) { g_object_unref (identity); identity = NULL; } if (main_loop) { g_main_loop_quit (main_loop); g_main_loop_unref (main_loop); main_loop = NULL; } } static gboolean quit_loop (gpointer user_data) { GMainLoop *loop = user_data; g_main_loop_quit (loop); return FALSE; } static void run_main_loop_for_n_seconds(guint seconds) { GMainLoop *loop = g_main_loop_new (NULL, FALSE); g_timeout_add_seconds (seconds, quit_loop, loop); g_main_loop_run (loop); g_main_loop_unref (loop); } START_TEST(test_init) { g_debug("%s", G_STRFUNC); auth_service = signon_auth_service_new (); main_loop = g_main_loop_new (NULL, FALSE); fail_unless (SIGNON_IS_AUTH_SERVICE (auth_service), "Failed to initialize the AuthService."); end_test (); } END_TEST 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 (main_loop); fail(); } gboolean has_ssotest = FALSE; fail_unless (g_strcmp0 (user_data, "Hello") == 0, "Got wrong string"); fail_unless (methods != NULL, "The methods does not exist"); while (*methods) { if (g_strcmp0 (*methods, "ssotest") == 0) { has_ssotest = TRUE; break; } methods++; } fail_unless (has_ssotest, "ssotest method does not exist"); g_main_loop_quit (main_loop); } START_TEST(test_query_methods) { g_debug("%s", G_STRFUNC); if(!main_loop) main_loop = g_main_loop_new (NULL, FALSE); auth_service = signon_auth_service_new (); fail_unless (SIGNON_IS_AUTH_SERVICE (auth_service), "Failed to initialize the AuthService."); signon_auth_service_query_methods (auth_service, (SignonQueryMethodsCb)signon_query_methods_cb, "Hello"); g_main_loop_run (main_loop); end_test (); } END_TEST 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 (main_loop); fail(); } gboolean has_mech1 = FALSE; gboolean has_mech2 = FALSE; gboolean has_mech3 = FALSE; fail_unless (strcmp (user_data, "Hello") == 0, "Got wrong string"); fail_unless (mechanisms != NULL, "The mechanisms does not exist"); while (*mechanisms) { if (g_strcmp0 (*mechanisms, "mech1") == 0) has_mech1 = TRUE; if (g_strcmp0 (*mechanisms, "mech2") == 0) has_mech2 = TRUE; if (g_strcmp0 (*mechanisms, "mech3") == 0) has_mech3 = TRUE; mechanisms++; } fail_unless (has_mech1, "mech1 mechanism does not exist"); fail_unless (has_mech2, "mech2 mechanism does not exist"); fail_unless (has_mech3, "mech3 mechanism does not exist"); g_main_loop_quit (main_loop); } static void signon_query_mechanisms_cb_fail (SignonAuthService *auth_service, gchar *method, gchar **mechanisms, GError *error, gpointer user_data) { fail_unless (error != NULL); fail_unless (mechanisms == NULL); fail_unless (error->domain == SIGNON_ERROR); fail_unless (error->code == SIGNON_ERROR_METHOD_NOT_KNOWN); g_main_loop_quit (main_loop); } START_TEST(test_query_mechanisms) { g_debug("%s", G_STRFUNC); auth_service = signon_auth_service_new (); fail_unless (SIGNON_IS_AUTH_SERVICE (auth_service), "Failed to initialize the AuthService."); signon_auth_service_query_mechanisms (auth_service, "ssotest", (SignonQueryMechanismCb)signon_query_mechanisms_cb, "Hello"); if(!main_loop) main_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (main_loop); /* Test a non existing method */ signon_auth_service_query_mechanisms (auth_service, "non-existing", (SignonQueryMechanismCb)signon_query_mechanisms_cb_fail, "Hello"); g_main_loop_run (main_loop); end_test (); } END_TEST static void test_auth_session_query_mechanisms_cb (SignonAuthSession *self, gchar **mechanisms, const GError *error, gpointer user_data) { if (error) { g_warning ("%s: %s", G_STRFUNC, error->message); g_main_loop_quit (main_loop); fail(); } fail_unless (mechanisms != NULL, "The mechanisms does not exist"); gchar** patterns = (gchar**)user_data; int i = g_strv_length(mechanisms); fail_unless( i == g_strv_length(patterns), "The number of obtained methods is wrong: %d %s", i); while ( i > 0 ) { gchar* pattern = patterns[--i]; fail_unless(_contains(mechanisms, pattern), "The obtained mechanism list does not contain %s", pattern); } g_strfreev(mechanisms); g_main_loop_quit (main_loop); } START_TEST(test_auth_session_query_mechanisms) { GError *err = NULL; g_debug("%s", G_STRFUNC); SignonIdentity *idty = signon_identity_new(NULL, NULL); fail_unless (idty != NULL, "Cannot create Iddentity object"); SignonAuthSession *auth_session = signon_identity_create_session(idty, "ssotest", &err); fail_unless (auth_session != NULL, "Cannot create AuthSession object"); g_clear_error(&err); gchar* patterns[4]; patterns[0] = g_strdup("mech1"); patterns[1] = g_strdup("mech2"); patterns[2] = g_strdup("mech3"); patterns[3] = NULL; signon_auth_session_query_available_mechanisms(auth_session, (const gchar**)patterns, test_auth_session_query_mechanisms_cb, (gpointer)patterns); if(!main_loop) main_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (main_loop); g_free(patterns[2]); patterns[2] = NULL; signon_auth_session_query_available_mechanisms(auth_session, (const gchar**)patterns, test_auth_session_query_mechanisms_cb, (gpointer)patterns); g_main_loop_run (main_loop); g_free(patterns[1]); patterns[1] = NULL; signon_auth_session_query_available_mechanisms(auth_session, (const gchar**)patterns, test_auth_session_query_mechanisms_cb, (gpointer)patterns); g_main_loop_run (main_loop); g_free(patterns[0]); g_object_unref(auth_session); g_object_unref(idty); end_test (); } END_TEST static void test_auth_session_query_mechanisms_nonexisting_cb (SignonAuthSession *self, gchar **mechanisms, const GError *error, gpointer user_data) { if (!error) { g_main_loop_quit (main_loop); fail(); return; } g_warning ("%s: %s", G_STRFUNC, error->message); g_main_loop_quit (main_loop); } START_TEST(test_auth_session_query_mechanisms_nonexisting) { GError *err = NULL; g_debug("%s", G_STRFUNC); SignonIdentity *idty = signon_identity_new(NULL, NULL); fail_unless (idty != NULL, "Cannot create Iddentity object"); SignonAuthSession *auth_session = signon_identity_create_session(idty, "nonexisting", &err); fail_unless (auth_session != NULL, "Cannot create AuthSession object"); g_clear_error(&err); gchar* patterns[4]; patterns[0] = g_strdup("mech1"); patterns[1] = g_strdup("mech2"); patterns[2] = g_strdup("mech3"); patterns[3] = NULL; signon_auth_session_query_available_mechanisms(auth_session, (const gchar**)patterns, test_auth_session_query_mechanisms_nonexisting_cb, (gpointer)patterns); if(!main_loop) main_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (main_loop); g_free(patterns[0]); g_free(patterns[1]); g_free(patterns[2]); g_object_unref(auth_session); g_object_unref(idty); end_test (); } END_TEST static void test_auth_session_states_cb (SignonAuthSession *self, gint state, gchar *message, gpointer user_data) { gint *state_counter = (gint *)user_data; (*state_counter)++; } static void test_auth_session_process_cb (SignonAuthSession *self, GHashTable *sessionData, const GError *error, gpointer user_data) { if (error) { g_warning ("%s: %s", G_STRFUNC, error->message); g_main_loop_quit (main_loop); fail(); } fail_unless (sessionData != NULL, "The result is empty"); gchar* usernameKey = g_strdup(SIGNON_SESSION_DATA_USERNAME); GValue* usernameVa = (GValue*)g_hash_table_lookup(sessionData, usernameKey); gchar* realmKey = g_strdup(SIGNON_SESSION_DATA_REALM); GValue* realmVa = (GValue*)g_hash_table_lookup(sessionData, realmKey); fail_unless(g_strcmp0(g_value_get_string(usernameVa), "test_username") == 0, "Wrong value of username"); fail_unless(g_strcmp0(g_value_get_string(realmVa), "testRealm_after_test") == 0, "Wrong value of realm"); g_free(usernameKey); g_free(realmKey); g_main_loop_quit (main_loop); } START_TEST(test_auth_session_creation) { GError *err = NULL; gpointer auth_session_sentinel; gpointer idty_sentinel; g_debug("%s", G_STRFUNC); SignonIdentity *idty = signon_identity_new(NULL, NULL); fail_unless (idty != NULL, "Cannot create Iddentity object"); SignonAuthSession *auth_session = signon_identity_create_session(idty, "ssotest", &err); fail_unless (auth_session != NULL, "Cannot create AuthSession object"); g_object_add_weak_pointer (G_OBJECT (idty), &idty_sentinel); g_object_add_weak_pointer (G_OBJECT (auth_session), &auth_session_sentinel); g_object_unref (idty); fail_unless (SIGNON_IS_IDENTITY(idty), "Identity must stay untill all its session are not destroyed"); g_object_unref (auth_session); fail_if (auth_session_sentinel != NULL, "AuthSession is not synchronized with parent Identity"); fail_if (idty_sentinel != NULL, "Identity is not synchronized with its AuthSession"); g_clear_error(&err); } END_TEST START_TEST(test_auth_session_process) { gint state_counter = 0; GError *err = NULL; g_debug("%s", G_STRFUNC); SignonIdentity *idty = signon_identity_new(NULL, NULL); fail_unless (idty != NULL, "Cannot create Iddentity object"); SignonAuthSession *auth_session = signon_identity_create_session(idty, "ssotest", &err); fail_unless (auth_session != NULL, "Cannot create AuthSession object"); g_clear_error(&err); g_signal_connect(auth_session, "state-changed", G_CALLBACK(test_auth_session_states_cb), &state_counter); GHashTable* sessionData = g_hash_table_new(g_str_hash, g_str_equal); GValue* usernameVa = g_new0(GValue, 1); gchar* usernameKey = g_strdup(SIGNON_SESSION_DATA_USERNAME); g_value_init (usernameVa, G_TYPE_STRING); g_value_set_static_string(usernameVa, "test_username"); g_hash_table_insert (sessionData, usernameKey, usernameVa); GValue* passwordVa = g_new0(GValue, 1); gchar* passwordKey = g_strdup(SIGNON_SESSION_DATA_SECRET); g_value_init (passwordVa, G_TYPE_STRING); g_value_set_static_string(passwordVa, "test_username"); g_hash_table_insert (sessionData, passwordKey, passwordVa); signon_auth_session_process(auth_session, sessionData, "mech1", test_auth_session_process_cb, sessionData); main_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (main_loop); fail_unless (state_counter == 12, "Wrong numer of state change signals: %d", state_counter); state_counter = 0; signon_auth_session_process(auth_session, sessionData, "mech1", test_auth_session_process_cb, sessionData); g_main_loop_run (main_loop); fail_unless (state_counter == 12, "Wrong numer of state change signals: %d", state_counter); state_counter = 0; signon_auth_session_process(auth_session, sessionData, "mech1", test_auth_session_process_cb, sessionData); g_main_loop_run (main_loop); fail_unless (state_counter == 12, "Wrong numer of state change signals: %d", state_counter); state_counter = 0; g_object_unref (auth_session); g_object_unref (idty); g_value_unset(usernameVa); g_free(usernameVa); g_free(usernameKey); g_value_unset(passwordVa); g_free(passwordVa); g_free(passwordKey); g_hash_table_unref (sessionData); end_test (); } END_TEST static void test_auth_session_process_async_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { SignonAuthSession *auth_session = SIGNON_AUTH_SESSION (source_object); GVariant **v_reply = user_data; GError *error = NULL; fail_unless (SIGNON_IS_AUTH_SESSION (source_object)); *v_reply = signon_auth_session_process_finish (auth_session, res, &error); fail_unless (error == NULL); g_main_loop_quit (main_loop); } START_TEST(test_auth_session_process_async) { gint state_counter = 0; GError *err = NULL; GVariantBuilder builder; GVariant *session_data, *reply; gchar *username, *realm; gboolean ok; g_debug("%s", G_STRFUNC); SignonIdentity *idty = signon_identity_new(NULL, NULL); fail_unless (idty != NULL, "Cannot create Iddentity object"); SignonAuthSession *auth_session = signon_identity_create_session(idty, "ssotest", &err); fail_unless (auth_session != NULL, "Cannot create AuthSession object"); g_clear_error(&err); g_signal_connect(auth_session, "state-changed", G_CALLBACK(test_auth_session_states_cb), &state_counter); g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); g_variant_builder_add (&builder, "{sv}", SIGNON_SESSION_DATA_USERNAME, g_variant_new_string ("test_username")); g_variant_builder_add (&builder, "{sv}", SIGNON_SESSION_DATA_SECRET, g_variant_new_string ("test_pw")); session_data = g_variant_builder_end (&builder); signon_auth_session_process_async (auth_session, session_data, "mech1", NULL, test_auth_session_process_async_cb, &reply); main_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (main_loop); fail_unless (state_counter == 12, "Wrong numer of state change signals: %d", state_counter); fail_unless (reply != NULL); session_data = NULL; ok = g_variant_lookup (reply, SIGNON_SESSION_DATA_USERNAME, "&s", &username); ck_assert (ok); ck_assert_str_eq (username, "test_username"); ok = g_variant_lookup (reply, SIGNON_SESSION_DATA_REALM, "&s", &realm); ck_assert (ok); ck_assert_str_eq (realm, "testRealm_after_test"); g_variant_unref (reply); g_object_unref (auth_session); g_object_unref (idty); end_test (); } END_TEST static void test_auth_session_process_failure_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { SignonAuthSession *auth_session = SIGNON_AUTH_SESSION (source_object); GVariant *v_reply; GError **error = user_data; fail_unless (SIGNON_IS_AUTH_SESSION (source_object)); v_reply = signon_auth_session_process_finish (auth_session, res, error); fail_unless (v_reply == NULL); g_main_loop_quit (main_loop); } START_TEST(test_auth_session_process_failure) { SignonAuthSession *auth_session; GVariantBuilder builder; GVariant *session_data; GError *error = NULL; g_debug("%s", G_STRFUNC); auth_session = signon_auth_session_new (0, "nonexisting-method", &error); fail_unless (auth_session != NULL, "Cannot create AuthSession object"); fail_unless (error == NULL); g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); g_variant_builder_add (&builder, "{sv}", "key", g_variant_new_string ("value")); session_data = g_variant_builder_end (&builder); signon_auth_session_process_async (auth_session, session_data, "mech1", NULL, test_auth_session_process_failure_cb, &error); main_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (main_loop); fail_unless (error != NULL); fail_unless (error->domain == SIGNON_ERROR); fail_unless (error->code == SIGNON_ERROR_METHOD_NOT_KNOWN); g_error_free (error); g_object_unref (auth_session); end_test (); } END_TEST static void test_auth_session_process_after_store_cb (SignonAuthSession *self, GHashTable *reply, const GError *error, gpointer user_data) { GValue *v_username; if (error != NULL) { fail("Got error: %s", error->message); g_main_loop_quit (main_loop); return; } fail_unless (reply != NULL, "The result is empty"); v_username = g_hash_table_lookup(reply, SIGNON_SESSION_DATA_USERNAME); fail_unless (g_strcmp0 (g_value_get_string (v_username), "Nice user") == 0, "Wrong value of username"); g_object_unref (self); g_main_loop_quit (main_loop); } static void test_auth_session_process_after_store_start_session(SignonIdentity *self, guint32 id, const GError *error, gpointer user_data) { GError *err = NULL; if (error != NULL) { g_warning ("%s %d: %s", G_STRFUNC, __LINE__, error->message); fail(); g_main_loop_quit (main_loop); return; } fail_unless (id > 0); SignonAuthSession *auth_session = signon_identity_create_session (self, "ssotest", &err); fail_unless (auth_session != NULL, "Cannot create AuthSession object"); if (err != NULL) { fail ("Got error: %s", err->message); g_clear_error (&err); } GHashTable *session_data = g_hash_table_new (g_str_hash, g_str_equal); signon_auth_session_process (auth_session, session_data, "mech1", test_auth_session_process_after_store_cb, NULL); g_hash_table_unref (session_data); } START_TEST(test_auth_session_process_after_store) { SignonIdentityInfo *info; SignonIdentity *identity; const gchar *const acl[] = { "*", NULL }; g_debug("%s", G_STRFUNC); main_loop = g_main_loop_new (NULL, FALSE); identity = signon_identity_new (); fail_unless (SIGNON_IS_IDENTITY (identity), "Failed to initialize the Identity."); info = signon_identity_info_new (); signon_identity_info_set_username (info, "Nice user"); signon_identity_info_set_access_control_list (info, acl); signon_identity_store_credentials_with_info (identity, info, test_auth_session_process_after_store_start_session, NULL); g_main_loop_run (main_loop); g_object_unref (identity); signon_identity_info_free (info); end_test (); } END_TEST static GHashTable *create_methods_hashtable() { gchar *mechanisms[] = { "mechanism1", "mechanism2", "mechanism3", NULL }; GHashTable *methods = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_strfreev); g_hash_table_insert (methods, g_strdup("method1"), g_strdupv(mechanisms)); g_hash_table_insert (methods, g_strdup("method2"), g_strdupv(mechanisms)); g_hash_table_insert (methods, g_strdup("method3"), g_strdupv(mechanisms)); return methods; } static void new_identity_store_credentials_cb(SignonIdentity *self, guint32 id, const GError *error, gpointer user_data) { gint *new_id = user_data; if(error) { g_warning ("%s %d: %s", G_STRFUNC, __LINE__, error->message); fail(); } fail_unless (id > 0); *new_id = id; g_object_unref (self); g_main_loop_quit (main_loop); } static guint new_identity() { SignonIdentity *identity; GHashTable *methods; const gchar *const acl[] = { "*", NULL }; guint id = 0; identity = signon_identity_new(NULL, NULL); fail_unless (SIGNON_IS_IDENTITY (identity)); methods = g_hash_table_new (g_str_hash, g_str_equal); signon_identity_store_credentials_with_args (identity, "James Bond", "007", 1, methods, "caption", NULL, acl, 0, new_identity_store_credentials_cb, &id); g_hash_table_destroy (methods); if (id == 0) g_main_loop_run (main_loop); return id; } static gboolean identity_registered_cb (gpointer data) { g_main_loop_quit (main_loop); return FALSE; } START_TEST(test_get_existing_identity) { g_debug("%s", G_STRFUNC); main_loop = g_main_loop_new (NULL, FALSE); guint id = new_identity(); fail_unless (id != 0); identity = signon_identity_new_from_db(id); fail_unless (identity != NULL); fail_unless (SIGNON_IS_IDENTITY (identity), "Failed to initialize the Identity."); g_timeout_add (1000, identity_registered_cb, identity); g_main_loop_run (main_loop); end_test (); } END_TEST START_TEST(test_get_nonexisting_identity) { g_debug("%s", G_STRFUNC); identity = signon_identity_new_from_db(G_MAXINT); fail_unless (identity != NULL); fail_unless (SIGNON_IS_IDENTITY (identity), "Failed to initialize the Identity."); g_timeout_add (1000, identity_registered_cb, identity); main_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (main_loop); const GError *error = NULL; error = signon_identity_get_last_error(identity); fail_unless (error != NULL); fail_unless (error->domain == SIGNON_ERROR); fail_unless (error->code == SIGNON_ERROR_IDENTITY_NOT_FOUND || error->code == SIGNON_ERROR_PERMISSION_DENIED); end_test (); } END_TEST static void store_credentials_identity_cb(SignonIdentity *self, guint32 id, const GError *error, gpointer user_data) { if(error) { g_warning ("%s %d: %s", G_STRFUNC, __LINE__, error->message); fail(); } fail_unless (id > 0); if (user_data != NULL) { gint *last_id = (gint *)user_data; g_warning ("%s (prev_id vs new_id): %d vs %d", G_STRFUNC, *last_id, id); fail_unless (id == (*last_id) + 1); (*last_id) += 1; } /* Wait some time to ensure that the info-updated signals are * processed */ g_timeout_add_seconds (2, quit_loop, main_loop); } START_TEST(test_store_credentials_identity) { g_debug("%s", G_STRFUNC); SignonIdentity *idty = signon_identity_new(NULL, NULL); fail_unless (idty != NULL); fail_unless (SIGNON_IS_IDENTITY (idty), "Failed to initialize the Identity."); main_loop = g_main_loop_new (NULL, FALSE); gint last_id = new_identity(); GHashTable *methods = create_methods_hashtable(); signon_identity_store_credentials_with_args (idty, "James Bond", "007", 1, methods, "caption", NULL, NULL, 0, store_credentials_identity_cb, &last_id); g_hash_table_destroy (methods); g_main_loop_run (main_loop); g_object_unref(idty); end_test (); } END_TEST static void identity_verify_secret_cb(SignonIdentity *self, gboolean valid, const GError *error, gpointer user_data) { fail_unless (error == NULL, "The callback returned error for proper secret"); fail_unless (valid == TRUE, "The callback gives FALSE for proper secret"); g_main_loop_quit((GMainLoop *)user_data); } static void identity_verify_username_cb(SignonIdentity *self, gboolean valid, const GError *error, gpointer user_data) { fail_unless (error != NULL, "The callback returned NULL error for unimplemented function"); g_warning ("Error: %s ", error->message); g_main_loop_quit((GMainLoop *)user_data); } START_TEST(test_verify_secret_identity) { const gchar *const acl[] = { "*", NULL }; g_debug("%s", G_STRFUNC); SignonIdentity *idty = signon_identity_new(NULL, NULL); fail_unless (idty != NULL); fail_unless (SIGNON_IS_IDENTITY (idty), "Failed to initialize the Identity."); GHashTable *methods = create_methods_hashtable(); gchar username[] = "James Bond"; gchar secret[] = "007"; gchar caption[] = "caption"; main_loop = g_main_loop_new (NULL, FALSE); signon_identity_store_credentials_with_args (idty, username, secret, 1, methods, caption, NULL, acl, 0, store_credentials_identity_cb, NULL); g_main_loop_run (main_loop); signon_identity_verify_secret(idty, secret, identity_verify_secret_cb, main_loop); g_main_loop_run (main_loop); g_hash_table_destroy (methods); g_object_unref (idty); end_test (); } END_TEST static void identity_remove_cb(SignonIdentity *self, const GError *error, gpointer user_data) { g_warning (" %s ", __func__); if (error) { g_warning ("Error: %s ", error->message); fail_if (user_data == NULL, "There should be no error in callback"); } else { g_warning ("No error"); fail_if (user_data != NULL, "The callback must return an error"); } g_main_loop_quit(main_loop); } START_TEST(test_remove_identity) { g_debug("%s", G_STRFUNC); SignonIdentity *idty = signon_identity_new(); fail_unless (idty != NULL); fail_unless (SIGNON_IS_IDENTITY (idty), "Failed to initialize the Identity."); main_loop = g_main_loop_new (NULL, FALSE); /* * Try to remove non-stored idetnity * */ signon_identity_remove(idty, identity_remove_cb, NULL); g_main_loop_run (main_loop); /* * Try to remove existing identy * */ gint id = new_identity(); SignonIdentity *idty2 = signon_identity_new_from_db (id); signon_identity_remove(idty2, identity_remove_cb, NULL); g_main_loop_run (main_loop); /* * Try to remove already removed * */ signon_identity_remove(idty2, identity_remove_cb, GINT_TO_POINTER(TRUE)); g_object_unref (idty); g_object_unref (idty2); end_test (); } END_TEST static void identity_info_cb(SignonIdentity *self, const SignonIdentityInfo *info, const GError *error, gpointer user_data) { if (error) { g_warning ("%s: Error: %s ", __func__, error->message); fail_if (info != NULL, "Error: %s ", error->message); g_main_loop_quit(main_loop); return; } g_warning ("No error"); SignonIdentityInfo **pattern_ptr = (SignonIdentityInfo **)user_data; SignonIdentityInfo *pattern = NULL; if (pattern_ptr) pattern = (*pattern_ptr); if (pattern == NULL) fail_unless (info == NULL, "The info must be NULL"); else { fail_unless (info != NULL, "The info must be non-null"); fail_unless (g_strcmp0 (signon_identity_info_get_username(info), signon_identity_info_get_username(pattern)) == 0, "The info has wrong username"); fail_unless (g_strcmp0 (signon_identity_info_get_caption(info), signon_identity_info_get_caption(pattern)) == 0, "The info has wrong caption"); GHashTable *methods = (GHashTable *)signon_identity_info_get_methods (info); gchar **mechs1 = g_hash_table_lookup (methods, "method1"); gchar **mechs2 = g_hash_table_lookup (methods, "method2"); gchar **mechs3 = g_hash_table_lookup (methods, "method3"); fail_unless (g_strv_length (mechs1) == 3); fail_unless (g_strv_length (mechs2) == 3); fail_unless (g_strv_length (mechs3) == 3); fail_unless (_contains(mechs1, "mechanism1")); fail_unless (_contains(mechs1, "mechanism2")); fail_unless (_contains(mechs1, "mechanism3")); fail_unless (_contains(mechs2, "mechanism1")); fail_unless (_contains(mechs2, "mechanism2")); fail_unless (_contains(mechs2, "mechanism3")); fail_unless (_contains(mechs3, "mechanism1")); fail_unless (_contains(mechs3, "mechanism2")); fail_unless (_contains(mechs3, "mechanism3")); } if (info && pattern_ptr) { signon_identity_info_free (pattern); *pattern_ptr = signon_identity_info_copy (info); } g_main_loop_quit(main_loop); } static SignonIdentityInfo *create_standard_info() { const gchar *const acl[] = { "*", NULL }; g_debug("%s", G_STRFUNC); SignonIdentityInfo *info = signon_identity_info_new (); signon_identity_info_set_username (info, "James Bond"); signon_identity_info_set_secret (info, "007", TRUE); signon_identity_info_set_caption (info, "caption"); gchar *mechanisms[] = { "mechanism1", "mechanism2", "mechanism3", NULL }; signon_identity_info_set_method (info, "method1", (const gchar **)mechanisms); signon_identity_info_set_method (info, "method2", (const gchar **)mechanisms); signon_identity_info_set_method (info, "method3", (const gchar **)mechanisms); signon_identity_info_set_access_control_list (info, acl); return info; } START_TEST(test_info_identity) { const gchar *const acl[] = { "*", NULL }; g_debug("%s", G_STRFUNC); SignonIdentity *idty = signon_identity_new(); fail_unless (idty != NULL); fail_unless (SIGNON_IS_IDENTITY (idty), "Failed to initialize the Identity."); SignonIdentityInfo *info = NULL; main_loop = g_main_loop_new (NULL, FALSE); /* * Try to get_info for non-stored idetnity * */ signon_identity_query_info (idty, identity_info_cb, &info); g_main_loop_run (main_loop); GHashTable *methods = create_methods_hashtable(); signon_identity_store_credentials_with_args (idty, "James Bond", "007", 1, methods, "caption", NULL, acl, 0, store_credentials_identity_cb, NULL); g_hash_table_destroy (methods); g_main_loop_run (main_loop); info = signon_identity_info_new (); signon_identity_info_set_username (info, "James Bond"); signon_identity_info_set_secret (info, "007", TRUE); signon_identity_info_set_caption (info, "caption"); gchar *mechanisms[] = { "mechanism1", "mechanism2", "mechanism3", NULL }; signon_identity_info_set_method (info, "method1", (const gchar **)mechanisms); signon_identity_info_set_method (info, "method2", (const gchar **)mechanisms); signon_identity_info_set_method (info, "method3", (const gchar **)mechanisms); signon_identity_query_info (idty, identity_info_cb, &info); g_main_loop_run (main_loop); gint id = signon_identity_info_get_id (info); fail_unless (id != 0); SignonIdentity *idty2 = signon_identity_new_from_db (id); signon_identity_query_info (idty2, identity_info_cb, &info); g_main_loop_run (main_loop); /* * Try to update one identity and * have a look what will happen * */ signon_identity_info_set_username (info, "James Bond_2nd version"); signon_identity_info_set_caption (info, "caption_2nd version"); signon_identity_store_credentials_with_info (idty2, info, store_credentials_identity_cb, NULL); g_main_loop_run (main_loop); signon_identity_query_info (idty, identity_info_cb, &info); g_main_loop_run (main_loop); /* * Try to remove existing identity and * have a look what will happen * */ signon_identity_remove(idty2, identity_remove_cb, NULL); g_main_loop_run (main_loop); signon_identity_query_info (idty2, identity_info_cb, NULL); g_main_loop_run (main_loop); signon_identity_query_info (idty, identity_info_cb, NULL); g_main_loop_run (main_loop); signon_identity_info_free (info); g_object_unref (idty); g_object_unref (idty2); end_test (); } END_TEST static void identity_signout_cb (SignonIdentity *self, const GError *error, gpointer user_data) { if (error) g_warning ("%s: %s", G_STRFUNC, error->message); else g_warning ("%s: No error", G_STRFUNC); fail_unless (error == NULL, "There should be no error in callback"); g_main_loop_quit (main_loop); } static void identity_signout_signal_cb (gpointer instance, gpointer user_data) { gint *incr = (gint *)user_data; (*incr) = (*incr) + 1; g_warning ("%s: %d", G_STRFUNC, *incr); } START_TEST(test_signout_identity) { gpointer as1_sentinel, as2_sentinel; g_debug("%s", G_STRFUNC); SignonIdentity *idty = signon_identity_new(); fail_unless (idty != NULL); fail_unless (SIGNON_IS_IDENTITY (idty), "Failed to initialize the Identity."); SignonIdentityInfo *info = create_standard_info(); main_loop = g_main_loop_new (NULL, FALSE); signon_identity_store_credentials_with_info (idty, info, store_credentials_identity_cb, NULL); g_main_loop_run (main_loop); signon_identity_query_info (idty, identity_info_cb, &info); g_main_loop_run (main_loop); gint id = signon_identity_info_get_id (info); SignonIdentity *idty2 = signon_identity_new_from_db (id); /* wait some more time to ensure that the object gets registered */ run_main_loop_for_n_seconds(2); signon_identity_info_free (info); GError *err = NULL; SignonAuthSession *as1 = signon_identity_create_session (idty, "ssotest", &err); fail_unless (as1 != NULL, "cannot create AuthSession"); SignonAuthSession *as2 = signon_identity_create_session (idty2, "ssotest", &err); fail_unless (as2 != NULL, "cannot create AuthSession"); gint counter = 0; g_signal_connect (idty, "signout", G_CALLBACK(identity_signout_signal_cb), &counter); g_signal_connect (idty2, "signout", G_CALLBACK(identity_signout_signal_cb), &counter); g_object_add_weak_pointer (G_OBJECT (as1), &as1_sentinel); g_object_add_weak_pointer (G_OBJECT (as2), &as2_sentinel); signon_identity_signout (idty, identity_signout_cb, NULL); g_main_loop_run (main_loop); fail_unless (counter == 2, "Lost some of SIGNOUT signals"); fail_if (as1_sentinel != NULL, "Authsession1 was not destroyed after signout"); fail_if (as2_sentinel != NULL, "Authsession2 was not destroyed after signout"); g_object_unref (idty); g_object_unref (idty2); end_test (); } END_TEST START_TEST(test_unregistered_identity) { g_debug("%s", G_STRFUNC); SignonIdentity *idty = signon_identity_new(); fail_unless (idty != NULL); fail_unless (SIGNON_IS_IDENTITY (idty), "Failed to initialize the Identity."); SignonIdentityInfo *info = create_standard_info(); main_loop = g_main_loop_new (NULL, FALSE); signon_identity_store_credentials_with_info (idty, info, store_credentials_identity_cb, NULL); g_main_loop_run (main_loop); /* * give the time for identity to became idle * */ sleep(SIGNOND_IDLE_TIMEOUT); SignonIdentity *idty2 = signon_identity_new(); /* * give time to handle unregistered signal * */ //run_main_loop_for_n_seconds(5); signon_identity_query_info (idty, identity_info_cb, &info); g_main_loop_run (main_loop); signon_identity_info_free (info); g_object_unref (idty); g_object_unref (idty2); end_test (); } END_TEST START_TEST(test_unregistered_auth_session) { GVariantBuilder builder; GVariant *session_data; GVariant *reply = NULL; gchar *username; gboolean ok; g_debug("%s", G_STRFUNC); SignonIdentity *idty = signon_identity_new(); fail_unless (idty != NULL); fail_unless (SIGNON_IS_IDENTITY (idty), "Failed to initialize the Identity."); main_loop = g_main_loop_new (NULL, FALSE); GError *err = NULL; SignonAuthSession *as = signon_identity_create_session(idty, "ssotest", &err); /* give time to register the objects */ run_main_loop_for_n_seconds(2); /* * give the time for identity to became idle * */ sleep(SIGNOND_IDLE_TIMEOUT); SignonIdentity *idty2 = signon_identity_new(); g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); g_variant_builder_add (&builder, "{sv}", SIGNON_SESSION_DATA_USERNAME, g_variant_new_string ("test_username")); g_variant_builder_add (&builder, "{sv}", SIGNON_SESSION_DATA_SECRET, g_variant_new_string ("test_pw")); session_data = g_variant_builder_end (&builder); signon_auth_session_process_async (as, session_data, "mech1", NULL, test_auth_session_process_async_cb, &reply); g_main_loop_run (main_loop); fail_unless (reply != NULL); session_data = NULL; ok = g_variant_lookup (reply, SIGNON_SESSION_DATA_USERNAME, "&s", &username); ck_assert (ok); ck_assert_str_eq (username, "test_username"); g_variant_unref (reply); gchar* patterns[4]; patterns[0] = g_strdup("mech1"); patterns[1] = g_strdup("mech2"); patterns[2] = g_strdup("mech3"); patterns[3] = NULL; signon_auth_session_query_available_mechanisms(as, (const gchar**)patterns, test_auth_session_query_mechanisms_cb, (gpointer)patterns); g_main_loop_run (main_loop); g_object_unref (as); g_object_unref (idty); g_object_unref (idty2); g_free (patterns[0]); g_free (patterns[1]); g_free (patterns[2]); g_free (patterns[3]); end_test (); } END_TEST static void test_regression_unref_process_cb (SignonAuthSession *self, GHashTable *reply, const GError *error, gpointer user_data) { GValue *v_string; if (error) { g_warning ("%s: %s", G_STRFUNC, error->message); g_main_loop_quit (main_loop); fail(); } fail_unless (reply != NULL, "The result is empty"); fail_unless (g_strcmp0 (user_data, "Hi there!") == 0, "Didn't get expected user_data"); v_string = g_hash_table_lookup(reply, "James"); fail_unless (v_string != 0); fail_unless (g_strcmp0 (g_value_get_string (v_string), "Bond") == 0, "Wrong reply data"); /* The next line is actually the regression we want to test */ g_object_unref (self); g_main_loop_quit (main_loop); } START_TEST(test_regression_unref) { SignonAuthSession *auth_session; GHashTable *session_data; GError *error = NULL; GValue v_string = G_VALUE_INIT; g_debug ("%s", G_STRFUNC); main_loop = g_main_loop_new (NULL, FALSE); auth_session = signon_auth_session_new (0, "ssotest", &error); fail_unless (auth_session != NULL); session_data = g_hash_table_new (g_str_hash, g_str_equal); g_value_init (&v_string, G_TYPE_STRING); g_value_set_static_string (&v_string, "Bond"); g_hash_table_insert (session_data, "James", &v_string); signon_auth_session_process (auth_session, session_data, "mech1", test_regression_unref_process_cb, "Hi there!"); g_hash_table_unref (session_data); g_main_loop_run (main_loop); end_test (); } END_TEST Suite * signon_suite(void) { Suite *s = suite_create ("signon-glib"); /* Core test case */ TCase * tc_core = tcase_create("Core"); /* * 18 minutes timeout * */ tcase_set_timeout(tc_core, 1080); tcase_add_test (tc_core, test_init); tcase_add_test (tc_core, test_query_methods); tcase_add_test (tc_core, test_query_mechanisms); tcase_add_test (tc_core, test_get_existing_identity); tcase_add_test (tc_core, test_get_nonexisting_identity); tcase_add_test (tc_core, test_auth_session_creation); tcase_add_test (tc_core, test_auth_session_query_mechanisms); tcase_add_test (tc_core, test_auth_session_query_mechanisms_nonexisting); tcase_add_test (tc_core, test_auth_session_process); tcase_add_test (tc_core, test_auth_session_process_async); tcase_add_test (tc_core, test_auth_session_process_failure); tcase_add_test (tc_core, test_auth_session_process_after_store); tcase_add_test (tc_core, test_store_credentials_identity); tcase_add_test (tc_core, test_verify_secret_identity); tcase_add_test (tc_core, test_remove_identity); tcase_add_test (tc_core, test_info_identity); tcase_add_test (tc_core, test_signout_identity); tcase_add_test (tc_core, test_unregistered_identity); tcase_add_test (tc_core, test_unregistered_auth_session); tcase_add_test (tc_core, test_regression_unref); suite_add_tcase (s, tc_core); return s; } int main(void) { int number_failed; Suite * s = signon_suite(); SRunner * sr = srunner_create(s); srunner_set_xml(sr, "/tmp/result.xml"); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free (sr); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } /* vim: set ai et tw=75 ts=4 sw=4: */ ./tests/Makefile.am0000644000004100000410000000101313013271000014417 0ustar www-datawww-data## Process this file with automake to produce Makefile.in check_PROGRAMS = signon-glib-testsuite dist_check_SCRIPTS = signon-glib-test.sh signon_glib_testsuite_SOURCES = check_signon.c signon_glib_testsuite_CPPFLAGS = \ -I$(top_builddir) \ -I$(top_srcdir) \ $(DEPS_CFLAGS) \ $(CHECK_FLAGS) signon_glib_testsuite_LDADD = \ $(top_builddir)/libsignon-glib/libsignon-glib.la \ $(CHECK_LIBS) \ $(DEPS_LIBS) \ -lpthread TESTS_ENVIRONMENT = \ TESTDIR=$(top_srcdir)/tests/; export TESTDIR; TESTS = signon-glib-test.sh ./libsignon-glib/0000755000004100000410000000000013013271000014125 5ustar www-datawww-data./libsignon-glib/signon.vapi0000644000004100000410000002261413013271000016310 0ustar www-datawww-data/* signon.vapi generated by vapigen, do not modify. */ [CCode (cprefix = "Signon", gir_namespace = "Signon", gir_version = "1.0", lower_case_cprefix = "signon_")] namespace Signon { [CCode (cheader_filename = "libsignon-glib/signon-glib.h", type_id = "signon_auth_service_get_type ()")] public class AuthService : GLib.Object { [CCode (has_construct_function = false)] public AuthService (); public void query_mechanisms (string method, [CCode (scope = "async")] owned Signon.QueryMechanismCb cb); public void query_methods ([CCode (scope = "async")] owned Signon.QueryMethodsCb cb); } [CCode (cheader_filename = "libsignon-glib/signon-glib.h", type_id = "signon_auth_session_get_type ()")] public class AuthSession : GLib.Object { [CCode (has_construct_function = false)] public AuthSession (uint id, string method_name) throws GLib.Error; public void cancel (); public unowned string get_method (); [Deprecated (since = "1.8")] public void process (GLib.HashTable session_data, string mechanism, [CCode (scope = "async")] owned Signon.AuthSessionProcessCb cb); public async GLib.Variant process_async (GLib.Variant session_data, string mechanism, GLib.Cancellable? cancellable) throws GLib.Error; public void query_available_mechanisms (string wanted_mechanisms, [CCode (scope = "async")] owned Signon.AuthSessionQueryAvailableMechanismsCb cb); public signal void state_changed (int state, string message); } [CCode (cheader_filename = "libsignon-glib/signon-glib.h", type_id = "signon_identity_get_type ()")] public class Identity : GLib.Object { [CCode (has_construct_function = false)] public Identity (); public void add_reference (string reference, Signon.IdentityReferenceAddedCb cb, void* user_data); public Signon.AuthSession create_session (string method) throws GLib.Error; [CCode (has_construct_function = false)] public Identity.from_db (uint32 id); public unowned GLib.Error get_last_error (); public void query_info ([CCode (scope = "async")] owned Signon.IdentityInfoCb cb); public void remove ([CCode (scope = "async")] owned Signon.IdentityRemovedCb cb, void* user_data); public void remove_reference (string reference, Signon.IdentityReferenceRemovedCb cb, void* user_data); public void store_credentials_with_args (string username, string secret, bool store_secret, GLib.HashTable methods, string caption, string realms, string access_control_list, Signon.IdentityType type, [CCode (scope = "async")] owned Signon.IdentityStoreCredentialsCb cb); public void store_credentials_with_info (Signon.IdentityInfo info, [CCode (scope = "async")] owned Signon.IdentityStoreCredentialsCb cb); public void verify_secret (string secret, [CCode (scope = "async")] owned Signon.IdentityVerifyCb cb); [NoAccessorMethod] public uint id { get; set; } [HasEmitter] public signal void signout (); } [CCode (cheader_filename = "libsignon-glib/signon-glib.h", copy_function = "g_boxed_copy", free_function = "g_boxed_free", type_id = "signon_identity_info_get_type ()")] [Compact] public class IdentityInfo { [CCode (has_construct_function = false)] public IdentityInfo (); public Signon.IdentityInfo copy (); public void free (); [CCode (array_length = false, array_null_terminated = true)] public unowned string[] get_access_control_list (); public unowned string get_caption (); public int get_id (); public Signon.IdentityType get_identity_type (); public unowned GLib.HashTable get_methods (); [CCode (array_length = false, array_null_terminated = true)] public unowned string[] get_realms (); public bool get_storing_secret (); public unowned string get_username (); public void remove_method (string method); public void set_access_control_list ([CCode (array_length = false, array_null_terminated = true)] string[] access_control_list); public void set_caption (string caption); public void set_identity_type (Signon.IdentityType type); public void set_method (string method, [CCode (array_length = false, array_null_terminated = true)] string[] mechanisms); public void set_realms ([CCode (array_length = false, array_null_terminated = true)] string[] realms); public void set_secret (string secret, bool store_secret); public void set_username (string username); } [CCode (cheader_filename = "libsignon-glib/signon-glib.h", cprefix = "SIGNON_IDENTITY_TYPE_", type_id = "signon_identity_type_get_type ()")] [Flags] public enum IdentityType { OTHER, APP, WEB, NETWORK } [CCode (cheader_filename = "libsignon-glib/signon-glib.h", cprefix = "SIGNON_POLICY_", type_id = "signon_session_data_ui_policy_get_type ()")] public enum SessionDataUiPolicy { DEFAULT, REQUEST_PASSWORD, NO_USER_INTERACTION, VALIDATION } [CCode (cheader_filename = "libsignon-glib/signon-glib.h", cprefix = "SIGNON_ERROR_")] public errordomain Error { UNKNOWN, INTERNAL_SERVER, INTERNAL_COMMUNICATION, PERMISSION_DENIED, METHOD_NOT_KNOWN, SERVICE_NOT_AVAILABLE, INVALID_QUERY, METHOD_NOT_AVAILABLE, IDENTITY_NOT_FOUND, STORE_FAILED, REMOVE_FAILED, SIGNOUT_FAILED, IDENTITY_OPERATION_CANCELED, CREDENTIALS_NOT_AVAILABLE, REFERENCE_NOT_FOUND, MECHANISM_NOT_AVAILABLE, MISSING_DATA, INVALID_CREDENTIALS, NOT_AUTHORIZED, WRONG_STATE, OPERATION_NOT_SUPPORTED, NO_CONNECTION, NETWORK, SSL, RUNTIME, SESSION_CANCELED, TIMED_OUT, USER_INTERACTION, OPERATION_FAILED, ENCRYPTION_FAILED, TOS_NOT_ACCEPTED, FORGOT_PASSWORD, METHOD_OR_MECHANISM_NOT_ALLOWED, INCORRECT_DATE, USER_ERROR; public static GLib.Quark quark (); } [CCode (cheader_filename = "libsignon-glib/signon-glib.h", instance_pos = 3.9)] public delegate void AuthSessionProcessCb (Signon.AuthSession self, GLib.HashTable session_data, GLib.Error error); [CCode (cheader_filename = "libsignon-glib/signon-glib.h", instance_pos = 3.9)] public delegate void AuthSessionQueryAvailableMechanismsCb (Signon.AuthSession self, [CCode (array_length = false, array_null_terminated = true)] owned string[] mechanisms, GLib.Error error); [CCode (cheader_filename = "libsignon-glib/signon-glib.h", instance_pos = 3.9)] public delegate void AuthSessionQueryAvailableMethodsCb (Signon.AuthSession self, [CCode (array_length = false, array_null_terminated = true)] owned string[] mechanisms, GLib.Error error); [CCode (cheader_filename = "libsignon-glib/signon-glib.h", instance_pos = 3.9)] public delegate void IdentityInfoCb (Signon.Identity self, Signon.IdentityInfo info, GLib.Error error); [CCode (cheader_filename = "libsignon-glib/signon-glib.h", instance_pos = 2.9)] public delegate void IdentityReferenceAddedCb (Signon.Identity self, GLib.Error error); [CCode (cheader_filename = "libsignon-glib/signon-glib.h", instance_pos = 2.9)] public delegate void IdentityReferenceRemovedCb (Signon.Identity self, GLib.Error error); [CCode (cheader_filename = "libsignon-glib/signon-glib.h", instance_pos = 2.9)] public delegate void IdentityRemovedCb (Signon.Identity self, GLib.Error error); [CCode (cheader_filename = "libsignon-glib/signon-glib.h", instance_pos = 2.9)] public delegate void IdentitySignedOutCb (Signon.Identity self, GLib.Error error); [CCode (cheader_filename = "libsignon-glib/signon-glib.h", instance_pos = 3.9)] public delegate void IdentityStoreCredentialsCb (Signon.Identity self, uint32 id, GLib.Error error); [CCode (cheader_filename = "libsignon-glib/signon-glib.h", instance_pos = 3.9)] public delegate void IdentityVerifyCb (Signon.Identity self, bool valid, GLib.Error error); [CCode (cheader_filename = "libsignon-glib/signon-glib.h", instance_pos = 2.9)] public delegate void IdentityVoidCb (Signon.Identity self, GLib.Error error); [CCode (cheader_filename = "libsignon-glib/signon-glib.h", instance_pos = 4.9)] public delegate void QueryMechanismCb (Signon.AuthService auth_service, string method, [CCode (array_length = false, array_null_terminated = true)] string[] mechanisms, GLib.Error error); [CCode (cheader_filename = "libsignon-glib/signon-glib.h", instance_pos = 3.9)] public delegate void QueryMethodsCb (Signon.AuthService auth_service, [CCode (array_length = false, array_null_terminated = true)] string[] methods, GLib.Error error); [CCode (cheader_filename = "libsignon-glib/signon-glib.h", cname = "SIGNON_SESSION_DATA_CAPTION")] public const string SESSION_DATA_CAPTION; [CCode (cheader_filename = "libsignon-glib/signon-glib.h", cname = "SIGNON_SESSION_DATA_PROXY")] public const string SESSION_DATA_PROXY; [CCode (cheader_filename = "libsignon-glib/signon-glib.h", cname = "SIGNON_SESSION_DATA_REALM")] public const string SESSION_DATA_REALM; [CCode (cheader_filename = "libsignon-glib/signon-glib.h", cname = "SIGNON_SESSION_DATA_RENEW_TOKEN")] public const string SESSION_DATA_RENEW_TOKEN; [CCode (cheader_filename = "libsignon-glib/signon-glib.h", cname = "SIGNON_SESSION_DATA_SECRET")] public const string SESSION_DATA_SECRET; [CCode (cheader_filename = "libsignon-glib/signon-glib.h", cname = "SIGNON_SESSION_DATA_TIMEOUT")] public const string SESSION_DATA_TIMEOUT; [CCode (cheader_filename = "libsignon-glib/signon-glib.h", cname = "SIGNON_SESSION_DATA_UI_POLICY")] public const string SESSION_DATA_UI_POLICY; [CCode (cheader_filename = "libsignon-glib/signon-glib.h", cname = "SIGNON_SESSION_DATA_USERNAME")] public const string SESSION_DATA_USERNAME; [CCode (cheader_filename = "libsignon-glib/signon-glib.h", cname = "SIGNON_SESSION_DATA_WINDOW_ID")] public const string SESSION_DATA_WINDOW_ID; } ./libsignon-glib/sso-auth-service.c0000644000004100000410000000613413013271000017476 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2012-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 "signon-errors.h" #include "signon-internals.h" #include "sso-auth-service.h" static GHashTable *thread_objects = NULL; static GMutex map_mutex; static SsoAuthService * get_singleton () { SsoAuthService *object = NULL; g_mutex_lock (&map_mutex); if (thread_objects != NULL) { GWeakRef *ref; ref = g_hash_table_lookup (thread_objects, g_thread_self ()); if (ref != NULL) { object = g_weak_ref_get (ref); } } g_mutex_unlock (&map_mutex); return object; } static void weak_ref_free(GWeakRef *ref) { g_weak_ref_clear (ref); g_slice_free (GWeakRef, ref); } static void set_singleton (SsoAuthService *object) { g_return_if_fail (IS_SSO_AUTH_SERVICE (object)); g_mutex_lock (&map_mutex); if (thread_objects == NULL) { thread_objects = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) weak_ref_free); } if (object != NULL) { GWeakRef *ref = g_slice_new (GWeakRef); g_weak_ref_init (ref, object); g_hash_table_insert (thread_objects, g_thread_self (), ref); } g_mutex_unlock (&map_mutex); } SsoAuthService * sso_auth_service_get_instance () { SsoAuthService *sso_auth_service; GError *error = NULL; sso_auth_service = get_singleton (); if (sso_auth_service != NULL) return sso_auth_service; /* Create the object */ sso_auth_service = sso_auth_service_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, SIGNOND_SERVICE, SIGNOND_DAEMON_OBJECTPATH, NULL, &error); if (G_LIKELY (error == NULL)) { set_singleton (sso_auth_service); } else { g_warning ("Couldn't activate signond: %s", error->message); g_clear_error (&error); } /* While at it, register the error mapping with GDBus */ signon_error_quark (); return sso_auth_service; } ./libsignon-glib/sso-auth-service.h0000644000004100000410000000220613013271000017477 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2012-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 _SSO_AUTH_SERVICE_H_ #define _SSO_AUTH_SERVICE_H_ #include "sso-auth-service-gen.h" G_BEGIN_DECLS G_GNUC_INTERNAL SsoAuthService *sso_auth_service_get_instance (); G_END_DECLS #endif /* _SSO_AUTH_SERVICE_H_ */ ./libsignon-glib/signon-identity-info.c0000644000004100000410000004067213013271000020357 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. * Copyright (C) 2011-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 */ /** * SECTION:signon-identity-info * @title: SignonIdentityInfo * @short_description: Extra data for a #SignonIdentity. * * Extra data retreived from a #SignonIdentity. */ #include "signon-identity-info.h" #include "signon-internals.h" #include "signon-utils.h" G_DEFINE_BOXED_TYPE (SignonIdentityInfo, signon_identity_info, (GBoxedCopyFunc)signon_identity_info_copy, (GBoxedFreeFunc)signon_identity_info_free); static GVariant * signon_variant_new_string (const gchar *string) { return g_variant_new_string (string != NULL ? string : ""); } static const gchar *identity_info_get_secret (const SignonIdentityInfo *info) { g_return_val_if_fail (info != NULL, NULL); return info->secret; } static void identity_info_set_id (SignonIdentityInfo *info, gint id) { g_return_if_fail (info != NULL); g_return_if_fail (id >= 0); info->id = id; } static void identity_methods_copy (gpointer key, gpointer value, gpointer user_data) { signon_identity_info_set_method ((SignonIdentityInfo *)user_data, (const gchar *)key, (const gchar* const *)value); } void signon_identity_info_set_methods (SignonIdentityInfo *info, const GHashTable *methods) { g_return_if_fail (info != NULL); g_return_if_fail (methods != NULL); DEBUG("%s", G_STRFUNC); if (info->methods) g_hash_table_remove_all (info->methods); else info->methods = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_strfreev); g_hash_table_foreach ((GHashTable *)methods, identity_methods_copy, info); } SignonIdentityInfo * signon_identity_info_new_from_variant (GVariant *variant) { GVariant *method_map; if (!variant) return NULL; SignonIdentityInfo *info = signon_identity_info_new (); DEBUG("%s: ", G_STRFUNC); g_variant_lookup (variant, SIGNOND_IDENTITY_INFO_ID, "u", &info->id); g_variant_lookup (variant, SIGNOND_IDENTITY_INFO_USERNAME, "s", &info->username); if (g_variant_lookup (variant, SIGNOND_IDENTITY_INFO_SECRET, "s", &info->secret)) { g_variant_lookup (variant, SIGNOND_IDENTITY_INFO_STORESECRET, "b", &info->store_secret); } g_variant_lookup (variant, SIGNOND_IDENTITY_INFO_CAPTION, "s", &info->caption); g_variant_lookup (variant, SIGNOND_IDENTITY_INFO_REALMS, "^as", &info->realms); /* get the methods */ if (g_variant_lookup (variant, SIGNOND_IDENTITY_INFO_AUTHMETHODS, "@a{sas}", &method_map)) { GVariantIter iter; gchar *method; gchar **mechanisms; g_variant_iter_init (&iter, method_map); while (g_variant_iter_next (&iter, "{s^as}", &method, &mechanisms)) { g_hash_table_insert (info->methods, method, mechanisms); } g_variant_unref (method_map); } g_variant_lookup (variant, SIGNOND_IDENTITY_INFO_ACL, "^as", &info->access_control_list); g_variant_lookup (variant, SIGNOND_IDENTITY_INFO_TYPE, "u", &info->type); return info; } GVariant * signon_identity_info_to_variant (const SignonIdentityInfo *self) { GVariantBuilder builder; GVariantBuilder method_builder; GVariant *method_map; GHashTableIter iter; const gchar *method; const gchar **mechanisms; g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); g_variant_builder_add (&builder, "{sv}", SIGNOND_IDENTITY_INFO_ID, g_variant_new_uint32 (self->id)); g_variant_builder_add (&builder, "{sv}", SIGNOND_IDENTITY_INFO_USERNAME, signon_variant_new_string (self->username)); g_variant_builder_add (&builder, "{sv}", SIGNOND_IDENTITY_INFO_SECRET, signon_variant_new_string (self->secret)); g_variant_builder_add (&builder, "{sv}", SIGNOND_IDENTITY_INFO_CAPTION, signon_variant_new_string (self->caption)); g_variant_builder_add (&builder, "{sv}", SIGNOND_IDENTITY_INFO_STORESECRET, g_variant_new_boolean (self->store_secret)); g_variant_builder_init (&method_builder, (const GVariantType *)"a{sas}"); g_hash_table_iter_init (&iter, self->methods); while (g_hash_table_iter_next (&iter, (gpointer)&method, (gpointer)&mechanisms)) { g_variant_builder_add (&method_builder, "{s^as}", method, mechanisms); } method_map = g_variant_builder_end (&method_builder); g_variant_builder_add (&builder, "{sv}", SIGNOND_IDENTITY_INFO_AUTHMETHODS, method_map); if (self->realms != NULL) { g_variant_builder_add (&builder, "{sv}", SIGNOND_IDENTITY_INFO_REALMS, g_variant_new_strv ((const gchar * const *) self->realms, -1)); } if (self->access_control_list != NULL) { g_variant_builder_add (&builder, "{sv}", SIGNOND_IDENTITY_INFO_ACL, g_variant_new_strv ((const gchar * const *) self->access_control_list, -1)); } g_variant_builder_add (&builder, "{sv}", SIGNOND_IDENTITY_INFO_TYPE, g_variant_new_int32 (self->type)); return g_variant_builder_end (&builder); } /* * Public methods: */ /** * signon_identity_info_new: * * Creates a new #SignonIdentityInfo item. * * Returns: a new #SignonIdentityInfo item. */ SignonIdentityInfo *signon_identity_info_new () { SignonIdentityInfo *info = g_slice_new0 (SignonIdentityInfo); info->methods = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_strfreev); info->store_secret = FALSE; return info; } /** * signon_identity_info_free: * @info: the #SignonIdentityInfo. * * Destroys the given #SignonIdentityInfo item. */ void signon_identity_info_free (SignonIdentityInfo *info) { if (info == NULL) return; g_free (info->username); g_free (info->secret); g_free (info->caption); g_hash_table_destroy (info->methods); g_strfreev (info->realms); g_strfreev (info->access_control_list); g_slice_free (SignonIdentityInfo, info); } /** * signon_identity_info_copy: * @other: the #SignonIdentityInfo. * * Get a newly-allocated copy of @info. * * Returns: a copy of the given #SignonIdentityInfo, or %NULL on failure. */ SignonIdentityInfo *signon_identity_info_copy (const SignonIdentityInfo *other) { g_return_val_if_fail (other != NULL, NULL); SignonIdentityInfo *info = signon_identity_info_new (); identity_info_set_id (info, signon_identity_info_get_id (other)); signon_identity_info_set_username (info, signon_identity_info_get_username (other)); signon_identity_info_set_secret (info, identity_info_get_secret(other), signon_identity_info_get_storing_secret (other)); signon_identity_info_set_caption (info, signon_identity_info_get_caption(other)); signon_identity_info_set_methods (info, signon_identity_info_get_methods (other)); signon_identity_info_set_realms (info, signon_identity_info_get_realms (other)); signon_identity_info_set_access_control_list (info, signon_identity_info_get_access_control_list (other)); signon_identity_info_set_identity_type (info, signon_identity_info_get_identity_type (other)); return info; } /** * signon_identity_info_get_id: * @info: the #SignonIdentityInfo. * * Get the numeric ID of @info. * * Returns: the numeric ID of the identity. */ gint signon_identity_info_get_id (const SignonIdentityInfo *info) { g_return_val_if_fail (info != NULL, -1); return info->id; } /** * signon_identity_info_get_username: * @info: the #SignonIdentityInfo. * * Get the username of @info. * * Returns: the username, or %NULL. */ const gchar *signon_identity_info_get_username (const SignonIdentityInfo *info) { g_return_val_if_fail (info != NULL, NULL); return info->username; } /** * signon_identity_info_get_storing_secret: * @info: the #SignonIdentityInfo. * * Get whether the secret of @info should be stored. * * Returns: %TRUE if Signon must store the secret, %FALSE otherwise. */ gboolean signon_identity_info_get_storing_secret (const SignonIdentityInfo *info) { g_return_val_if_fail (info != NULL, FALSE); return info->store_secret; } /** * signon_identity_info_get_caption: * @info: the #SignonIdentityInfo. * * Get the display name of @info. * * Returns: the display name for the identity. */ const gchar *signon_identity_info_get_caption (const SignonIdentityInfo *info) { g_return_val_if_fail (info != NULL, NULL); return info->caption; } /** * signon_identity_info_get_methods: * @info: the #SignonIdentityInfo. * * Get a hash table of the methods and mechanisms of @info. * * Returns: (transfer none) (element-type utf8 GStrv): the table of allowed * methods and mechanisms. */ const GHashTable *signon_identity_info_get_methods (const SignonIdentityInfo *info) { g_return_val_if_fail (info != NULL, NULL); return info->methods; } /** * signon_identity_info_get_realms: * @info: the #SignonIdentityInfo. * * Get an array of the realms of @info. * * Returns: (transfer none): a %NULL terminated array of realms. */ const gchar* const *signon_identity_info_get_realms (const SignonIdentityInfo *info) { g_return_val_if_fail (info != NULL, NULL); return (const gchar* const *)info->realms; } /** * signon_identity_info_get_access_control_list: * @info: the #SignonIdentityInfo. * * Get an array of ACL statements of the identity. * * Returns: (transfer none): a %NULL terminated array of ACL statements. */ const gchar* const *signon_identity_info_get_access_control_list (const SignonIdentityInfo *info) { g_return_val_if_fail (info != NULL, NULL); return (const gchar* const *)info->access_control_list; } /** * signon_identity_info_get_identity_type: * @info: the #SignonIdentityInfo. * * Get the type of the identity. * * Returns: the type of the identity. */ SignonIdentityType signon_identity_info_get_identity_type (const SignonIdentityInfo *info) { g_return_val_if_fail (info != NULL, -1); return (SignonIdentityType)info->type; } /** * signon_identity_info_set_username: * @info: the #SignonIdentityInfo. * @username: the username. * * Sets the username for the identity. */ void signon_identity_info_set_username (SignonIdentityInfo *info, const gchar *username) { g_return_if_fail (info != NULL); if (info->username) g_free (info->username); info->username = g_strdup (username); } /** * signon_identity_info_set_secret: * @info: the #SignonIdentityInfo. * @secret: the secret. * @store_secret: whether signond should store the secret in its DB. * * Sets the secret (password) for the identity, and whether the signon daemon * should remember it. */ void signon_identity_info_set_secret (SignonIdentityInfo *info, const gchar *secret, gboolean store_secret) { g_return_if_fail (info != NULL); if (info->secret) g_free (info->secret); info->secret = g_strdup (secret); info->store_secret = store_secret; } /** * signon_identity_info_set_caption: * @info: the #SignonIdentityInfo. * @caption: the caption. * * Sets the caption (display name) for the identity. */ void signon_identity_info_set_caption (SignonIdentityInfo *info, const gchar *caption) { g_return_if_fail (info != NULL); if (info->caption) g_free (info->caption); info->caption = g_strdup (caption); } /** * signon_identity_info_set_method: * @info: the #SignonIdentityInfo. * @method: an authentication method. * @mechanisms: (transfer none) (type GStrv): a %NULL-termianted list of mechanisms. * * Adds a method to the list of allowed methods. If this method is not called * even once, then all methods are allowed. * Mechanisms are method-specific variants of authentication. */ void signon_identity_info_set_method (SignonIdentityInfo *info, const gchar *method, const gchar* const *mechanisms) { g_return_if_fail (info != NULL); g_return_if_fail (info->methods != NULL); g_return_if_fail (method != NULL); g_return_if_fail (mechanisms != NULL); g_hash_table_replace (info->methods, g_strdup(method), g_strdupv((gchar **)mechanisms)); } /** * signon_identity_info_remove_method: * @info: the #SignonIdentityInfo. * @method: an authentication method. * * Remove @method from the list of allowed authentication methods. If all * methods are removed, then all methods are allowed. */ void signon_identity_info_remove_method (SignonIdentityInfo *info, const gchar *method) { g_return_if_fail (info != NULL); g_return_if_fail (info->methods != NULL); g_hash_table_remove (info->methods, method); } /** * signon_identity_info_set_realms: * @info: the #SignonIdentityInfo. * @realms: (transfer none) (type GStrv): a %NULL-terminated list of realms. * * Specify what realms this identity can be used in. */ void signon_identity_info_set_realms (SignonIdentityInfo *info, const gchar* const *realms) { g_return_if_fail (info != NULL); if (info->realms) g_strfreev (info->realms); info->realms = g_strdupv ((gchar **)realms); } /** * signon_identity_info_set_access_control_list: * @info: the #SignonIdentityInfo. * @access_control_list: (transfer none) (type GStrv): a %NULL-terminated list * of ACL security domains. * * Specifies the ACL for this identity. The actual meaning of the ACL depends * on the security framework used by signond. */ void signon_identity_info_set_access_control_list (SignonIdentityInfo *info, const gchar* const *access_control_list) { g_return_if_fail (info != NULL); if (info->access_control_list) g_strfreev (info->access_control_list); info->access_control_list = g_strdupv ((gchar **)access_control_list); } /** * signon_identity_info_set_identity_type: * @info: the #SignonIdentityInfo. * @type: the type of the identity. * * Specifies the type of this identity. */ void signon_identity_info_set_identity_type (SignonIdentityInfo *info, SignonIdentityType type) { g_return_if_fail (info != NULL); info->type = (gint)type; } ./libsignon-glib/signon-errors.c0000644000004100000410000000327713013271000017111 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. * Copyright (C) 2012-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 "signon-errors.h" #include "signon-enum-types.h" #include "signon-internals.h" #include "signoncommon.h" #include /** * SECTION:signon-errors * @title: SignonError * @short_description: Possible errors from Signon. * * An enumeration of errors that are possible from Signon. */ #define SIGNON_ERROR_PREFIX SIGNOND_SERVICE_PREFIX ".Error" #include "signon-errors-map.c" GQuark signon_error_quark (void) { static volatile gsize quark = 0; g_dbus_error_register_error_domain ("signon-errors", &quark, signon_error_entries, G_N_ELEMENTS (signon_error_entries)); return (GQuark) quark; } ./libsignon-glib/signon-errors.h0000644000004100000410000001216713013271000017114 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. * Copyright (C) 2012-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 __LIBSIGNON_ERRORS_H__ #define __LIBSIGNON_ERRORS_H__ #include #include #include #define SIGNON_ERROR (signon_error_quark()) /** * SignonError: * @SIGNON_ERROR_UNKNOWN: Catch-all for errors not distinguished by another code. * @SIGNON_ERROR_INTERNAL_SERVER: Signon daemon internal error. * @SIGNON_ERROR_INTERNAL_COMMUNICATION: Error communicating with Sigon daemon. * @SIGNON_ERROR_PERMISSION_DENIED: The operation cannot be performed due to * insufficient client permissions. * @SIGNON_ERROR_METHOD_NOT_KNOWN: The method with this name was not found. * @SIGNON_ERROR_SERVICE_NOT_AVAILABLE: The service is temporarily unavailable. * @SIGNON_ERROR_INVALID_QUERY: Parameters for the query are invalid. * @SIGNON_ERROR_METHOD_NOT_AVAILABLE: The requested method is not available. * @SIGNON_ERROR_IDENTITY_NOT_FOUND: The identity mathching the #SignonIdentity * was not found on the service. * @SIGNON_ERROR_STORE_FAILED: Storing credentials failed. * @SIGNON_ERROR_REMOVE_FAILED: Removing credentials failed. * @SIGNON_ERROR_SIGNOUT_FAILED: Signing out failed. * @SIGNON_ERROR_IDENTITY_OPERATION_CANCELED: Identity operation was canceled * by the user. * @SIGNON_ERROR_CREDENTIALS_NOT_AVAILABLE: Query failed. * @SIGNON_ERROR_REFERENCE_NOT_FOUND: Trying to remove non-existent reference. * @SIGNON_ERROR_MECHANISM_NOT_AVAILABLE: The requested mechanism in not * available. * @SIGNON_ERROR_MISSING_DATA: The #SessionData does not contain the necessary * information. * @SIGNON_ERROR_INVALID_CREDENTIALS: The supplied credentials are invalid for * the mechanism implementation. * @SIGNON_ERROR_NOT_AUTHORIZED: Authorization failed. * @SIGNON_ERROR_WRONG_STATE: An operation method has been called in an * incorrect state. * @SIGNON_ERROR_OPERATION_NOT_SUPPORTED: The operation is not supported by the * mechanism implementation. * @SIGNON_ERROR_NO_CONNECTION: No network connection. * @SIGNON_ERROR_NETWORK: Network connection failed. * @SIGNON_ERROR_SSL: SSL connection failed. * @SIGNON_ERROR_RUNTIME: Casting #SessionData into subclass failed. * @SIGNON_ERROR_SESSION_CANCELED: Challenge was canceled. * @SIGNON_ERROR_TIMED_OUT: Challenge timed out. * @SIGNON_ERROR_USER_INTERACTION: User interaction dialog failed. * @SIGNON_ERROR_OPERATION_FAILED: Temporary failure in authentication. * @SIGNON_ERROR_ENCRYPTION_FAILED: @deprecated: Failure during data * encryption/decryption. * @SIGNON_ERROR_TOS_NOT_ACCEPTED: User declined Terms of Service. * @SIGNON_ERROR_FORGOT_PASSWORD: User requested password reset sequence. * @SIGNON_ERROR_METHOD_OR_MECHANISM_NOT_ALLOWED: Method or mechanism not * allowed for this identity. * @SIGNON_ERROR_INCORRECT_DATE: Date/time incorrect on device. * @SIGNON_ERROR_USER_ERROR: Placeholder to rearrange enumeration - userspace * specific. * * Possible Signon errors. */ typedef enum { SIGNON_ERROR_UNKNOWN = 1, SIGNON_ERROR_INTERNAL_SERVER = 2, SIGNON_ERROR_INTERNAL_COMMUNICATION = 3, SIGNON_ERROR_PERMISSION_DENIED = 4, SIGNON_ERROR_METHOD_NOT_KNOWN = 101, SIGNON_ERROR_SERVICE_NOT_AVAILABLE, SIGNON_ERROR_INVALID_QUERY, SIGNON_ERROR_METHOD_NOT_AVAILABLE = 201, SIGNON_ERROR_IDENTITY_NOT_FOUND, SIGNON_ERROR_STORE_FAILED, SIGNON_ERROR_REMOVE_FAILED, SIGNON_ERROR_SIGNOUT_FAILED, SIGNON_ERROR_IDENTITY_OPERATION_CANCELED, SIGNON_ERROR_CREDENTIALS_NOT_AVAILABLE, SIGNON_ERROR_REFERENCE_NOT_FOUND, SIGNON_ERROR_MECHANISM_NOT_AVAILABLE = 301, SIGNON_ERROR_MISSING_DATA, SIGNON_ERROR_INVALID_CREDENTIALS, SIGNON_ERROR_NOT_AUTHORIZED, SIGNON_ERROR_WRONG_STATE, SIGNON_ERROR_OPERATION_NOT_SUPPORTED, SIGNON_ERROR_NO_CONNECTION, SIGNON_ERROR_NETWORK, SIGNON_ERROR_SSL, SIGNON_ERROR_RUNTIME, SIGNON_ERROR_SESSION_CANCELED, SIGNON_ERROR_TIMED_OUT, SIGNON_ERROR_USER_INTERACTION, SIGNON_ERROR_OPERATION_FAILED, SIGNON_ERROR_ENCRYPTION_FAILED, SIGNON_ERROR_TOS_NOT_ACCEPTED, SIGNON_ERROR_FORGOT_PASSWORD, SIGNON_ERROR_METHOD_OR_MECHANISM_NOT_ALLOWED, SIGNON_ERROR_INCORRECT_DATE, SIGNON_ERROR_USER_ERROR = 400 } SignonError; GQuark signon_error_quark (void); #endif ./libsignon-glib/signon-auth-service.h0000644000004100000410000000663513013271000020202 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. * Copyright (C) 2012-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 _SIGNON_AUTH_SERVICE_H_ #define _SIGNON_AUTH_SERVICE_H_ #include G_BEGIN_DECLS #define SIGNON_TYPE_AUTH_SERVICE (signon_auth_service_get_type ()) #define SIGNON_AUTH_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SIGNON_TYPE_AUTH_SERVICE, SignonAuthService)) #define SIGNON_AUTH_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SIGNON_TYPE_AUTH_SERVICE, SignonAuthServiceClass)) #define SIGNON_IS_AUTH_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SIGNON_TYPE_AUTH_SERVICE)) #define SIGNON_IS_AUTH_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SIGNON_TYPE_AUTH_SERVICE)) #define SIGNON_AUTH_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SIGNON_TYPE_AUTH_SERVICE, SignonAuthServiceClass)) typedef struct _SignonAuthServiceClass SignonAuthServiceClass; typedef struct _SignonAuthServicePrivate SignonAuthServicePrivate; typedef struct _SignonAuthService SignonAuthService; /** * SignonAuthServiceClass: * * Opaque struct. Use the accessor functions below. */ struct _SignonAuthServiceClass { GObjectClass parent_class; }; /** * SignonAuthService: * * Opaque struct. Use the accessor functions below. */ struct _SignonAuthService { GObject parent_instance; SignonAuthServicePrivate *priv; }; GType signon_auth_service_get_type (void) G_GNUC_CONST; typedef void (*SignonQueryMethodsCb) (SignonAuthService *auth_service, gchar **methods, const GError *error, gpointer user_data); typedef void (*SignonQueryMechanismCb) (SignonAuthService *auth_service, const gchar *method, gchar **mechanisms, const GError *error, gpointer user_data); SignonAuthService *signon_auth_service_new (); void signon_auth_service_query_methods (SignonAuthService *auth_service, SignonQueryMethodsCb cb, gpointer user_data); void signon_auth_service_query_mechanisms (SignonAuthService *auth_service, const gchar *method, SignonQueryMechanismCb cb, gpointer user_data); G_END_DECLS #endif /* _SIGNON_AUTH_SERVICE_H_ */ ./libsignon-glib/signon-internals.h0000644000004100000410000000375713013271000017604 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. * Copyright (C) 2012-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 _SIGNONINTERNALS_H_ #define _SIGNONINTERNALS_H_ #ifndef SIGNON_TRACE #define SIGNON_TRACE #endif #ifdef SIGNON_TRACE #define DEBUG(format...) g_debug (G_STRLOC ": " format) #else #define DEBUG(...) do {} while (0) #endif #include #include "signon-identity.h" #include "signon-auth-session.h" G_BEGIN_DECLS struct _SignonIdentityInfo { gint id; gchar *username; gchar *secret; gchar *caption; gboolean store_secret; GHashTable *methods; gchar **realms; gchar **access_control_list; gint type; }; G_GNUC_INTERNAL SignonIdentityInfo * signon_identity_info_new_from_variant (GVariant *variant); G_GNUC_INTERNAL GVariant * signon_identity_info_to_variant (const SignonIdentityInfo *self); G_GNUC_INTERNAL void signon_identity_info_set_methods (SignonIdentityInfo *self, const GHashTable *methods); G_GNUC_INTERNAL void signon_auth_session_set_id(SignonAuthSession* self, gint32 id); G_END_DECLS #endif ./libsignon-glib/signon-auth-service.c0000644000004100000410000001716713013271000020177 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. * Copyright (C) 2012-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 */ /** * SECTION:signon-auth-service * @title: SignonAuthService * @short_description: The authorization service object * * The #SignonAuthService is the main object in this library. */ #include "signon-auth-service.h" #include "signon-errors.h" #include "signon-internals.h" #include "sso-auth-service.h" #include #include G_DEFINE_TYPE (SignonAuthService, signon_auth_service, G_TYPE_OBJECT); struct _SignonAuthServicePrivate { SsoAuthService *proxy; GCancellable *cancellable; }; typedef struct _MethodCbData { SignonAuthService *service; SignonQueryMethodsCb cb; gpointer userdata; } MethodCbData; typedef struct _MechanismCbData { SignonAuthService *service; SignonQueryMechanismCb cb; gpointer userdata; gchar *method; } MechanismCbData; #define SIGNON_AUTH_SERVICE_PRIV(obj) (SIGNON_AUTH_SERVICE(obj)->priv) static void signon_auth_service_init (SignonAuthService *auth_service) { SignonAuthServicePrivate *priv; priv = G_TYPE_INSTANCE_GET_PRIVATE (auth_service, SIGNON_TYPE_AUTH_SERVICE, SignonAuthServicePrivate); auth_service->priv = priv; /* Create the proxy */ priv->cancellable = g_cancellable_new (); priv->proxy = sso_auth_service_get_instance (); } static void signon_auth_service_dispose (GObject *object) { SignonAuthService *auth_service = SIGNON_AUTH_SERVICE (object); SignonAuthServicePrivate *priv = auth_service->priv; if (priv->cancellable) { g_cancellable_cancel (priv->cancellable); g_object_unref (priv->cancellable); priv->cancellable = NULL; } if (priv->proxy) { g_object_unref (priv->proxy); priv->proxy = NULL; } G_OBJECT_CLASS (signon_auth_service_parent_class)->dispose (object); } static void signon_auth_service_finalize (GObject *object) { G_OBJECT_CLASS (signon_auth_service_parent_class)->finalize (object); } static void signon_auth_service_class_init (SignonAuthServiceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); g_type_class_add_private (object_class, sizeof (SignonAuthServicePrivate)); object_class->dispose = signon_auth_service_dispose; object_class->finalize = signon_auth_service_finalize; } /** * signon_auth_service_new: * * Create a new #SignonAuthService. * * Returns: an instance of an #SignonAuthService. */ SignonAuthService * signon_auth_service_new () { return g_object_new (SIGNON_TYPE_AUTH_SERVICE, NULL); } static void auth_query_methods_cb (GObject *object, GAsyncResult *res, gpointer user_data) { SsoAuthService *proxy = SSO_AUTH_SERVICE (object); MethodCbData *data = (MethodCbData*)user_data; gchar **value = NULL; GError *error = NULL; g_return_if_fail (data != NULL); sso_auth_service_call_query_methods_finish (proxy, &value, res, &error); (data->cb) (data->service, value, error, data->userdata); g_strfreev (value); if (error) g_error_free (error); g_slice_free (MethodCbData, data); } static void auth_query_mechanisms_cb (GObject *object, GAsyncResult *res, gpointer user_data) { SsoAuthService *proxy = SSO_AUTH_SERVICE (object); MechanismCbData *data = (MechanismCbData*) user_data; gchar **value = NULL; GError *error = NULL; g_return_if_fail (data != NULL); sso_auth_service_call_query_mechanisms_finish (proxy, &value, res, &error); (data->cb) (data->service, data->method, value, error, data->userdata); g_strfreev (value); if (error) g_error_free (error); g_free (data->method); g_slice_free (MechanismCbData, data); } /** * SignonQueryMethodsCb: * @auth_service: the #SignonAuthService. * @methods: (transfer none) (type GStrv): list of available methods. * @error: a #GError if an error occurred, %NULL otherwise. * @user_data: the user data that was passed when installing this callback. * * Callback to be passed to signon_auth_service_query_methods(). */ /** * signon_auth_service_query_methods: * @auth_service: the #SignonAuthService. * @cb: (scope async): callback to be invoked. * @user_data: user data. * * Lists all the available methods. */ void signon_auth_service_query_methods (SignonAuthService *auth_service, SignonQueryMethodsCb cb, gpointer user_data) { SignonAuthServicePrivate *priv; g_return_if_fail (SIGNON_IS_AUTH_SERVICE (auth_service)); g_return_if_fail (cb != NULL); priv = SIGNON_AUTH_SERVICE_PRIV (auth_service); MethodCbData *cb_data; cb_data = g_slice_new (MethodCbData); cb_data->service = auth_service; cb_data->cb = cb; cb_data->userdata = user_data; sso_auth_service_call_query_methods (priv->proxy, priv->cancellable, auth_query_methods_cb, cb_data); } /** * SignonQueryMechanismCb: * @auth_service: the #SignonAuthService. * @method: the authentication method being inspected. * @mechanisms: (transfer none) (type GStrv): list of available mechanisms. * @error: a #GError if an error occurred, %NULL otherwise. * @user_data: the user data that was passed when installing this callback. * * Callback to be passed to signon_auth_service_query_mechanisms(). */ /** * signon_auth_service_query_mechanisms: * @auth_service: the #SignonAuthService. * @method: the name of the method whose mechanisms must be * retrieved. * @cb: (scope async): callback to be invoked. * @user_data: user data. * * Lists all the available mechanisms. */ void signon_auth_service_query_mechanisms (SignonAuthService *auth_service, const gchar *method, SignonQueryMechanismCb cb, gpointer user_data) { SignonAuthServicePrivate *priv; g_return_if_fail (SIGNON_IS_AUTH_SERVICE (auth_service)); g_return_if_fail (cb != NULL); priv = SIGNON_AUTH_SERVICE_PRIV (auth_service); MechanismCbData *cb_data; cb_data = g_slice_new (MechanismCbData); cb_data->service = auth_service; cb_data->cb = cb; cb_data->userdata = user_data; cb_data->method = g_strdup (method); sso_auth_service_call_query_mechanisms (priv->proxy, method, priv->cancellable, auth_query_mechanisms_cb, cb_data); } ./libsignon-glib/signon-auth-session.h0000644000004100000410000001466513013271000020227 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. * Copyright (C) 2012-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 SIGNONAUTHSESSION_H_ #define SIGNONAUTHSESSION_H_ #include #include #include G_BEGIN_DECLS /* * Useful session data keys */ /** * SIGNON_SESSION_DATA_USERNAME: * * Username. */ #define SIGNON_SESSION_DATA_USERNAME "UserName" /** * SIGNON_SESSION_DATA_SECRET: * * Secret. */ #define SIGNON_SESSION_DATA_SECRET "Secret" /** * SIGNON_SESSION_DATA_REALM: * * Realm. */ #define SIGNON_SESSION_DATA_REALM "Realm" /** * SIGNON_SESSION_DATA_PROXY: * * Proxy. */ #define SIGNON_SESSION_DATA_PROXY "NetworkProxy" /** * SignonSessionDataUiPolicy: * @SIGNON_POLICY_DEFAULT: The plugin can decide when to show UI. * @SIGNON_POLICY_REQUEST_PASSWORD: Force the user to enter the password. * @SIGNON_POLICY_NO_USER_INTERACTION: No UI elements will be shown to the user. * @SIGNON_POLICY_VALIDATION: UI elements can be shown to the user only when * CAPTCHA-like security measures are required. * * Policy for the signon process, passed to the UI plugin. */ typedef enum { SIGNON_POLICY_DEFAULT = 0, SIGNON_POLICY_REQUEST_PASSWORD, SIGNON_POLICY_NO_USER_INTERACTION, SIGNON_POLICY_VALIDATION, } SignonSessionDataUiPolicy; /** * SIGNON_SESSION_DATA_UI_POLICY: * @see_also: #SignonSessionDataUiPolicy * * Policy for the signon process. */ #define SIGNON_SESSION_DATA_UI_POLICY "UiPolicy" /** * SIGNON_SESSION_DATA_CAPTION: * * Caption for the UI dialog. */ #define SIGNON_SESSION_DATA_CAPTION "Caption" /** * SIGNON_SESSION_DATA_TIMEOUT: * * Network timeout, in milliseconds (uint32). */ #define SIGNON_SESSION_DATA_TIMEOUT "NetworkTimeout" /** * SIGNON_SESSION_DATA_WINDOW_ID: * * Platform-specific window id (for dialog transiency) - uint32. */ #define SIGNON_SESSION_DATA_WINDOW_ID "WindowId" /** * SIGNON_SESSION_DATA_RENEW_TOKEN: * * Requests the signon plugin to obtain a new token (boolean). */ #define SIGNON_SESSION_DATA_RENEW_TOKEN "RenewToken" #define SIGNON_TYPE_AUTH_SESSION (signon_auth_session_get_type ()) #define SIGNON_AUTH_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SIGNON_TYPE_AUTH_SESSION, SignonAuthSession)) #define SIGNON_AUTH_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SIGNON_TYPE_AUTH_SESSION, SignonAuthSessionClass)) #define SIGNON_IS_AUTH_SESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SIGNON_TYPE_AUTH_SESSION)) #define SIGNON_IS_AUTH_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SIGNON_TYPE_AUTH_SESSION)) #define SIGNON_AUTH_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SIGNON_TYPE_AUTH_SESSION, SignonAuthSessionClass)) typedef struct _SignonAuthSession SignonAuthSession; typedef struct _SignonAuthSessionPrivate SignonAuthSessionPrivate; typedef struct _SignonAuthSessionClass SignonAuthSessionClass; /** * SignonAuthSession: * * Opaque struct. Use the accessor functions below. */ struct _SignonAuthSession { GObject parent; SignonAuthSessionPrivate *priv; }; /** * SignonAuthSessionClass: * * Opaque struct. Use the accessor functions below. */ struct _SignonAuthSessionClass { GObjectClass parent; }; GType signon_auth_session_get_type (void) G_GNUC_CONST; SignonAuthSession *signon_auth_session_new(gint id, const gchar *method_name, GError **err); const gchar *signon_auth_session_get_method (SignonAuthSession *self); typedef void (*SignonAuthSessionQueryAvailableMechanismsCb) ( SignonAuthSession* self, gchar **mechanisms, const GError *error, gpointer user_data); G_GNUC_DEPRECATED typedef SignonAuthSessionQueryAvailableMechanismsCb SignonAuthSessionQueryAvailableMethodsCb; void signon_auth_session_query_available_mechanisms(SignonAuthSession *self, const gchar **wanted_mechanisms, SignonAuthSessionQueryAvailableMechanismsCb cb, gpointer user_data); #ifndef SIGNON_DISABLE_DEPRECATED typedef void (*SignonAuthSessionProcessCb) (SignonAuthSession *self, GHashTable *session_data, const GError *error, gpointer user_data); SIGNON_DEPRECATED_FOR(signon_auth_session_process_async) void signon_auth_session_process(SignonAuthSession *self, const GHashTable *session_data, const gchar *mechanism, SignonAuthSessionProcessCb cb, gpointer user_data); #endif void signon_auth_session_process_async (SignonAuthSession *self, GVariant *session_data, const gchar *mechanism, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); GVariant *signon_auth_session_process_finish (SignonAuthSession *self, GAsyncResult *res, GError **error); void signon_auth_session_cancel(SignonAuthSession *self); G_END_DECLS #endif //SIGNONAUTHSESSIONIMPL_H_ ./libsignon-glib/signon-glib.h0000644000004100000410000000240513013271000016507 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2011-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 SIGNON_GLIB_H #define SIGNON_GLIB_H #include #include #include #include #include #include #endif /* SIGNON_GLIB_H */ ./libsignon-glib/signon-auth-session.c0000644000004100000410000007201713013271000020215 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. * Copyright (C) 2012-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 */ /** * SECTION:signon-auth-session * @title: SignonAuthSession * @short_description: Authentication session handler. * * The #SignonAuthSession object is responsible for handling the client * authentication. #SignonAuthSession objects can be created from existing * identities (via signon_identity_create_session() or by passing a non-zero ID * to signon_auth_session_new()), in which case the authentication data such as * username and password will be implicitly taken from the identity, or they * can be created with no existing identity bound to them, in which case all * the authentication data must be filled in by the client when * signon_auth_session_process() is called. */ #include "signon-internals.h" #include "signon-auth-session.h" #include "signon-errors.h" #include "signon-marshal.h" #include "signon-proxy.h" #include "signon-utils.h" #include "sso-auth-service.h" #include "sso-auth-session-gen.h" /* SignonAuthSessionState is defined in signoncommon.h */ #include static void signon_auth_session_proxy_if_init (SignonProxyInterface *iface); G_DEFINE_TYPE_WITH_CODE (SignonAuthSession, signon_auth_session, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (SIGNON_TYPE_PROXY, signon_auth_session_proxy_if_init)) /* Signals */ enum { STATE_CHANGED, LAST_SIGNAL }; static guint auth_session_signals[LAST_SIGNAL] = { 0 }; static const gchar auth_session_process_pending_message[] = "The request is added to queue."; static const gchar data_key_process[] = "signon-process"; struct _SignonAuthSessionPrivate { SsoAuthSession *proxy; SsoAuthService *auth_service_proxy; GCancellable *cancellable; gint id; gchar *method_name; gboolean registering; gboolean busy; gboolean canceled; gboolean dispose_has_run; guint signal_state_changed; guint signal_unregistered; }; typedef struct _AuthSessionQueryAvailableMechanismsData { gchar **wanted_mechanisms; gpointer cb_data; } AuthSessionQueryAvailableMechanismsData; typedef struct _AuthSessionProcessData { GVariant *session_data; gchar *mechanism; } AuthSessionProcessData; typedef struct _AuthSessionQueryAvailableMechanismsCbData { SignonAuthSession *self; SignonAuthSessionQueryAvailableMechanismsCb cb; gpointer user_data; } AuthSessionQueryAvailableMechanismsCbData; typedef struct _AuthSessionProcessCbData { SignonAuthSessionProcessCb cb; gpointer user_data; } AuthSessionProcessCbData; #define SIGNON_AUTH_SESSION_PRIV(obj) (SIGNON_AUTH_SESSION(obj)->priv) #define SIGNON_AUTH_SESSION_GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SIGNON_TYPE_AUTH_SESSION, SignonAuthSessionPrivate)) static void auth_session_state_changed_cb (GDBusProxy *proxy, gint state, gchar *message, gpointer user_data); static void auth_session_remote_object_destroyed_cb (GDBusProxy *proxy, gpointer user_data); static gboolean auth_session_priv_init (SignonAuthSession *self, guint id, const gchar *method_name, GError **err); static void auth_session_set_id_ready_cb (gpointer object, const GError *error, gpointer user_data); static void auth_session_query_available_mechanisms_ready_cb (gpointer object, const GError *error, gpointer user_data); static void auth_session_cancel_ready_cb (gpointer object, const GError *error, gpointer user_data); static void auth_session_check_remote_object(SignonAuthSession *self); static void auth_session_process_data_free (AuthSessionProcessData *process_data) { g_free (process_data->mechanism); g_variant_unref (process_data->session_data); g_slice_free (AuthSessionProcessData, process_data); } static void auth_session_process_reply (GObject *object, GAsyncResult *res, gpointer userdata) { SignonAuthSession *self; SsoAuthSession *proxy = SSO_AUTH_SESSION (object); GTask *res_process = userdata; GVariant *reply; GError *error = NULL; g_return_if_fail (res_process != NULL); sso_auth_session_call_process_finish (proxy, &reply, res, &error); self = SIGNON_AUTH_SESSION (g_task_get_source_object (res_process)); self->priv->busy = FALSE; if (G_LIKELY (error == NULL)) { g_task_return_pointer (res_process, reply, (GDestroyNotify) g_variant_unref); } else { g_task_return_error (res_process, error); } g_object_unref (res_process); } static void auth_session_process_ready_cb (gpointer object, const GError *error, gpointer user_data) { SignonAuthSession *self = SIGNON_AUTH_SESSION (object); SignonAuthSessionPrivate *priv; GTask *res = G_TASK (user_data); AuthSessionProcessData *process_data; g_return_if_fail (self != NULL); priv = self->priv; if (error != NULL) { DEBUG ("AuthSessionError: %s", error->message); g_task_return_error (res, g_error_copy (error)); g_object_unref (res); return; } if (priv->canceled) { priv->busy = FALSE; priv->canceled = FALSE; g_task_return_new_error (res, signon_error_quark (), SIGNON_ERROR_SESSION_CANCELED, "Authentication session was canceled"); g_object_unref (res); return; } process_data = g_object_get_data ((GObject *)res, data_key_process); g_return_if_fail (process_data != NULL); sso_auth_session_call_process (priv->proxy, process_data->session_data, process_data->mechanism, g_task_get_cancellable (res), auth_session_process_reply, res); g_signal_emit (self, auth_session_signals[STATE_CHANGED], 0, SIGNON_AUTH_SESSION_STATE_PROCESS_PENDING, auth_session_process_pending_message); } static void process_async_cb_wrapper (GObject *object, GAsyncResult *res, gpointer user_data) { AuthSessionProcessCbData *cb_data = user_data; SignonAuthSession *self = SIGNON_AUTH_SESSION (object); GVariant *v_reply; GHashTable *reply = NULL; GError *error = NULL; gboolean cancelled; v_reply = signon_auth_session_process_finish (self, res, &error); cancelled = error != NULL && error->domain == G_IO_ERROR && error->code == G_IO_ERROR_CANCELLED; /* Do not invoke the callback if the operation was cancelled */ if (cb_data->cb != NULL && !cancelled) { if (v_reply != NULL) reply = signon_hash_table_from_variant (v_reply); cb_data->cb (self, reply, error, cb_data->user_data); if (reply != NULL) g_hash_table_unref (reply); } if (v_reply != NULL) g_variant_unref (v_reply); g_slice_free (AuthSessionProcessCbData, cb_data); g_clear_error (&error); } static void destroy_proxy (SignonAuthSessionPrivate *priv) { g_signal_handler_disconnect (priv->proxy, priv->signal_state_changed); g_signal_handler_disconnect (priv->proxy, priv->signal_unregistered); g_object_unref (priv->proxy); priv->proxy = NULL; } static GQuark auth_session_object_quark () { static GQuark quark = 0; if (!quark) quark = g_quark_from_static_string ("auth_session_object_quark"); return quark; } static void signon_auth_session_proxy_setup (SignonProxy *proxy) { auth_session_check_remote_object (SIGNON_AUTH_SESSION (proxy)); } static void signon_auth_session_proxy_if_init (SignonProxyInterface *iface) { iface->setup = signon_auth_session_proxy_setup; } static void signon_auth_session_init (SignonAuthSession *self) { self->priv = SIGNON_AUTH_SESSION_GET_PRIV (self); self->priv->auth_service_proxy = sso_auth_service_get_instance (); self->priv->cancellable = g_cancellable_new (); } static void signon_auth_session_dispose (GObject *object) { g_return_if_fail (SIGNON_IS_AUTH_SESSION (object)); SignonAuthSession *self = SIGNON_AUTH_SESSION (object); SignonAuthSessionPrivate *priv = self->priv; g_return_if_fail (priv != NULL); if (priv->dispose_has_run) return; if (priv->cancellable) { g_cancellable_cancel (priv->cancellable); g_object_unref (priv->cancellable); priv->cancellable = NULL; } if (priv->proxy) destroy_proxy (priv); if (priv->auth_service_proxy) { g_object_unref (priv->auth_service_proxy); priv->auth_service_proxy = NULL; } G_OBJECT_CLASS (signon_auth_session_parent_class)->dispose (object); priv->dispose_has_run = TRUE; } static void signon_auth_session_finalize (GObject *object) { g_return_if_fail (SIGNON_IS_AUTH_SESSION(object)); SignonAuthSession *self = SIGNON_AUTH_SESSION(object); SignonAuthSessionPrivate *priv = self->priv; g_return_if_fail (priv != NULL); g_free (priv->method_name); G_OBJECT_CLASS (signon_auth_session_parent_class)->finalize (object); } static void signon_auth_session_class_init (SignonAuthSessionClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); g_type_class_add_private (object_class, sizeof (SignonAuthSessionPrivate)); /** * SignonAuthSession::state-changed: * @auth_session: the #SignonAuthSession * @state: the current state of the #SignonAuthSession * @message: the message associated with the state change * * Emitted when the state of the #SignonAuthSession changes. */ auth_session_signals[STATE_CHANGED] = g_signal_new ("state-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, 0, NULL, NULL, _signon_marshal_VOID__INT_STRING, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING); object_class->dispose = signon_auth_session_dispose; object_class->finalize = signon_auth_session_finalize; } /** * signon_auth_session_new: * @id: the id of the #SignonIdentity to be used. Can be 0, if this session is * not bound to any stored identity. * @method_name: the name of the authentication method to be used. * @err: a pointer to a location which will contain the error, in case this * function fails. * * Creates a new #SignonAuthSession, which can be used to authenticate using * the specified method. * * Returns: a new #SignonAuthSession. */ SignonAuthSession * signon_auth_session_new (gint id, const gchar *method_name, GError **err) { SignonAuthSession *self = SIGNON_AUTH_SESSION(g_object_new (SIGNON_TYPE_AUTH_SESSION, NULL)); g_return_val_if_fail (self != NULL, NULL); if (!auth_session_priv_init(self, id, method_name, err)) { if (*err) g_warning ("%s returned error: %s", G_STRFUNC, (*err)->message); g_object_unref (self); return NULL; } return self; } static void auth_session_set_id_ready_cb (gpointer object, const GError *error, gpointer user_data) { if (error) { g_warning ("%s returned error: %s", G_STRFUNC, error->message); return; } g_return_if_fail (SIGNON_IS_AUTH_SESSION (object)); SignonAuthSession *self = SIGNON_AUTH_SESSION (object); SignonAuthSessionPrivate *priv = self->priv; g_return_if_fail (priv != NULL); gint id = GPOINTER_TO_INT(user_data); GError *err = NULL; sso_auth_session_call_set_id_sync (priv->proxy, id, priv->cancellable, &err); priv->id = id; if (err) g_warning ("%s returned error: %s", G_STRFUNC, err->message); g_clear_error(&err); } void signon_auth_session_set_id(SignonAuthSession* self, gint id) { g_return_if_fail (SIGNON_IS_AUTH_SESSION (self)); g_return_if_fail (id >= 0); signon_proxy_call_when_ready (self, auth_session_object_quark(), auth_session_set_id_ready_cb, GINT_TO_POINTER(id)); } /** * signon_auth_session_get_method: * @self: the #SignonAuthSession. * * Get the current authentication method. * * Returns: the authentication method being used, or %NULL on failure. */ const gchar * signon_auth_session_get_method (SignonAuthSession *self) { g_return_val_if_fail (SIGNON_IS_AUTH_SESSION (self), NULL); SignonAuthSessionPrivate *priv = self->priv; g_return_val_if_fail (priv != NULL, NULL); return priv->method_name; } /** * SignonAuthSessionQueryAvailableMechanismsCb: * @self: the #SignonAuthSession. * @mechanisms: (transfer full) (type GStrv): list of available mechanisms. * @error: a #GError if an error occurred, %NULL otherwise. * @user_data: the user data that was passed when installing this callback. * * Callback to be passed to signon_auth_session_query_available_mechanisms(). */ /** * signon_auth_session_query_available_mechanisms: * @self: the #SignonAuthSession. * @wanted_mechanisms: a %NULL-terminated list of mechanisms supported by the client. * @cb: (scope async): a callback which will be called with the result. * @user_data: user data to be passed to the callback. * * Queries the mechanisms available for this authentication session. the result * will be the intersection between @wanted_mechanisms and the mechanisms * supported by the authentication plugin. */ void signon_auth_session_query_available_mechanisms (SignonAuthSession *self, const gchar **wanted_mechanisms, SignonAuthSessionQueryAvailableMechanismsCb cb, gpointer user_data) { g_return_if_fail (SIGNON_IS_AUTH_SESSION (self)); AuthSessionQueryAvailableMechanismsCbData *cb_data = g_slice_new0 (AuthSessionQueryAvailableMechanismsCbData); cb_data->self = self; cb_data->cb = cb; cb_data->user_data = user_data; AuthSessionQueryAvailableMechanismsData *operation_data = g_slice_new0 (AuthSessionQueryAvailableMechanismsData); operation_data->wanted_mechanisms = g_strdupv ((gchar **)wanted_mechanisms); operation_data->cb_data = cb_data; signon_proxy_call_when_ready (self, auth_session_object_quark(), auth_session_query_available_mechanisms_ready_cb, operation_data); } /** * SignonAuthSessionProcessCb: * @self: the #SignonAuthSession. * @session_data: (transfer none) (element-type utf8 GValue): a dictionary with * the response. * @error: a #GError if an error occurred, %NULL otherwise. * @user_data: the user data that was passed when installing this callback. * * This callback is invoked when the authentication plugin delivers the result * of the signon_auth_session_process() operation. */ /** * signon_auth_session_process: * @self: the #SignonAuthSession. * @session_data: (transfer none) (element-type utf8 GValue): a dictionary of parameters. * @mechanism: the authentication mechanism to be used. * @cb: (scope async): a callback which will be called with the result. * @user_data: user data to be passed to the callback. * * Performs one step of the authentication process. If the #SignonAuthSession * object is bound to an existing identity, the identity properties such as * username and password will be also passed to the authentication plugin, so * there's no need to fill them into @session_data. * @session_data can be used to add additional authentication parameters to the * session, or to override the parameters otherwise taken from the identity. * * Deprecated: 1.8: Use signon_auth_session_process_async() instead. */ void signon_auth_session_process (SignonAuthSession *self, const GHashTable *session_data, const gchar* mechanism, SignonAuthSessionProcessCb cb, gpointer user_data) { GVariant *v_session_data; g_return_if_fail (SIGNON_IS_AUTH_SESSION (self)); AuthSessionProcessCbData *cb_data = g_slice_new0 (AuthSessionProcessCbData); cb_data->cb = cb; cb_data->user_data = user_data; v_session_data = signon_hash_table_to_variant (session_data); signon_auth_session_process_async (self, v_session_data, mechanism, NULL, process_async_cb_wrapper, cb_data); } /** * signon_auth_session_process_async: * @self: the #SignonAuthSession. * @session_data: (transfer floating): a dictionary of parameters. * @mechanism: the authentication mechanism to be used. * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore. * @callback: (scope async): a callback which will be called when the * authentication reply is available. * @user_data: user data to be passed to the callback. * * Performs one step of the authentication process. If the #SignonAuthSession * object is bound to an existing identity, the identity properties such as * username and password will be also passed to the authentication plugin, so * there's no need to fill them into @session_data. * @session_data can be used to add additional authentication parameters to the * session, or to override the parameters otherwise taken from the identity. * * Since: 1.8 */ void signon_auth_session_process_async (SignonAuthSession *self, GVariant *session_data, const gchar *mechanism, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { SignonAuthSessionPrivate *priv; AuthSessionProcessData *process_data; GTask *res; g_return_if_fail (SIGNON_IS_AUTH_SESSION (self)); priv = self->priv; g_return_if_fail (session_data != NULL); res = g_task_new (self, cancellable, callback, user_data); process_data = g_slice_new0 (AuthSessionProcessData); process_data->session_data = g_variant_ref_sink (session_data); process_data->mechanism = g_strdup (mechanism); g_object_set_data_full ((GObject *)res, data_key_process, process_data, (GDestroyNotify)auth_session_process_data_free); priv->busy = TRUE; signon_proxy_call_when_ready (self, auth_session_object_quark(), auth_session_process_ready_cb, res); } /** * signon_auth_session_process_finish: * @self: the #SignonAuthSession. * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to * signon_auth_session_process_async(). * @error: return location for error, or %NULL. * * Collect the result of the signon_auth_session_process_async() operation. * * Returns: a #GVariant of type %G_VARIANT_TYPE_VARDICT containing the * authentication reply. * * Since: 1.8 */ GVariant * signon_auth_session_process_finish (SignonAuthSession *self, GAsyncResult *res, GError **error) { GTask *task; g_return_val_if_fail (SIGNON_IS_AUTH_SESSION (self), NULL); task = G_TASK (res); return g_task_propagate_pointer (task, error); } /** * signon_auth_session_cancel: * @self: the #SignonAuthSession. * * Cancel the authentication session. */ void signon_auth_session_cancel (SignonAuthSession *self) { g_return_if_fail (SIGNON_IS_AUTH_SESSION (self)); SignonAuthSessionPrivate *priv = self->priv; g_return_if_fail (priv != NULL); if (!priv->busy) return; priv->canceled = TRUE; signon_proxy_call_when_ready (self, auth_session_object_quark(), auth_session_cancel_ready_cb, NULL); } static void auth_session_get_object_path_reply (GObject *object, GAsyncResult *res, gpointer userdata) { SsoAuthService *proxy = SSO_AUTH_SERVICE (object); gchar *object_path = NULL; GError *error = NULL; sso_auth_service_call_get_auth_session_object_path_finish (proxy, &object_path, res, &error); SIGNON_RETURN_IF_CANCELLED (error); g_return_if_fail (SIGNON_IS_AUTH_SESSION (userdata)); SignonAuthSession *self = SIGNON_AUTH_SESSION (userdata); SignonAuthSessionPrivate *priv = self->priv; g_return_if_fail (priv != NULL); priv->registering = FALSE; if (!g_strcmp0(object_path, "") || error) { if (error) DEBUG ("Error message is %s", error->message); else error = g_error_new (signon_error_quark(), SIGNON_ERROR_RUNTIME, "Cannot create remote AuthSession object"); } else { GDBusConnection *connection; const gchar *bus_name; GError *proxy_error = NULL; connection = g_dbus_proxy_get_connection ((GDBusProxy *)proxy); bus_name = g_dbus_proxy_get_name ((GDBusProxy *)proxy); priv->proxy = sso_auth_session_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, bus_name, object_path, priv->cancellable, &proxy_error); if (G_UNLIKELY (proxy_error != NULL)) { g_warning ("Failed to initialize AuthSession proxy: %s", proxy_error->message); g_clear_error (&proxy_error); } g_dbus_proxy_set_default_timeout ((GDBusProxy *)priv->proxy, G_MAXINT); priv->signal_state_changed = g_signal_connect (priv->proxy, "state-changed", G_CALLBACK (auth_session_state_changed_cb), self); priv->signal_unregistered = g_signal_connect (priv->proxy, "unregistered", G_CALLBACK (auth_session_remote_object_destroyed_cb), self); } DEBUG ("Object path received: %s", object_path); g_free (object_path); signon_proxy_set_ready (self, auth_session_object_quark (), error); } static void auth_session_state_changed_cb (GDBusProxy *proxy, gint state, gchar *message, gpointer user_data) { g_return_if_fail (SIGNON_IS_AUTH_SESSION (user_data)); SignonAuthSession *self = SIGNON_AUTH_SESSION (user_data); g_signal_emit ((GObject *)self, auth_session_signals[STATE_CHANGED], 0, state, message); } static void auth_session_remote_object_destroyed_cb (GDBusProxy *proxy, gpointer user_data) { g_return_if_fail (SIGNON_IS_AUTH_SESSION (user_data)); SignonAuthSession *self = SIGNON_AUTH_SESSION (user_data); SignonAuthSessionPrivate *priv = self->priv; g_return_if_fail (priv != NULL); DEBUG ("remote object unregistered"); if (priv->proxy) destroy_proxy (priv); signon_proxy_set_not_ready (self); } static gboolean auth_session_priv_init (SignonAuthSession *self, guint id, const gchar *method_name, GError **err) { g_return_val_if_fail (SIGNON_IS_AUTH_SESSION (self), FALSE); SignonAuthSessionPrivate *priv = SIGNON_AUTH_SESSION_PRIV (self); g_return_val_if_fail (priv, FALSE); priv->id = id; priv->method_name = g_strdup (method_name); priv->registering = FALSE; priv->busy = FALSE; priv->canceled = FALSE; return TRUE; } static void auth_session_query_mechanisms_reply (GObject *object, GAsyncResult *res, gpointer userdata) { SsoAuthSession *proxy = SSO_AUTH_SESSION (object); gchar **mechanisms = NULL; GError *error = NULL; AuthSessionQueryAvailableMechanismsCbData *cb_data = (AuthSessionQueryAvailableMechanismsCbData *)userdata; g_return_if_fail (cb_data != NULL); sso_auth_session_call_query_available_mechanisms_finish (proxy, &mechanisms, res, &error); SIGNON_RETURN_IF_CANCELLED (error); (cb_data->cb) (cb_data->self, mechanisms, error, cb_data->user_data); if (error) g_error_free (error); g_slice_free (AuthSessionQueryAvailableMechanismsCbData, cb_data); } static void auth_session_query_available_mechanisms_ready_cb (gpointer object, const GError *error, gpointer user_data) { g_return_if_fail (SIGNON_IS_AUTH_SESSION (object)); SignonAuthSession *self = SIGNON_AUTH_SESSION (object); SignonAuthSessionPrivate *priv = self->priv; g_return_if_fail (priv != NULL); AuthSessionQueryAvailableMechanismsData *operation_data = (AuthSessionQueryAvailableMechanismsData *)user_data; g_return_if_fail (operation_data != NULL); AuthSessionQueryAvailableMechanismsCbData *cb_data = operation_data->cb_data; g_return_if_fail (cb_data != NULL); if (error) { (cb_data->cb) (self, NULL, error, cb_data->user_data); g_slice_free (AuthSessionQueryAvailableMechanismsCbData, cb_data); } else { g_return_if_fail (priv->proxy != NULL); sso_auth_session_call_query_available_mechanisms ( priv->proxy, (const char **)operation_data->wanted_mechanisms, priv->cancellable, auth_session_query_mechanisms_reply, cb_data); g_signal_emit (self, auth_session_signals[STATE_CHANGED], 0, SIGNON_AUTH_SESSION_STATE_PROCESS_PENDING, auth_session_process_pending_message); } g_strfreev (operation_data->wanted_mechanisms); g_slice_free (AuthSessionQueryAvailableMechanismsData, operation_data); } static void auth_session_cancel_ready_cb (gpointer object, const GError *error, gpointer user_data) { g_return_if_fail (SIGNON_IS_AUTH_SESSION (object)); g_return_if_fail (user_data == NULL); SignonAuthSession *self = SIGNON_AUTH_SESSION (object); SignonAuthSessionPrivate *priv = self->priv; g_return_if_fail (priv != NULL); if (error) { //TODO: in general this function does not return any values, // that is why I think it should not emit anything for this particular case DEBUG("error during initialization"); } else if (priv->proxy && priv->busy) sso_auth_session_call_cancel_sync (priv->proxy, priv->cancellable, NULL); priv->busy = FALSE; priv->canceled = FALSE; } static void auth_session_check_remote_object(SignonAuthSession *self) { g_return_if_fail (self != NULL); SignonAuthSessionPrivate *priv = self->priv; g_return_if_fail (priv != NULL); if (priv->proxy != NULL) return; g_return_if_fail (priv->auth_service_proxy != NULL); if (!priv->registering) { priv->registering = TRUE; sso_auth_service_call_get_auth_session_object_path ( priv->auth_service_proxy, priv->id, priv->method_name, priv->cancellable, auth_session_get_object_path_reply, self); } } ./libsignon-glib/signon-utils.h0000644000004100000410000000306413013271000016734 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. * Copyright (C) 2012-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 _SIGNON_UTILS_H_ #define _SIGNON_UTILS_H_ #include #define SIGNON_RETURN_IF_CANCELLED(error) \ if (error != NULL && \ error->domain == G_IO_ERROR && \ error->code == G_IO_ERROR_CANCELLED) \ { \ g_error_free (error); \ return; \ } G_GNUC_INTERNAL GValue *signon_gvalue_new (GType type); G_GNUC_INTERNAL void signon_gvalue_free (gpointer val); G_GNUC_INTERNAL GHashTable *signon_hash_table_from_variant (GVariant *variant); G_GNUC_INTERNAL GVariant *signon_hash_table_to_variant (const GHashTable *hash_table); #endif //_SIGNON_UTILS_H_ ./libsignon-glib/signon-proxy.c0000644000004100000410000001410313013271000016744 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. * Copyright (C) 2012-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 "signon-proxy.h" #include "signon-internals.h" G_DEFINE_INTERFACE (SignonProxy, signon_proxy, G_TYPE_OBJECT) typedef struct { SignonReadyCb callback; gpointer user_data; } SignonReadyCbData; typedef struct { gpointer self; GSList *callbacks; GSource *idle_source; } SignonReadyData; static void signon_proxy_default_init (SignonProxyInterface *iface) { /* add properties and signals to the interface here */ } static GQuark _signon_proxy_ready_quark() { static GQuark quark = 0; if (!quark) quark = g_quark_from_static_string ("signon_proxy_ready_quark"); return quark; } static GQuark _signon_proxy_error_quark() { static GQuark quark = 0; if (!quark) quark = g_quark_from_static_string ("signon_proxy_error_quark"); return quark; } static void signon_proxy_invoke_ready_callbacks (SignonReadyData *rd, const GError *error) { GSList *list; /* Make a copy of the callbacks list and erase the pointer in the * structure, to ensure that we won't invoke the same callback twice. */ GSList *callbacks = rd->callbacks; rd->callbacks = NULL; for (list = callbacks; list != NULL; list = list->next) { SignonReadyCbData *cb = list->data; cb->callback (rd->self, error, cb->user_data); g_slice_free (SignonReadyCbData, cb); } g_slist_free (callbacks); } static void signon_ready_data_free (SignonReadyData *rd) { if (rd->self) { //TODO: Signon error codes need be presented instead of 555 and 666 GError error = { 555, 666, "Object disposed" }; signon_proxy_invoke_ready_callbacks (rd, &error); } if (rd->idle_source) { g_main_context_unref (g_source_get_context (rd->idle_source)); g_source_destroy (rd->idle_source); rd->idle_source = NULL; } g_slice_free (SignonReadyData, rd); } static gboolean signon_proxy_call_when_ready_idle (SignonReadyData *rd) { if (GPOINTER_TO_INT (g_object_get_qdata((GObject*)rd->self, _signon_proxy_ready_quark())) == TRUE) { //TODO: specify the last error in object initialization GError * err = g_object_get_qdata((GObject*)rd->self, _signon_proxy_error_quark()); signon_proxy_invoke_ready_callbacks (rd, err); } else { signon_proxy_setup (SIGNON_PROXY (rd->self)); } g_main_context_unref (g_source_get_context (rd->idle_source)); rd->idle_source = NULL; return FALSE; } void signon_proxy_setup (gpointer self) { SignonProxyInterface *iface; g_return_if_fail (SIGNON_IS_PROXY (self)); iface = SIGNON_PROXY_GET_IFACE (self); if (iface->setup != NULL) { iface->setup (self); } } void signon_proxy_call_when_ready (gpointer object, GQuark quark, SignonReadyCb callback, gpointer user_data) { SignonReadyData *rd; SignonReadyCbData *cb; g_return_if_fail (SIGNON_IS_PROXY (object)); g_return_if_fail (quark != 0); g_return_if_fail (callback != NULL); cb = g_slice_new (SignonReadyCbData); cb->callback = callback; cb->user_data = user_data; rd = g_object_get_qdata ((GObject *)object, quark); if (!rd) { rd = g_slice_new (SignonReadyData); rd->self = object; rd->callbacks = NULL; rd->idle_source = NULL; g_object_set_qdata_full ((GObject *)object, quark, rd, (GDestroyNotify)signon_ready_data_free); } rd->callbacks = g_slist_append (rd->callbacks, cb); if (!rd->idle_source) { rd->idle_source = g_idle_source_new (); g_source_set_callback (rd->idle_source, (GSourceFunc)signon_proxy_call_when_ready_idle, rd, NULL); g_source_attach (rd->idle_source, g_main_context_ref_thread_default ()); } } void signon_proxy_set_ready (gpointer object, GQuark quark, GError *error) { SignonReadyData *rd; g_return_if_fail (SIGNON_IS_PROXY (object)); g_object_set_qdata((GObject *)object, _signon_proxy_ready_quark(), GINT_TO_POINTER(TRUE)); if(error) g_object_set_qdata_full ((GObject *)object, _signon_proxy_error_quark(), error, (GDestroyNotify)g_error_free); rd = g_object_get_qdata ((GObject *)object, quark); if (!rd) return; g_object_ref (object); signon_proxy_invoke_ready_callbacks (rd, error); g_object_unref (object); } void signon_proxy_set_not_ready (gpointer object) { g_return_if_fail (SIGNON_IS_PROXY (object)); g_object_set_qdata ((GObject *)object, _signon_proxy_ready_quark(), GINT_TO_POINTER(FALSE)); g_object_set_qdata ((GObject *)object, _signon_proxy_error_quark(), NULL); } const GError * signon_proxy_get_last_error (gpointer object) { g_return_val_if_fail (SIGNON_IS_PROXY (object), NULL); return g_object_get_qdata((GObject *)object, _signon_proxy_error_quark()); } ./libsignon-glib/signon-proxy.h0000644000004100000410000000366013013271000016757 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. * Copyright (C) 2012-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 _SIGNON_PROXY_H_ #define _SIGNON_PROXY_H_ #include #include G_BEGIN_DECLS #define SIGNON_TYPE_PROXY (signon_proxy_get_type ()) G_GNUC_INTERNAL G_DECLARE_INTERFACE(SignonProxy, signon_proxy, SIGNON, PROXY, GObject) typedef void (*SignonReadyCb) (gpointer object, const GError *error, gpointer user_data); struct _SignonProxyInterface { GTypeInterface parent_iface; void (*setup) (SignonProxy *self); }; G_GNUC_INTERNAL void signon_proxy_setup (gpointer self); G_GNUC_INTERNAL void signon_proxy_call_when_ready (gpointer self, GQuark quark, SignonReadyCb callback, gpointer user_data); G_GNUC_INTERNAL void signon_proxy_set_ready (gpointer self, GQuark quark, GError *error); G_GNUC_INTERNAL void signon_proxy_set_not_ready (gpointer self); G_GNUC_INTERNAL const GError *signon_proxy_get_last_error (gpointer self); G_END_DECLS #endif /* _SIGNON_PROXY_H_ */ ./libsignon-glib/signon-types.h0000644000004100000410000000237613013271000016745 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2012-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 SIGNON_TYPES_H #define SIGNON_TYPES_H #include G_BEGIN_DECLS #ifdef SIGNON_DISABLE_DEPRECATION_WARNINGS #define SIGNON_DEPRECATED #define SIGNON_DEPRECATED_FOR(x) #else #define SIGNON_DEPRECATED G_DEPRECATED #define SIGNON_DEPRECATED_FOR(x) G_DEPRECATED_FOR(x) #endif G_END_DECLS #endif /* SIGNON_TYPES_H */ ./libsignon-glib/signon-utils.c0000644000004100000410000000714413013271000016732 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. * Copyright (C) 2012-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 "signon-utils.h" #include static const GVariantType * signon_gtype_to_variant_type (GType type) { switch (type) { case G_TYPE_STRING: return G_VARIANT_TYPE_STRING; case G_TYPE_BOOLEAN: return G_VARIANT_TYPE_BOOLEAN; case G_TYPE_UCHAR: return G_VARIANT_TYPE_BYTE; case G_TYPE_INT: return G_VARIANT_TYPE_INT32; case G_TYPE_UINT: return G_VARIANT_TYPE_UINT32; case G_TYPE_INT64: return G_VARIANT_TYPE_INT64; case G_TYPE_UINT64: return G_VARIANT_TYPE_UINT64; case G_TYPE_DOUBLE: return G_VARIANT_TYPE_DOUBLE; default: if (type == G_TYPE_STRV) return G_VARIANT_TYPE_STRING_ARRAY; g_critical ("Unsupported type %s", g_type_name (type)); return NULL; } } GValue * signon_gvalue_new (GType type) { GValue *value = g_slice_new0 (GValue); g_value_init (value, type); return value; } void signon_gvalue_free (gpointer val) { g_return_if_fail (G_IS_VALUE(val)); GValue *value = (GValue*)val; g_value_unset (value); g_slice_free (GValue, value); } GHashTable *signon_hash_table_from_variant (GVariant *variant) { GHashTable *hash_table; GVariantIter iter; GVariant *value; gchar *key; if (variant == NULL) return NULL; hash_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, signon_gvalue_free); g_variant_iter_init (&iter, variant); while (g_variant_iter_next (&iter, "{sv}", &key, &value)) { GValue *val = g_slice_new0 (GValue); g_dbus_gvariant_to_gvalue (value, val); g_variant_unref (value); g_hash_table_insert (hash_table, key, val); } return hash_table; } GVariant *signon_hash_table_to_variant (const GHashTable *hash_table) { GVariantBuilder builder; GHashTableIter iter; const gchar *key; const GValue *value; if (hash_table == NULL) return NULL; g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); g_hash_table_iter_init (&iter, (GHashTable *)hash_table); while (g_hash_table_iter_next (&iter, (gpointer)&key, (gpointer)&value)) { GVariant *val; if (G_VALUE_TYPE (value) == G_TYPE_VARIANT) { val = g_value_dup_variant (value); } else { const GVariantType *type; type = signon_gtype_to_variant_type (G_VALUE_TYPE (value)); val = g_dbus_gvalue_to_gvariant (value, type); } g_variant_builder_add (&builder, "{sv}", key, val); g_variant_unref (val); } return g_variant_builder_end (&builder); } ./libsignon-glib/signon-identity-info.h0000644000004100000410000000726113013271000020361 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. * Copyright (C) 2011-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 _SIGNON_IDENTITY_INFO_H_ #define _SIGNON_IDENTITY_INFO_H_ #include G_BEGIN_DECLS /** * SignonIdentityInfo: * * Opaque struct. Use the accessor functions below. */ typedef struct _SignonIdentityInfo SignonIdentityInfo; /** * SignonIdentityType: * @SIGNON_IDENTITY_TYPE_OTHER: an identity that is not an app, web or network * @SIGNON_IDENTITY_TYPE_APP: an application identity * @SIGNON_IDENTITY_TYPE_WEB: a web identity * @SIGNON_IDENTITY_TYPE_NETWORK: a network server identity * * Types used in #SignonIdentityInfo. */ typedef enum { SIGNON_IDENTITY_TYPE_OTHER = 0, SIGNON_IDENTITY_TYPE_APP = 1 << 0, SIGNON_IDENTITY_TYPE_WEB = 1 << 1, SIGNON_IDENTITY_TYPE_NETWORK = 1 << 2 } SignonIdentityType; GType signon_identity_info_get_type (void) G_GNUC_CONST; SignonIdentityInfo *signon_identity_info_new (); void signon_identity_info_free (SignonIdentityInfo *info); SignonIdentityInfo *signon_identity_info_copy (const SignonIdentityInfo *other); gint signon_identity_info_get_id (const SignonIdentityInfo *info); const gchar *signon_identity_info_get_username (const SignonIdentityInfo *info); gboolean signon_identity_info_get_storing_secret (const SignonIdentityInfo *info); const gchar *signon_identity_info_get_caption (const SignonIdentityInfo *info); const GHashTable *signon_identity_info_get_methods (const SignonIdentityInfo *info); const gchar* const *signon_identity_info_get_realms (const SignonIdentityInfo *info); const gchar* const *signon_identity_info_get_access_control_list (const SignonIdentityInfo *info); SignonIdentityType signon_identity_info_get_identity_type (const SignonIdentityInfo *info); void signon_identity_info_set_username (SignonIdentityInfo *info, const gchar *username); void signon_identity_info_set_secret (SignonIdentityInfo *info, const gchar *secret, gboolean store_secret); void signon_identity_info_set_caption (SignonIdentityInfo *info, const gchar *caption); void signon_identity_info_set_method (SignonIdentityInfo *info, const gchar *method, const gchar* const *mechanisms); void signon_identity_info_remove_method (SignonIdentityInfo *info, const gchar *method); void signon_identity_info_set_realms (SignonIdentityInfo *info, const gchar* const *realms); void signon_identity_info_set_access_control_list (SignonIdentityInfo *info, const gchar* const *access_control_list); void signon_identity_info_set_identity_type (SignonIdentityInfo *info, SignonIdentityType type); G_END_DECLS #endif /* _SIGNON_IDENTITY_INFO_H_ */ ./libsignon-glib/signon-identity.h0000644000004100000410000001745013013271000017431 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. * Copyright (C) 2012-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 _SIGNON_IDENTITY_H_ #define _SIGNON_IDENTITY_H_ #include #include #include G_BEGIN_DECLS #define SIGNON_TYPE_IDENTITY (signon_identity_get_type ()) #define SIGNON_IDENTITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SIGNON_TYPE_IDENTITY, SignonIdentity)) #define SIGNON_IDENTITY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SIGNON_TYPE_IDENTITY, SignonIdentityClass)) #define SIGNON_IS_IDENTITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SIGNON_TYPE_IDENTITY)) #define SIGNON_IS_IDENTITY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SIGNON_TYPE_IDENTITY)) #define SIGNON_IDENTITY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SIGNON_TYPE_IDENTITY, SignonIdentityClass)) typedef struct _SignonIdentityClass SignonIdentityClass; typedef struct _SignonIdentityPrivate SignonIdentityPrivate; typedef struct _SignonIdentity SignonIdentity; /** * SignonIdentityClass: * * Opaque struct. Use the accessor functions below. */ struct _SignonIdentityClass { GObjectClass parent_class; }; /** * SignonIdentity: * * Opaque struct. Use the accessor functions below. */ struct _SignonIdentity { GObject parent_instance; SignonIdentityPrivate *priv; }; /** * SignonIdentityVoidCb: * @self: the #SignonIdentity. * @error: a #GError if an error occurred, or %NULL otherwise. * @user_data: the user data that was passed when installing this callback. * * Generic callback to be passed to several #SignonIdentity methods. */ typedef void (*SignonIdentityVoidCb) (SignonIdentity *self, const GError *error, gpointer user_data); /** * SignonIdentityRemovedCb: * * Callback to be passed to signon_identity_remove(). */ typedef SignonIdentityVoidCb SignonIdentityRemovedCb; /** * SignonIdentitySignedOutCb: * * Callback to be passed to signon_identity_signout(). */ typedef SignonIdentityVoidCb SignonIdentitySignedOutCb; /** * SignonIdentityReferenceAddedCb: * * Callback to be passed to signon_identity_add_reference(). */ typedef SignonIdentityVoidCb SignonIdentityReferenceAddedCb; /** * SignonIdentityReferenceRemovedCb: * * Callback to be passed to signon_identity_remove_reference(). */ typedef SignonIdentityVoidCb SignonIdentityReferenceRemovedCb; GType signon_identity_get_type (void) G_GNUC_CONST; SignonIdentity *signon_identity_new_from_db (guint32 id); SignonIdentity *signon_identity_new (); const GError *signon_identity_get_last_error (SignonIdentity *identity); SignonAuthSession *signon_identity_create_session(SignonIdentity *self, const gchar *method, GError **error); /** * SignonIdentityStoreCredentialsCb: * @self: the #SignonIdentity. * @id: the numeric ID of the identity in the database. * @error: a #GError if an error occurred, or %NULL otherwise. * @user_data: the user data that was passed when installing this callback. * * Callback to be passed to signon_identity_store_credentials_with_args() or * signon_identity_store_credentials_with_info(). */ typedef void (*SignonIdentityStoreCredentialsCb) (SignonIdentity *self, guint32 id, const GError *error, gpointer user_data); void signon_identity_store_credentials_with_info(SignonIdentity *self, const SignonIdentityInfo *info, SignonIdentityStoreCredentialsCb cb, gpointer user_data); void signon_identity_store_credentials_with_args(SignonIdentity *self, const gchar *username, const gchar *secret, const gboolean store_secret, const GHashTable *methods, const gchar *caption, const gchar* const *realms, const gchar* const *access_control_list, SignonIdentityType type, SignonIdentityStoreCredentialsCb cb, gpointer user_data); /** * SignonIdentityVerifyCb: * @self: the #SignonIdentity. * @valid: whether the secret is valid. * @error: a #GError if an error occurred, or %NULL otherwise. * @user_data: the user data that was passed when installing this callback. * * Callback to be passed to signon_identity_verify_secret(). */ typedef void (*SignonIdentityVerifyCb) (SignonIdentity *self, gboolean valid, const GError *error, gpointer user_data); void signon_identity_verify_secret(SignonIdentity *self, const gchar *secret, SignonIdentityVerifyCb cb, gpointer user_data); /** * SignonIdentityInfoCb: * @self: the #SignonIdentity. * @info: (transfer none): the #SignonIdentityInfo for @self. * @error: a #GError if an error occurred, or %NULL otherwise. * @user_data: the user data that was passed when installing this callback. * * Callback to be passed to signon_identity_query_info(). */ typedef void (*SignonIdentityInfoCb) (SignonIdentity *self, const SignonIdentityInfo *info, const GError *error, gpointer user_data); void signon_identity_query_info(SignonIdentity *self, SignonIdentityInfoCb cb, gpointer user_data); void signon_identity_remove(SignonIdentity *self, SignonIdentityRemovedCb cb, gpointer user_data); void signon_identity_signout(SignonIdentity *self, SignonIdentitySignedOutCb cb, gpointer user_data); void signon_identity_add_reference(SignonIdentity *self, const gchar *reference, SignonIdentityReferenceAddedCb cb, gpointer user_data); void signon_identity_remove_reference(SignonIdentity *self, const gchar *reference, SignonIdentityReferenceRemovedCb cb, gpointer user_data); G_END_DECLS #endif /* _SIGNON_IDENTITY_H_ */ ./libsignon-glib/signon-identity.c0000644000004100000410000012701013013271000017416 0ustar www-datawww-data/* 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 libsignon-glib * * Copyright (C) 2009-2010 Nokia Corporation. * Copyright (C) 2012-2016 Canonical Ltd. * * Contact: Alberto Mardegan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * version 2.1 as published by the Free Software Foundation. * * 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 */ /** * SECTION:signon-identity * @title: SignonIdentity * @short_description: Client side presentation of a credential. * * The #SignonIdentity represents a database entry for a single identity. */ #include "signon-identity.h" #include "signon-auth-session.h" #include "signon-internals.h" #include "signon-proxy.h" #include "signon-utils.h" #include "signon-errors.h" #include "sso-auth-service.h" #include "sso-identity-gen.h" static void signon_identity_proxy_if_init (SignonProxyInterface *iface); G_DEFINE_TYPE_WITH_CODE (SignonIdentity, signon_identity, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (SIGNON_TYPE_PROXY, signon_identity_proxy_if_init)) enum { PROP_0, PROP_ID }; typedef enum { NOT_REGISTERED, PENDING_REGISTRATION, REGISTERED, } IdentityRegistrationState; typedef enum { DATA_UPDATED = 0, IDENTITY_REMOVED, IDENTITY_SIGNED_OUT } RemoteIdentityState; struct _SignonIdentityPrivate { SsoIdentity *proxy; SsoAuthService *auth_service_proxy; GCancellable *cancellable; SignonIdentityInfo *identity_info; GSList *sessions; IdentityRegistrationState registration_state; gboolean removed; gboolean signed_out; gboolean updated; gboolean first_registration; guint id; guint signal_info_updated; guint signal_unregistered; }; enum { SIGNEDOUT_SIGNAL, LAST_SIGNAL }; static guint signals[LAST_SIGNAL]; #define SIGNON_IDENTITY_PRIV(obj) (SIGNON_IDENTITY(obj)->priv) typedef struct _IdentityStoreCredentialsCbData { SignonIdentity *self; SignonIdentityStoreCredentialsCb cb; gpointer user_data; } IdentityStoreCredentialsCbData; typedef struct _IdentityStoreCredentialsData { GVariant *info_variant; gpointer cb_data; } IdentityStoreCredentialsData; typedef enum { SIGNON_VERIFY_USER, SIGNON_VERIFY_SECRET, SIGNON_INFO, SIGNON_REMOVE, SIGNON_SIGNOUT } IdentityOperation; typedef struct _IdentityVerifyCbData { SignonIdentity *self; SignonIdentityVerifyCb cb; gpointer user_data; } IdentityVerifyCbData; typedef struct _IdentityVerifyData { gchar *data_to_send; GHashTable *params; IdentityOperation operation; gpointer cb_data; } IdentityVerifyData; typedef struct _IdentityInfoCbData { SignonIdentity *self; SignonIdentityInfoCb cb; gpointer user_data; } IdentityInfoCbData; typedef struct _IdentityVoidCbData { SignonIdentity *self; SignonIdentityVoidCb cb; gpointer user_data; } IdentityVoidCbData; typedef struct _IdentityVoidData { IdentityOperation operation; gpointer cb_data; } IdentityVoidData; static void identity_check_remote_registration (SignonIdentity *self); static void identity_store_credentials_ready_cb (gpointer object, const GError *error, gpointer user_data); static void identity_store_credentials_reply (GObject *object, GAsyncResult *res, gpointer userdata); static void identity_session_object_destroyed_cb (gpointer data, GObject *where_the_session_was); static void identity_verify_data (SignonIdentity *self, const gchar *data_to_send, gint operation, SignonIdentityVerifyCb cb, gpointer user_data); static void identity_verify_ready_cb (gpointer object, const GError *error, gpointer user_data); static void identity_remove_ready_cb (gpointer object, const GError *error, gpointer user_data); static void identity_signout_ready_cb (gpointer object, const GError *error, gpointer user_data); static void identity_info_ready_cb (gpointer object, const GError *error, gpointer user_data); static void identity_process_signout (SignonIdentity *self); static void identity_process_updated (SignonIdentity *self); static void identity_process_removed (SignonIdentity *self); static GQuark identity_object_quark () { static GQuark quark = 0; if (!quark) quark = g_quark_from_static_string ("identity_object_quark"); return quark; } static void signon_identity_proxy_setup (SignonProxy *proxy) { identity_check_remote_registration (SIGNON_IDENTITY (proxy)); } static void signon_identity_proxy_if_init (SignonProxyInterface *iface) { iface->setup = signon_identity_proxy_setup; } static void signon_identity_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { SignonIdentity *self = SIGNON_IDENTITY (object); switch (property_id) { case PROP_ID: self->priv->id = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void signon_identity_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { SignonIdentity *self = SIGNON_IDENTITY (object); switch (property_id) { case PROP_ID: g_value_set_uint (value, self->priv->id); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void signon_identity_init (SignonIdentity *identity) { SignonIdentityPrivate *priv; identity->priv = G_TYPE_INSTANCE_GET_PRIVATE (identity, SIGNON_TYPE_IDENTITY, SignonIdentityPrivate); priv = identity->priv; priv->auth_service_proxy = sso_auth_service_get_instance(); priv->cancellable = g_cancellable_new (); priv->registration_state = NOT_REGISTERED; priv->removed = FALSE; priv->signed_out = FALSE; priv->updated = FALSE; priv->first_registration = TRUE; } static void signon_identity_dispose (GObject *object) { SignonIdentity *identity = SIGNON_IDENTITY (object); SignonIdentityPrivate *priv = identity->priv; if (priv->cancellable) { g_cancellable_cancel (priv->cancellable); g_object_unref (priv->cancellable); priv->cancellable = NULL; } if (priv->identity_info) { signon_identity_info_free (priv->identity_info); priv->identity_info = NULL; } g_clear_object (&priv->auth_service_proxy); if (priv->proxy) { g_signal_handler_disconnect (priv->proxy, priv->signal_info_updated); g_signal_handler_disconnect (priv->proxy, priv->signal_unregistered); g_object_unref (priv->proxy); priv->proxy = NULL; } if (priv->sessions) g_critical ("SignonIdentity: the list of AuthSessions MUST be empty"); G_OBJECT_CLASS (signon_identity_parent_class)->dispose (object); } static void signon_identity_finalize (GObject *object) { G_OBJECT_CLASS (signon_identity_parent_class)->finalize (object); } static void signon_identity_class_init (SignonIdentityClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GParamSpec *pspec; object_class->set_property = signon_identity_set_property; object_class->get_property = signon_identity_get_property; pspec = g_param_spec_uint ("id", "Identity ID", "Set/Get Identity ID", 0, G_MAXUINT, 0, G_PARAM_READWRITE); g_object_class_install_property (object_class, PROP_ID, pspec); g_type_class_add_private (object_class, sizeof (SignonIdentityPrivate)); /** * SignonIdentity::signout: * * Emitted when the identity was signed out. */ signals[SIGNEDOUT_SIGNAL] = g_signal_new("signout", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0 /* class closure */, NULL /* accumulator */, NULL /* accu_data */, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE /* return_type */, 0); object_class->dispose = signon_identity_dispose; object_class->finalize = signon_identity_finalize; } static void identity_state_changed_cb (GDBusProxy *proxy, gint state, gpointer user_data) { g_return_if_fail (SIGNON_IS_IDENTITY (user_data)); SignonIdentity *self = SIGNON_IDENTITY (user_data); switch (state) { case DATA_UPDATED: DEBUG ("State changed to DATA_UPDATED"); identity_process_updated (self); break; case IDENTITY_REMOVED: DEBUG ("State changed to IDENTITY_REMOVED"); identity_process_removed (self); break; case IDENTITY_SIGNED_OUT: DEBUG ("State changed to IDENTITY_SIGNED_OUT"); identity_process_signout (self); break; default: g_critical ("wrong state value obtained from signon daemon"); }; } static void identity_remote_object_destroyed_cb(GDBusProxy *proxy, gpointer user_data) { g_return_if_fail (SIGNON_IS_IDENTITY (user_data)); SignonIdentity *self = SIGNON_IDENTITY (user_data); SignonIdentityPrivate *priv = self->priv; g_return_if_fail (priv != NULL); if (priv->proxy) { g_object_unref (priv->proxy); priv->proxy = NULL; } DEBUG ("%s %d", G_STRFUNC, __LINE__); signon_proxy_set_not_ready (self); priv->registration_state = NOT_REGISTERED; signon_identity_info_free (priv->identity_info); priv->identity_info = NULL; priv->removed = FALSE; priv->signed_out = FALSE; priv->updated = FALSE; } static void identity_registered (SignonIdentity *identity, char *object_path, GVariant *identity_data, GError *error) { g_return_if_fail (SIGNON_IS_IDENTITY (identity)); SignonIdentityPrivate *priv; priv = identity->priv; g_return_if_fail (priv != NULL); if (!error) { GDBusConnection *connection; GDBusProxy *auth_service_proxy; const gchar *bus_name; GError *proxy_error = NULL; DEBUG("%s: %s", G_STRFUNC, object_path); /* * TODO: as Aurel will finalize the code polishing so we will * need to implement the refresh of the proxy to SignonIdentity * */ g_return_if_fail (priv->proxy == NULL); auth_service_proxy = (GDBusProxy *)priv->auth_service_proxy; connection = g_dbus_proxy_get_connection (auth_service_proxy); bus_name = g_dbus_proxy_get_name (auth_service_proxy); priv->proxy = sso_identity_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, bus_name, object_path, priv->cancellable, &proxy_error); if (G_UNLIKELY (proxy_error != NULL)) { g_warning ("Failed to initialize Identity proxy: %s", proxy_error->message); g_clear_error (&proxy_error); } priv->signal_info_updated = g_signal_connect (priv->proxy, "info-updated", G_CALLBACK (identity_state_changed_cb), identity); priv->signal_unregistered = g_signal_connect (priv->proxy, "unregistered", G_CALLBACK (identity_remote_object_destroyed_cb), identity); if (identity_data) { DEBUG("%s: ", G_STRFUNC); priv->identity_info = signon_identity_info_new_from_variant (identity_data); g_variant_unref (identity_data); } priv->updated = TRUE; } else if (error->domain == G_DBUS_ERROR && error->code == G_DBUS_ERROR_SERVICE_UNKNOWN) { /* This can happen if signond quits and the GDBusProxy is not notified * about it -- typically because the main loop was not being run. * We try the registration once more. */ if (priv->first_registration) { DEBUG ("Service unknown; retrying registration"); g_error_free (error); priv->first_registration = FALSE; priv->registration_state = NOT_REGISTERED; identity_check_remote_registration (identity); return; } else { g_warning ("%s, second failure: %s", G_STRFUNC, error->message); } } else g_warning ("%s: %s", G_STRFUNC, error->message); /* * execute queued operations or emit errors on each of them * */ priv->registration_state = REGISTERED; /* * TODO: if we will add a new state for identity: "INVALID" * consider emission of another error, like "invalid" * */ signon_proxy_set_ready (identity, identity_object_quark (), error); /* * as the registration failed we do not * request for new registration, but emit * same error again and again * */ } /** * signon_identity_get_last_error: * @identity: the #SignonIdentity. * * Get the most recent error that occurred on @identity. * * Returns: a #GError containing the most recent error, or %NULL on failure. */ const GError * signon_identity_get_last_error (SignonIdentity *identity) { g_return_val_if_fail (SIGNON_IS_IDENTITY (identity), NULL); return signon_proxy_get_last_error (identity); } static void identity_new_cb (GObject *object, GAsyncResult *res, gpointer userdata) { SignonIdentity *identity = (SignonIdentity*)userdata; SsoAuthService *proxy = SSO_AUTH_SERVICE (object); gchar *object_path = NULL; GError *error = NULL; g_return_if_fail (identity != NULL); DEBUG ("%s", G_STRFUNC); sso_auth_service_call_register_new_identity_finish (proxy, &object_path, res, &error); SIGNON_RETURN_IF_CANCELLED (error); identity_registered (identity, object_path, NULL, error); g_free (object_path); } static void identity_new_from_db_cb (GObject *object, GAsyncResult *res, gpointer userdata) { SignonIdentity *identity = (SignonIdentity*)userdata; SsoAuthService *proxy = SSO_AUTH_SERVICE (object); gchar *object_path = NULL; GVariant *identity_data; GError *error = NULL; g_return_if_fail (identity != NULL); DEBUG ("%s", G_STRFUNC); sso_auth_service_call_get_identity_finish (proxy, &object_path, &identity_data, res, &error); SIGNON_RETURN_IF_CANCELLED (error); identity_registered (identity, object_path, identity_data, error); g_free (object_path); } static void identity_check_remote_registration (SignonIdentity *self) { g_return_if_fail (self != NULL); SignonIdentityPrivate *priv = self->priv; g_return_if_fail (priv != NULL); if (priv->registration_state != NOT_REGISTERED) return; if (priv->id != 0) sso_auth_service_call_get_identity (priv->auth_service_proxy, priv->id, priv->cancellable, identity_new_from_db_cb, self); else sso_auth_service_call_register_new_identity (priv->auth_service_proxy, priv->cancellable, identity_new_cb, self); priv->registration_state = PENDING_REGISTRATION; } /** * signon_identity_new_from_db: * @id: identity ID. * * Construct an identity object associated with an existing identity * record. * * Returns: an instance of a #SignonIdentity. */ SignonIdentity* signon_identity_new_from_db (guint32 id) { SignonIdentity *identity; DEBUG ("%s %d: %d\n", G_STRFUNC, __LINE__, id); if (id == 0) return NULL; identity = g_object_new (SIGNON_TYPE_IDENTITY, "id", id, NULL); g_return_val_if_fail (SIGNON_IS_IDENTITY (identity), NULL); g_return_val_if_fail (identity->priv != NULL, NULL); identity->priv->id = id; identity_check_remote_registration (identity); return identity; } /** * signon_identity_new: * * Construct new, empty, identity object. * * Returns: an instance of an #SignonIdentity. */ SignonIdentity* signon_identity_new () { DEBUG ("%s %d", G_STRFUNC, __LINE__); SignonIdentity *identity = g_object_new (SIGNON_TYPE_IDENTITY, NULL); g_return_val_if_fail (SIGNON_IS_IDENTITY (identity), NULL); g_return_val_if_fail (identity->priv != NULL, NULL); identity_check_remote_registration (identity); return identity; } static void identity_session_object_destroyed_cb(gpointer data, GObject *where_the_session_was) { g_return_if_fail (SIGNON_IS_IDENTITY (data)); DEBUG ("%s %d", G_STRFUNC, __LINE__); SignonIdentity *self = SIGNON_IDENTITY (data); SignonIdentityPrivate *priv = self->priv; g_return_if_fail (priv != NULL); priv->sessions = g_slist_remove(priv->sessions, (gpointer)where_the_session_was); g_object_unref (self); } /** * 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; } /** * signon_identity_store_credentials_with_info: * @self: the #SignonIdentity. * @info: the #SignonIdentityInfo data to store. * @cb: (scope async): callback. * @user_data: user_data. * * Stores the data from @info into the identity. */ void signon_identity_store_credentials_with_info(SignonIdentity *self, const SignonIdentityInfo *info, SignonIdentityStoreCredentialsCb cb, gpointer user_data) { IdentityStoreCredentialsCbData *cb_data; IdentityStoreCredentialsData *operation_data; DEBUG (); g_return_if_fail (SIGNON_IS_IDENTITY (self)); g_return_if_fail (info != NULL); cb_data = g_slice_new0 (IdentityStoreCredentialsCbData); cb_data->self = self; cb_data->cb = cb; cb_data->user_data = user_data; operation_data = g_slice_new0 (IdentityStoreCredentialsData); operation_data->info_variant = signon_identity_info_to_variant (info); operation_data->cb_data = cb_data; signon_proxy_call_when_ready (self, identity_object_quark(), identity_store_credentials_ready_cb, operation_data); } /** * signon_identity_store_credentials_with_args: * @self: the #SignonIdentity. * @username: username. * @secret: secret. * @store_secret: whether signond should store the password. * @methods: (transfer none) (element-type utf8 GStrv): methods. * @caption: caption. * @realms: (transfer none) (type GStrv): realms. * @access_control_list: (transfer none) (type GStrv): access control list. * @type: the type of the identity. * @cb: (scope async): callback. * @user_data: user_data. * * Stores the given data into the identity. */ void signon_identity_store_credentials_with_args(SignonIdentity *self, const gchar *username, const gchar *secret, const gboolean store_secret, const GHashTable *methods, const gchar *caption, const gchar* const *realms, const gchar* const *access_control_list, SignonIdentityType type, SignonIdentityStoreCredentialsCb cb, gpointer user_data) { SignonIdentityInfo *info; g_return_if_fail (SIGNON_IS_IDENTITY (self)); info = signon_identity_info_new (); signon_identity_info_set_username (info, username); signon_identity_info_set_secret (info, secret, store_secret); signon_identity_info_set_methods (info, methods); signon_identity_info_set_caption (info, caption); signon_identity_info_set_realms (info, realms); signon_identity_info_set_access_control_list (info, access_control_list); signon_identity_info_set_identity_type (info, type); signon_identity_store_credentials_with_info (self, info, cb, user_data); signon_identity_info_free (info); } static void identity_store_credentials_ready_cb (gpointer object, const GError *error, gpointer user_data) { g_return_if_fail (SIGNON_IS_IDENTITY (object)); SignonIdentity *self = SIGNON_IDENTITY (object); SignonIdentityPrivate *priv = self->priv; g_return_if_fail (priv != NULL); DEBUG ("%s %d", G_STRFUNC, __LINE__); IdentityStoreCredentialsData *operation_data = (IdentityStoreCredentialsData *)user_data; g_return_if_fail (operation_data != NULL); IdentityStoreCredentialsCbData *cb_data = operation_data->cb_data; g_return_if_fail (cb_data != NULL); if (error) { DEBUG ("IdentityError: %s", error->message); if (cb_data->cb) { (cb_data->cb) (self, 0, error, cb_data->user_data); } g_slice_free (IdentityStoreCredentialsCbData, cb_data); } else { g_return_if_fail (priv->proxy != NULL); sso_identity_call_store (priv->proxy, operation_data->info_variant, priv->cancellable, identity_store_credentials_reply, cb_data); } g_slice_free (IdentityStoreCredentialsData, operation_data); } static void identity_store_credentials_reply (GObject *object, GAsyncResult *res, gpointer userdata) { IdentityStoreCredentialsCbData *cb_data = (IdentityStoreCredentialsCbData *)userdata; SsoIdentity *proxy = SSO_IDENTITY (object); guint id; GError *error = NULL; g_return_if_fail (cb_data != NULL); g_return_if_fail (cb_data->self != NULL); g_return_if_fail (cb_data->self->priv != NULL); SignonIdentityPrivate *priv = cb_data->self->priv; sso_identity_call_store_finish (proxy, &id, res, &error); SIGNON_RETURN_IF_CANCELLED (error); if (error == NULL) { g_return_if_fail (priv->identity_info == NULL); GSList *slist = priv->sessions; while (slist) { SignonAuthSession *session = SIGNON_AUTH_SESSION (priv->sessions->data); signon_auth_session_set_id (session, id); slist = g_slist_next (slist); } g_object_set (cb_data->self, "id", id, NULL); cb_data->self->priv->id = id; /* * if the previous state was REMOVED * then we need to reset it * */ priv->removed = FALSE; } if (cb_data->cb) { (cb_data->cb) (cb_data->self, id, error, cb_data->user_data); } g_clear_error(&error); g_slice_free (IdentityStoreCredentialsCbData, cb_data); } static void identity_verify_reply (GObject *object, GAsyncResult *res, gpointer userdata) { SsoIdentity *proxy = SSO_IDENTITY (object); gboolean valid; GError *error = NULL; IdentityVerifyCbData *cb_data = (IdentityVerifyCbData *)userdata; g_return_if_fail (cb_data != NULL); g_return_if_fail (cb_data->self != NULL); sso_identity_call_verify_secret_finish (proxy, &valid, res, &error); SIGNON_RETURN_IF_CANCELLED (error); if (cb_data->cb) { (cb_data->cb) (cb_data->self, valid, error, cb_data->user_data); } g_clear_error(&error); g_slice_free (IdentityVerifyCbData, cb_data); } static void identity_verify_ready_cb (gpointer object, const GError *error, gpointer user_data) { g_return_if_fail (SIGNON_IS_IDENTITY (object)); SignonIdentity *self = SIGNON_IDENTITY (object); SignonIdentityPrivate *priv = self->priv; g_return_if_fail (priv != NULL); DEBUG ("%s %d", G_STRFUNC, __LINE__); IdentityVerifyData *operation_data = (IdentityVerifyData *)user_data; g_return_if_fail (operation_data != NULL); IdentityVerifyCbData *cb_data = operation_data->cb_data; g_return_if_fail (cb_data != NULL); if (priv->removed == TRUE) { GError *new_error = g_error_new (signon_error_quark(), SIGNON_ERROR_IDENTITY_NOT_FOUND, "Already removed from database."); if (cb_data->cb) { (cb_data->cb) (self, FALSE, new_error, cb_data->user_data); } g_error_free (new_error); g_slice_free (IdentityVerifyCbData, cb_data); } else if (error) { DEBUG ("IdentityError: %s", error->message); if (cb_data->cb) { (cb_data->cb) (self, FALSE, error, cb_data->user_data); } g_slice_free (IdentityVerifyCbData, cb_data); } else { DEBUG ("%s %d", G_STRFUNC, __LINE__); g_return_if_fail (priv->proxy != NULL); switch (operation_data->operation) { case SIGNON_VERIFY_SECRET: sso_identity_call_verify_secret (priv->proxy, operation_data->data_to_send, priv->cancellable, identity_verify_reply, cb_data); break; default: g_critical ("Wrong operation code"); }; } g_free (operation_data->params); g_free (operation_data->data_to_send); g_slice_free (IdentityVerifyData, operation_data); } static void identity_verify_data(SignonIdentity *self, const gchar *data_to_send, gint operation, SignonIdentityVerifyCb cb, gpointer user_data) { g_return_if_fail (SIGNON_IS_IDENTITY (self)); DEBUG ("%s %d", G_STRFUNC, __LINE__); IdentityVerifyCbData *cb_data = g_slice_new0 (IdentityVerifyCbData); cb_data->self = self; cb_data->cb = cb; cb_data->user_data = user_data; IdentityVerifyData *operation_data = g_slice_new0 (IdentityVerifyData); operation_data->params = NULL; operation_data->data_to_send = g_strdup (data_to_send); operation_data->operation = operation; operation_data->cb_data = cb_data; signon_proxy_call_when_ready (self, identity_object_quark(), identity_verify_ready_cb, operation_data); } /** * signon_identity_verify_secret: * @self: the #SignonIdentity. * @secret: the secret (password) to be verified. * @cb: (scope async): callback. * @user_data: user_data. * * Verifies the given secret. */ void signon_identity_verify_secret(SignonIdentity *self, const gchar *secret, SignonIdentityVerifyCb cb, gpointer user_data) { identity_verify_data (self, secret, SIGNON_VERIFY_SECRET, cb, user_data); } static void identity_process_updated (SignonIdentity *self) { DEBUG ("%d %s", __LINE__, __func__); g_return_if_fail (self != NULL); g_return_if_fail (self->priv != NULL); SignonIdentityPrivate *priv = self->priv; g_return_if_fail (priv->proxy != NULL); signon_identity_info_free (priv->identity_info); priv->identity_info = NULL; priv->updated = FALSE; } static void identity_process_removed (SignonIdentity *self) { g_return_if_fail (self != NULL); g_return_if_fail (self->priv != NULL); DEBUG ("%d %s", __LINE__, __func__); SignonIdentityPrivate *priv = self->priv; if (priv->removed == TRUE) return; priv->removed = TRUE; signon_identity_info_free (priv->identity_info); priv->identity_info = NULL; g_object_set (self, "id", 0, NULL); priv->id = 0; } static void identity_process_signout(SignonIdentity *self) { g_return_if_fail (self != NULL); g_return_if_fail (self->priv != NULL); DEBUG ("%d %s", __LINE__, __func__); SignonIdentityPrivate *priv = self->priv; if (priv->signed_out == TRUE) return; GSList *llink = priv->sessions; while (llink) { GSList *next = llink->next; g_object_unref (G_OBJECT(llink->data)); llink = next; } priv->signed_out = TRUE; g_signal_emit(G_OBJECT(self), signals[SIGNEDOUT_SIGNAL], 0); } /* * TODO: fix the implementation * of signond: it returns result = TRUE * in ANY CASE * */ static void identity_signout_reply (GObject *object, GAsyncResult *res, gpointer userdata) { SsoIdentity *proxy = SSO_IDENTITY (object); gboolean result; GError *error = NULL; IdentityVoidCbData *cb_data = (IdentityVoidCbData *)userdata; g_return_if_fail (cb_data != NULL); g_return_if_fail (cb_data->self != NULL); g_return_if_fail (cb_data->self->priv != NULL); sso_identity_call_sign_out_finish (proxy, &result, res, &error); SIGNON_RETURN_IF_CANCELLED (error); if (cb_data->cb) { (cb_data->cb) (cb_data->self, error, cb_data->user_data); } g_clear_error(&error); g_slice_free (IdentityVoidCbData, cb_data); } static void identity_removed_reply (GObject *object, GAsyncResult *res, gpointer userdata) { SsoIdentity *proxy = SSO_IDENTITY (object); GError *error = NULL; IdentityVoidCbData *cb_data = (IdentityVoidCbData *)userdata; g_return_if_fail (cb_data != NULL); g_return_if_fail (cb_data->self != NULL); g_return_if_fail (cb_data->self->priv != NULL); sso_identity_call_remove_finish (proxy, res, &error); SIGNON_RETURN_IF_CANCELLED (error); if (cb_data->cb) { (cb_data->cb) (cb_data->self, error, cb_data->user_data); } g_clear_error(&error); g_slice_free (IdentityVoidCbData, cb_data); } static void identity_info_reply(GObject *object, GAsyncResult *res, gpointer userdata) { SsoIdentity *proxy = SSO_IDENTITY (object); GVariant *identity_data = NULL; DEBUG ("%d %s", __LINE__, __func__); GError *error = NULL; IdentityInfoCbData *cb_data = (IdentityInfoCbData *)userdata; g_return_if_fail (cb_data != NULL); g_return_if_fail (cb_data->self != NULL); g_return_if_fail (cb_data->self->priv != NULL); SignonIdentityPrivate *priv = cb_data->self->priv; sso_identity_call_get_info_finish (proxy, &identity_data, res, &error); SIGNON_RETURN_IF_CANCELLED (error); priv->identity_info = signon_identity_info_new_from_variant (identity_data); if (identity_data != NULL) g_variant_unref (identity_data); if (cb_data->cb) { (cb_data->cb) (cb_data->self, priv->identity_info, error, cb_data->user_data); } g_clear_error(&error); g_slice_free (IdentityInfoCbData, cb_data); priv->updated = TRUE; } static void identity_info_ready_cb(gpointer object, const GError *error, gpointer user_data) { g_return_if_fail (SIGNON_IS_IDENTITY (object)); SignonIdentity *self = SIGNON_IDENTITY (object); SignonIdentityPrivate *priv = self->priv; g_return_if_fail (priv != NULL); DEBUG ("%s %d", G_STRFUNC, __LINE__); IdentityVoidData *operation_data = (IdentityVoidData *)user_data; g_return_if_fail (operation_data != NULL); IdentityInfoCbData *cb_data = operation_data->cb_data; g_return_if_fail (cb_data != NULL); if (priv->removed == TRUE) { GError *new_error = g_error_new (signon_error_quark(), SIGNON_ERROR_IDENTITY_NOT_FOUND, "Already removed from database."); if (cb_data->cb) { (cb_data->cb) (self, NULL, new_error, cb_data->user_data); } g_error_free (new_error); } else if (error || priv->id == 0) { if (error) DEBUG ("IdentityError: %s", error->message); else DEBUG ("Identity is not stored and has no info yet"); if (cb_data->cb) { (cb_data->cb) (self, NULL, error, cb_data->user_data); } } else if (priv->updated == FALSE) { g_return_if_fail (priv->proxy != NULL); sso_identity_call_get_info (priv->proxy, priv->cancellable, identity_info_reply, cb_data); } else { if (cb_data->cb) { (cb_data->cb) (self, priv->identity_info, error, cb_data->user_data); } } if (priv->updated || priv->removed) g_slice_free (IdentityInfoCbData, cb_data); g_slice_free (IdentityVoidData, operation_data); } static void identity_signout_ready_cb(gpointer object, const GError *error, gpointer user_data) { g_return_if_fail (SIGNON_IS_IDENTITY (object)); SignonIdentity *self = SIGNON_IDENTITY (object); SignonIdentityPrivate *priv = self->priv; g_return_if_fail (priv != NULL); DEBUG ("%s %d", G_STRFUNC, __LINE__); IdentityVoidCbData *cb_data = (IdentityVoidCbData *)user_data; g_return_if_fail (cb_data != NULL); if (priv->removed == TRUE) { GError *new_error = g_error_new (signon_error_quark(), SIGNON_ERROR_IDENTITY_NOT_FOUND, "Already removed from database."); if (cb_data->cb) { (cb_data->cb) (self, new_error, cb_data->user_data); } g_error_free (new_error); g_slice_free (IdentityVoidCbData, cb_data); } else if (error) { DEBUG ("IdentityError: %s", error->message); if (cb_data->cb) { (cb_data->cb) (self, error, cb_data->user_data); } g_slice_free (IdentityVoidCbData, cb_data); } else { g_return_if_fail (priv->proxy != NULL); sso_identity_call_sign_out (priv->proxy, priv->cancellable, identity_signout_reply, cb_data); } } static void identity_remove_ready_cb(gpointer object, const GError *error, gpointer user_data) { g_return_if_fail (SIGNON_IS_IDENTITY (object)); SignonIdentity *self = SIGNON_IDENTITY (object); SignonIdentityPrivate *priv = self->priv; g_return_if_fail (priv != NULL); DEBUG ("%s %d", G_STRFUNC, __LINE__); IdentityVoidCbData *cb_data = (IdentityVoidCbData *)user_data; g_return_if_fail (cb_data != NULL); if (priv->removed == TRUE) { GError *new_error = g_error_new (signon_error_quark(), SIGNON_ERROR_IDENTITY_NOT_FOUND, "Already removed from database."); if (cb_data->cb) { (cb_data->cb) (self, new_error, cb_data->user_data); } g_error_free (new_error); g_slice_free (IdentityVoidCbData, cb_data); } else if (error) { DEBUG ("IdentityError: %s", error->message); if (cb_data->cb) { (cb_data->cb) (self, error, cb_data->user_data); } g_slice_free (IdentityVoidCbData, cb_data); } else { g_return_if_fail (priv->proxy != NULL); sso_identity_call_remove (priv->proxy, priv->cancellable, identity_removed_reply, cb_data); } } void static identity_void_operation(SignonIdentity *self, gint operation, gpointer cb_data) { g_return_if_fail (SIGNON_IS_IDENTITY (self)); DEBUG ("%s %d", G_STRFUNC, __LINE__); IdentityVoidData *operation_data = g_slice_new0 (IdentityVoidData); operation_data->cb_data = cb_data; signon_proxy_call_when_ready (self, identity_object_quark(), identity_info_ready_cb, operation_data); } /** * signon_identity_remove: * @self: the #SignonIdentity. * @cb: (scope async): callback to be called when the operation has completed. * @user_data: user_data to pass to the callback. * * Removes the corresponding credentials record from the database. */ void signon_identity_remove(SignonIdentity *self, SignonIdentityRemovedCb cb, gpointer user_data) { g_return_if_fail (SIGNON_IS_IDENTITY (self)); IdentityVoidCbData *cb_data = g_slice_new0 (IdentityVoidCbData); cb_data->self = self; cb_data->cb = (SignonIdentityVoidCb)cb; cb_data->user_data = user_data; DEBUG ("%s %d", G_STRFUNC, __LINE__); signon_proxy_call_when_ready (self, identity_object_quark(), identity_remove_ready_cb, cb_data); } /** * signon_identity_signout: * @self: the #SignonIdentity. * @cb: (scope async): callback. * @user_data: user_data. * * Asks signond to close all authentication sessions for this * identity, and to remove any stored secrets associated with it (password and * authentication tokens). */ void signon_identity_signout(SignonIdentity *self, SignonIdentitySignedOutCb cb, gpointer user_data) { g_return_if_fail (SIGNON_IS_IDENTITY (self)); IdentityVoidCbData *cb_data = g_slice_new0 (IdentityVoidCbData); cb_data->self = self; cb_data->cb = (SignonIdentityVoidCb)cb; cb_data->user_data = user_data; signon_proxy_call_when_ready (self, identity_object_quark(), identity_signout_ready_cb, cb_data); } /** * signon_identity_add_reference: * @self: the #SignonIdentity. * @reference: reference to be added * @cb: callback * @user_data: user_data. * * Adds named reference to identity */ void signon_identity_add_reference(SignonIdentity *self, const gchar *reference, SignonIdentityReferenceAddedCb cb, gpointer user_data) { g_return_if_fail (SIGNON_IS_IDENTITY (self)); //TODO implement if (cb) (cb) (self, NULL, user_data); } /** * signon_identity_remove_reference: * @self: the #SignonIdentity. * @reference: reference to be removed * @cb: callback * @user_data: user_data. * * Removes named reference from identity */ void signon_identity_remove_reference(SignonIdentity *self, const gchar *reference, SignonIdentityReferenceRemovedCb cb, gpointer user_data) { g_return_if_fail (SIGNON_IS_IDENTITY (self)); //TODO implement if (cb) (cb) (self, NULL, user_data); } /** * signon_identity_query_info: * @self: the #SignonIdentity. * @cb: (scope async): callback. * @user_data: user_data. * * Fetches the #SignonIdentityInfo data associated with this * identity. */ void signon_identity_query_info(SignonIdentity *self, SignonIdentityInfoCb cb, gpointer user_data) { g_return_if_fail (SIGNON_IS_IDENTITY (self)); IdentityInfoCbData *cb_data = g_slice_new0 (IdentityInfoCbData); cb_data->self = self; cb_data->cb = cb; cb_data->user_data = user_data; identity_void_operation(self, SIGNON_INFO, cb_data); } ./libsignon-glib/Makefile.am0000644000004100000410000001670213013271000016167 0ustar www-datawww-datalib_LTLIBRARIES = \ libsignon-glib.la libsignon_glib_la_CPPFLAGS = \ -I$(top_srcdir) \ -I$(srcdir) \ -I$(top_builddir) \ -I$(builddir) libsignon_glib_la_CFLAGS = \ $(DEPS_CFLAGS) \ $(COVERAGE_CFLAGS) \ -Wall -Werror -Wno-error=deprecated-declarations libsignon_glib_la_LIBADD = $(DEPS_LIBS) libsignon_glib_la_LDFLAGS = \ $(COVERAGE_LDFLAGS) \ -version-info 1:0:0 \ -export-symbols-regex '^signon_' nodist_libsignon_glib_la_SOURCES = \ signon-marshal.c \ signon-marshal.h \ signon-enum-types.h \ signon-enum-types.c \ signon-errors-enum.c \ sso-auth-service-gen.c \ sso-auth-service-gen.h \ sso-auth-session-gen.c \ sso-auth-session-gen.h \ sso-identity-gen.c \ sso-identity-gen.h \ stamp-signon-enum-types.h BUILT_SOURCES = \ $(nodist_libsignon_glib_la_SOURCES) \ signon-errors-map.c CLEANFILES = \ $(BUILT_SOURCES) \ sso-auth-service-gen-doc-com.google.code.AccountsSSO.SingleSignOn.AuthService.xml \ sso-auth-session-gen-doc-com.google.code.AccountsSSO.SingleSignOn.AuthSession.xml \ sso-identity-gen-doc-com.google.code.AccountsSSO.SingleSignOn.Identity.xml libsignon_glib_la_SOURCES = \ signon-auth-service.h \ signon-identity-info.h \ signon-identity.h \ signon-auth-session.h \ signon-internals.h \ signon-auth-service.c \ signon-identity-info.c \ signon-identity.c \ signon-auth-session.c \ signon-errors.h \ signon-errors.c \ signon-proxy.c \ signon-proxy.h \ signon-utils.h \ signon-utils.c \ signon-types.h \ sso-auth-service.c \ sso-auth-service.h libsignon_glib_includedir = $(includedir)/libsignon-glib libsignon_glib_include_HEADERS = \ signon-auth-service.h \ signon-auth-session.h \ signon-identity-info.h \ signon-identity.h \ signon-errors.h \ signon-enum-types.h \ signon-glib.h \ signon-types.h \ $(signon_headers) # Headers with enums to be parsed with glib-mkenums; # signon-errors.h is handled separately libsignon_glib_headers_with_enums = \ signon-auth-session.h \ signon-identity-info.h DBUS_INTERFACES_DIR = $(datadir)/dbus-1/interfaces sso-auth-service-gen.h sso-auth-service-gen.c: $(DBUS_INTERFACES_DIR)/com.google.code.AccountsSSO.SingleSignOn.AuthService.xml $(AM_V_GEN)gdbus-codegen \ --generate-c-code sso-auth-service-gen \ --generate-docbook sso-auth-service-gen-doc \ --annotate "com.google.code.AccountsSSO.SingleSignOn.AuthService" org.gtk.GDBus.C.Name SsoAuthService \ $< sso-auth-session-gen.h sso-auth-session-gen.c: $(DBUS_INTERFACES_DIR)/com.google.code.AccountsSSO.SingleSignOn.AuthSession.xml $(AM_V_GEN)gdbus-codegen \ --generate-c-code sso-auth-session-gen \ --generate-docbook sso-auth-session-gen-doc \ --annotate "com.google.code.AccountsSSO.SingleSignOn.AuthSession" org.gtk.GDBus.C.Name SsoAuthSession \ $< sso-identity-gen.h sso-identity-gen.c: $(DBUS_INTERFACES_DIR)/com.google.code.AccountsSSO.SingleSignOn.Identity.xml $(AM_V_GEN)gdbus-codegen \ --generate-c-code sso-identity-gen \ --generate-docbook sso-identity-gen-doc \ --annotate "com.google.code.AccountsSSO.SingleSignOn.Identity" org.gtk.GDBus.C.Name SsoIdentity \ $< signon-marshal.h: signon-marshal.list Makefile $(AM_V_GEN)glib-genmarshal --header --prefix=_signon_marshal $< > $@ signon-marshal.c: signon-marshal.list Makefile $(AM_V_GEN)glib-genmarshal --body --prefix=_signon_marshal $< > $@ signon-enum-types.h: stamp-signon-enum-types.h $(AM_V_at)true stamp-signon-enum-types.h: Makefile \ $(libsignon_glib_headers_with_enums) signon-errors.h $(AM_V_GEN)( cd $(srcdir) && glib-mkenums \ --fhead "#ifndef __SIGNON_ENUM_TYPES_H__\n#define __SIGNON_ENUM_TYPES_H__\n#include \n\nG_BEGIN_DECLS\n" \ --fprod "/* enumerations from \"@filename@\" */\n" \ --vhead "GType @enum_name@_get_type (void) G_GNUC_CONST;\n#define SIGNON_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \ --ftail "G_END_DECLS\n\n#endif /* __SIGNON_ENUM_TYPES_H__ */" \ $(libsignon_glib_headers_with_enums) signon-errors.h ) >> xgen-geth \ && (cmp -s xgen-geth signon-enum-types.h || cp xgen-geth signon-enum-types.h ) \ && rm -f xgen-geth \ && echo timestamp > $(@F) signon-enum-types.c: Makefile $(libsignon_glib_headers_with_enums) $(AM_V_GEN)( cd $(srcdir) && glib-mkenums \ --fhead "#include \"signon-enum-types.h\"\n" \ --fhead "#include \"signon-identity-info.h\"\n" \ --fhead "#include \"signon-auth-session.h\"\n" \ --fhead "#define g_intern_static_string(s) (s)\n" \ --fprod "\n/* enumerations from \"@filename@\" */" \ --ftail "\n#define __SIGNON_ENUM_TYPES_C__\n" \ --vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \ --vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (g_intern_static_string (\"@EnumName@\"), values);\n }\n return etype;\n}\n" \ $(libsignon_glib_headers_with_enums) ) > xgen-getc \ && cp xgen-getc signon-enum-types.c \ && rm -f xgen-getc signon-errors-enum.c: Makefile signon-errors.h $(AM_V_GEN)( cd $(srcdir) && glib-mkenums \ --fhead "#include \"signon-enum-types.h\"\n#include \"signon-errors.h\"\n#include \"signoncommon.h\"\n#define g_intern_static_string(s) (s)\n" \ --fprod "\n/* enumerations from \"@filename@\" */" \ --ftail "\n#define __SIGNON_ENUM_TYPES_C__\n" \ --vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \ --vprod " { @VALUENAME@, SED@VALUENAME@, \"@valuenick@\" }," \ --vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (g_intern_static_string (\"@EnumName@\"), values);\n }\n return etype;\n}\n" \ signon-errors.h ) | \ $(SED) -e 's/SEDSIGNON_ERROR_\([^,]*\)/SIGNOND_\1_ERR_NAME/' \ > xgen-getc-enum \ && cp xgen-getc-enum signon-errors-enum.c \ && rm -f xgen-getc-enum signon-errors-map.c: Makefile signon-errors.h $(AM_V_GEN)( cd $(srcdir) && \ echo "static const GDBusErrorEntry signon_error_entries[] = {" && \ grep "^ *SIGNON_ERROR_" signon-errors.h | \ $(SED) -e 's/SIGNON_ERROR_\([A-Z_0-9]*\).*/{ SIGNON_ERROR_\1, SIGNOND_\1_ERR_NAME },/' && \ echo -e "};\n" ) > signon-errors-map.c dist_noinst_DATA = \ signon-marshal.list \ stamp-signon-enum-types.h -include $(INTROSPECTION_MAKEFILE) INTROSPECTION_GIRS = INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) if HAVE_INTROSPECTION introspection_sources = \ signon-auth-service.c \ signon-auth-service.h \ signon-auth-session.c \ signon-auth-session.h \ signon-enum-types.h \ signon-enum-types.c \ signon-errors.c \ signon-errors.h \ signon-identity-info.c \ signon-identity-info.h \ signon-identity.c \ signon-identity.h Signon-1.0.gir: libsignon-glib.la Signon_1_0_gir_INCLUDES = GObject-2.0 Gio-2.0 Signon_1_0_gir_SCANNERFLAGS = \ --identifier-prefix=Signon \ --symbol-prefix=signon \ --c-include="libsignon-glib/signon-glib.h" \ --warn-all Signon_1_0_gir_CFLAGS = \ -I$(top_srcdir) \ -I$(top_builddir) \ $(DEPS_CFLAGS) Signon_1_0_gir_LIBS = libsignon-glib.la Signon_1_0_gir_FILES = $(introspection_sources) INTROSPECTION_GIRS += Signon-1.0.gir girdir = $(datadir)/gir-1.0 gir_DATA = $(INTROSPECTION_GIRS) typelibdir = $(libdir)/girepository-1.0 typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) CLEANFILES += $(gir_DATA) $(typelib_DATA) endif # Vala bindings vapidir = $(datadir)/vala/vapi dist_vapi_DATA = \ signon.vapi ./libsignon-glib/signon-marshal.list0000644000004100000410000000002113013271000017735 0ustar www-datawww-dataVOID:INT,STRING ./libsignon-glib.pc.in0000644000004100000410000000045213013271000015057 0ustar www-datawww-dataprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libsignon-glib Description: A low-level library for managing account credentials. Version: @VERSION@ Requires: signond glib-2.0 gobject-2.0 gio-unix-2.0 Libs: -L${libdir} -lsignon-glib Cflags: -I${includedir} ./Makefile.am0000644000004100000410000000165013013271000013264 0ustar www-datawww-dataACLOCAL_AMFLAGS = -I m4 DISTCHECK_CONFIGURE_FLAGS = \ --enable-gtk-doc \ --enable-introspection=yes SUBDIRS = libsignon-glib docs if ENABLE_PYTHON SUBDIRS += pygobject endif if ENABLE_TESTS SUBDIRS += tests endif include $(top_srcdir)/Makefile.am.coverage pkgconfigdir = $(libdir)/pkgconfig pkgconfig_in_files = libsignon-glib.pc.in pkgconfig_DATA = $(pkgconfig_in_files:.pc.in=.pc) dist_noinst_DATA = \ $(libsignondoc_DATA) \ m4/introspection.m4 dist-hook: git-changelog-hook git-changelog-hook: Makefile $(AM_V_at)if $(top_srcdir)/build-aux/missing --run git \ --git-dir=$(top_srcdir)/.git --work-tree=$(top_srcdir) log \ --no-merges --date=short --pretty='tformat:%cd %an <%ae>%n%n%s%n%n%b' | \ $(SED) -e '/[^ ]/,/^[ ]*$$/ !d' > .ChangeLog.tmp; \ then mv -f .ChangeLog.tmp "$(top_distdir)/ChangeLog"; \ else rm -f .ChangeLog.tmp; exit 1; fi DISTCLEANFILES = \ $(pkgconfig_DATA) .PHONY: git-changelog-hook ./m4/0000755000004100000410000000000013013271000011546 5ustar www-datawww-data./m4/gcov.m40000644000004100000410000000570713013271000012757 0ustar www-datawww-data# Copyright 2012-2016 Canonical Ltd. # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License version 3, as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranties of # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR # PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # Checks for existence of coverage tools: # * gcov # * lcov # * genhtml # * gcovr # # Sets ac_cv_check_gcov to yes if tooling is present # and reports the executables to the variables LCOV, GCOVR and GENHTML. AC_DEFUN([AC_TDD_GCOV], [ AC_ARG_ENABLE(gcov, AS_HELP_STRING([--enable-gcov], [enable coverage testing with gcov])) AM_CONDITIONAL(HAVE_GCOV, test "x$enable_gcov" = "xyes") if test "x$enable_gcov" = "xyes"; then # we need gcc: if test "$GCC" != "yes"; then AC_MSG_ERROR([GCC is required for --enable-gcov]) fi # Check if ccache is being used AC_CHECK_PROG(SHTOOL, shtool, shtool) if test "$SHTOOL"; then AS_CASE([`$SHTOOL path $CC`], [*ccache*], [gcc_ccache=yes], [gcc_ccache=no]) fi if test "$gcc_ccache" = "yes" && (test -z "$CCACHE_DISABLE" || test "$CCACHE_DISABLE" != "1"); then AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.]) fi lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11 1.12" AC_CHECK_PROG(LCOV, lcov, lcov) AC_CHECK_PROG(GENHTML, genhtml, genhtml) if test "$LCOV"; then AC_CACHE_CHECK([for lcov version], glib_cv_lcov_version, [ glib_cv_lcov_version=invalid lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'` for lcov_check_version in $lcov_version_list; do if test "$lcov_version" = "$lcov_check_version"; then glib_cv_lcov_version="$lcov_check_version (ok)" fi done ]) else lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list" AC_MSG_ERROR([$lcov_msg]) fi case $glib_cv_lcov_version in ""|invalid[)] lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)." AC_MSG_ERROR([$lcov_msg]) LCOV="exit 0;" ;; esac if test -z "$GENHTML"; then AC_MSG_ERROR([Could not find genhtml from the lcov package]) fi # Remove all optimization flags from CFLAGS changequote({,}) CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9]*//g'` changequote([,]) # Add the special gcc flags COVERAGE_CFLAGS="--coverage -DG_DISABLE_ASSERTS -DG_DISABLE_CHECKS" COVERAGE_CXXFLAGS="--coverage" COVERAGE_LDFLAGS="-lgcov" fi ]) # AC_TDD_GCOV ./m4/introspection.m40000644000004100000410000000661413013271000014717 0ustar www-datawww-datadnl -*- mode: autoconf -*- dnl Copyright 2009 Johan Dahlin dnl dnl This file is free software; the author(s) gives unlimited dnl permission to copy and/or distribute it, with or without dnl modifications, as long as this notice is preserved. dnl # serial 1 m4_define([_GOBJECT_INTROSPECTION_CHECK_INTERNAL], [ AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first AC_BEFORE([LT_INIT],[$0])dnl setup libtool first dnl enable/disable introspection m4_if([$2], [require], [dnl enable_introspection=yes ],[dnl AC_ARG_ENABLE(introspection, AS_HELP_STRING([--enable-introspection[=@<:@no/auto/yes@:>@]], [Enable introspection for this build]),, [enable_introspection=auto]) ])dnl AC_MSG_CHECKING([for gobject-introspection]) dnl presence/version checking AS_CASE([$enable_introspection], [no], [dnl found_introspection="no (disabled, use --enable-introspection to enable)" ],dnl [yes],[dnl PKG_CHECK_EXISTS([gobject-introspection-1.0],, AC_MSG_ERROR([gobject-introspection-1.0 is not installed])) PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], found_introspection=yes, AC_MSG_ERROR([You need to have gobject-introspection >= $1 installed to build AC_PACKAGE_NAME])) ],dnl [auto],[dnl PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], found_introspection=yes, found_introspection=no) ],dnl [dnl AC_MSG_ERROR([invalid argument passed to --enable-introspection, should be one of @<:@no/auto/yes@:>@]) ])dnl AC_MSG_RESULT([$found_introspection]) INTROSPECTION_SCANNER= INTROSPECTION_COMPILER= INTROSPECTION_GENERATE= INTROSPECTION_GIRDIR= INTROSPECTION_TYPELIBDIR= if test "x$found_introspection" = "xyes"; then INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0` INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0` INTROSPECTION_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0` INTROSPECTION_GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0` INTROSPECTION_TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)" INTROSPECTION_CFLAGS=`$PKG_CONFIG --cflags gobject-introspection-1.0` INTROSPECTION_LIBS=`$PKG_CONFIG --libs gobject-introspection-1.0` INTROSPECTION_MAKEFILE=`$PKG_CONFIG --variable=datadir gobject-introspection-1.0`/gobject-introspection-1.0/Makefile.introspection fi AC_SUBST(INTROSPECTION_SCANNER) AC_SUBST(INTROSPECTION_COMPILER) AC_SUBST(INTROSPECTION_GENERATE) AC_SUBST(INTROSPECTION_GIRDIR) AC_SUBST(INTROSPECTION_TYPELIBDIR) AC_SUBST(INTROSPECTION_CFLAGS) AC_SUBST(INTROSPECTION_LIBS) AC_SUBST(INTROSPECTION_MAKEFILE) AM_CONDITIONAL(HAVE_INTROSPECTION, test "x$found_introspection" = "xyes") ]) dnl Usage: dnl GOBJECT_INTROSPECTION_CHECK([minimum-g-i-version]) AC_DEFUN([GOBJECT_INTROSPECTION_CHECK], [ _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1]) ]) dnl Usage: dnl GOBJECT_INTROSPECTION_REQUIRE([minimum-g-i-version]) AC_DEFUN([GOBJECT_INTROSPECTION_REQUIRE], [ _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1], [require]) ]) ./AUTHORS0000644000004100000410000000003413013271000012273 0ustar www-datawww-dataalberto.mardegan@nokia.com