tests: Use gdbus-codegen to drop hand-coded interface definitions

Bump our GLib dependency to 2.60 so we can use `gdbus-codegen
--interface-info-{body,header}` to generate interface definitions
dynamically rather than hand-coding them.

We actually need to depend on 2.60.1 so we get
https://gitlab.gnome.org/GNOME/glib/merge_requests/721.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
This commit is contained in:
Philip Withnall 2019-03-13 13:17:43 +00:00
parent a95ae0c182
commit d9acee829a
5 changed files with 358 additions and 142 deletions

View File

@ -1,138 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright © 2018 Endless Mobile, Inc.
*
* 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
*
* Authors:
* - Philip Withnall <withnall@endlessm.com>
*/
#pragma once
#include <gio/gio.h>
#include <glib.h>
#include <glib-object.h>
G_BEGIN_DECLS
/* Static definition of the AppFilter interface on org.freedesktop.Accounts.
* FIXME: Once we can depend on a new enough version of GLib, generate this
* from introspection XML using `gdbus-codegen --interface-info-{header,body}`. */
static const GDBusPropertyInfo app_filter_property_app_filter =
{
.ref_count = -1, /* static */
.name = (gchar *) "AppFilter",
.signature = (gchar *) "(bas)",
.flags = G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE,
.annotations = NULL,
};
static const GDBusPropertyInfo app_filter_property_oars_filter =
{
.ref_count = -1, /* static */
.name = (gchar *) "OarsFilter",
.signature = (gchar *) "(sa{ss})",
.flags = G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE,
.annotations = NULL,
};
static const GDBusPropertyInfo app_filter_property_allow_user_installation =
{
.ref_count = -1, /* static */
.name = (gchar *) "AllowUserInstallation",
.signature = (gchar *) "b",
.flags = G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE,
.annotations = NULL,
};
static const GDBusPropertyInfo app_filter_property_allow_system_installation =
{
.ref_count = -1, /* static */
.name = (gchar *) "AllowSystemInstallation",
.signature = (gchar *) "b",
.flags = G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE,
.annotations = NULL,
};
static const GDBusPropertyInfo *app_filter_properties[] =
{
(GDBusPropertyInfo *) &app_filter_property_app_filter,
(GDBusPropertyInfo *) &app_filter_property_oars_filter,
(GDBusPropertyInfo *) &app_filter_property_allow_user_installation,
(GDBusPropertyInfo *) &app_filter_property_allow_system_installation,
NULL,
};
static const GDBusInterfaceInfo app_filter_interface_info =
{
.ref_count = -1, /* static */
.name = (gchar *) "com.endlessm.ParentalControls.AppFilter",
.methods = NULL,
.signals = NULL,
.properties = (GDBusPropertyInfo **) &app_filter_properties,
.annotations = NULL,
};
static const GDBusArgInfo accounts_method_find_user_by_id_arg_user_id =
{
.ref_count = -1, /* static */
.name = (gchar *) "UserId",
.signature = (gchar *) "x",
.annotations = NULL,
};
static const GDBusArgInfo accounts_method_find_user_by_id_arg_object_path =
{
.ref_count = -1, /* static */
.name = (gchar *) "ObjectPath",
.signature = (gchar *) "o",
.annotations = NULL,
};
static const GDBusArgInfo *accounts_method_find_user_by_id_in_args[] =
{
(GDBusArgInfo *) &accounts_method_find_user_by_id_arg_user_id,
NULL,
};
static const GDBusArgInfo *accounts_method_find_user_by_id_out_args[] =
{
(GDBusArgInfo *) &accounts_method_find_user_by_id_arg_object_path,
NULL,
};
static const GDBusMethodInfo accounts_method_find_user_by_id =
{
.ref_count = -1, /* static */
.name = (gchar *) "FindUserById",
.in_args = (GDBusArgInfo **) &accounts_method_find_user_by_id_in_args,
.out_args = (GDBusArgInfo **) &accounts_method_find_user_by_id_out_args,
.annotations = NULL,
};
static const GDBusMethodInfo *accounts_methods[] =
{
(GDBusMethodInfo *) &accounts_method_find_user_by_id,
NULL,
};
static const GDBusInterfaceInfo accounts_interface_info =
{
.ref_count = -1, /* static */
.name = (gchar *) "org.freedesktop.Accounts",
.methods = (GDBusMethodInfo **) &accounts_methods,
.signals = NULL,
.properties = NULL,
.annotations = NULL,
};
G_END_DECLS

View File

@ -31,6 +31,7 @@
#include <locale.h>
#include <string.h>
#include "accounts-service-iface.h"
#include "accounts-service-extension-iface.h"
/* Check two arrays contain exactly the same items in the same order. */
@ -445,13 +446,13 @@ bus_set_up (BusFixture *fixture,
object_path = g_strdup_printf ("/org/freedesktop/Accounts/User%u", fixture->valid_uid);
gt_dbus_queue_export_object (fixture->queue,
object_path,
(GDBusInterfaceInfo *) &app_filter_interface_info,
(GDBusInterfaceInfo *) &com_endlessm_parental_controls_app_filter_interface,
&local_error);
g_assert_no_error (local_error);
gt_dbus_queue_export_object (fixture->queue,
"/org/freedesktop/Accounts",
(GDBusInterfaceInfo *) &accounts_interface_info,
(GDBusInterfaceInfo *) &org_freedesktop_accounts_interface,
&local_error);
g_assert_no_error (local_error);

View File

@ -0,0 +1,51 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd" >
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
<interface name="com.endlessm.ParentalControls.AppFilter">
<property name="AppFilter" type="(bas)" access="readwrite">
<doc:doc>
<doc:description>
<doc:para>
List of applications to allow (boolean is True) or deny
(boolean is False) access to.
</doc:para>
</doc:description>
</doc:doc>
</property>
<property name="OarsFilter" type="(sa{ss})" access="readwrite">
<doc:doc>
<doc:description>
<doc:para>
Restriction levels for different OARS categories, preventing
installation of apps which exceed those levels. The first string is
the OARS version (for example, `oars-1.1`), followed by a dictionary
mapping OARS categories to values.
</doc:para>
</doc:description>
</doc:doc>
</property>
<property name="AllowUserInstallation" type="b" access="readwrite">
<doc:doc>
<doc:description>
<doc:para>
Whether to allow installation of apps to the user flatpak
repository.
</doc:para>
</doc:description>
</doc:doc>
</property>
<property name="AllowSystemInstallation" type="b" access="readwrite">
<doc:doc>
<doc:description>
<doc:para>
Whether to allow installation of apps to the system flatpak
repository.
</doc:para>
</doc:description>
</doc:doc>
</property>
</interface>
</node>

View File

@ -1,5 +1,5 @@
deps = [
dependency('gio-2.0', version: '>= 2.44'),
dependency('gio-2.0', version: '>= 2.60.1'),
dependency('gio-unix-2.0', version: '>= 2.44'),
dependency('glib-2.0', version: '>= 2.54.2'),
dependency('gobject-2.0', version: '>= 2.44'),
@ -12,8 +12,53 @@ envs = test_env + [
'G_TEST_BUILDDIR=' + meson.current_build_dir(),
]
gdbus_codegen = find_program('gdbus-codegen')
accounts_service_iface_h = custom_target(
'accounts-service-iface.h',
input: ['org.freedesktop.Accounts.xml'],
output: ['accounts-service-iface.h'],
command: [gdbus_codegen,
'--interface-info-header',
'--output', '@OUTPUT@',
'@INPUT@'],
)
accounts_service_iface_c = custom_target(
'accounts-service-iface.c',
input: ['org.freedesktop.Accounts.xml'],
output: ['accounts-service-iface.c'],
command: [gdbus_codegen,
'--interface-info-body',
'--output', '@OUTPUT@',
'@INPUT@'],
)
accounts_service_extension_iface_h = custom_target(
'accounts-service-extension-iface.h',
input: ['com.endlessm.ParentalControls.AppFilter.xml'],
output: ['accounts-service-extension-iface.h'],
command: [gdbus_codegen,
'--interface-info-header',
'--output', '@OUTPUT@',
'@INPUT@'],
)
accounts_service_extension_iface_c = custom_target(
'accounts-service-extension-iface.c',
input: ['com.endlessm.ParentalControls.AppFilter.xml'],
output: ['accounts-service-extension-iface.c'],
command: [gdbus_codegen,
'--interface-info-body',
'--output', '@OUTPUT@',
'@INPUT@'],
)
test_programs = [
['app-filter', ['accounts-service-iface.h'], deps],
['app-filter', [
accounts_service_iface_h,
accounts_service_iface_c,
accounts_service_extension_iface_h,
accounts_service_extension_iface_c,
], deps],
]
installed_tests_metadir = join_paths(datadir, 'installed-tests',

View File

@ -0,0 +1,257 @@
<!DOCTYPE node PUBLIC
"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd" >
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
<interface name="org.freedesktop.Accounts">
<!-- ************************************************************ -->
<method name="ListCachedUsers">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="users" direction="out" type="ao">
<doc:doc><doc:summary>Object paths of cached users</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Lists users which have logged into the system locally before.
This is not meant to return an exhaustive list of all users.
It is possible for <doc:ref type="method" to="Accounts.FindUserByName">FindUserByName()</doc:ref>
to return a user that's not on the list.
</doc:para>
</doc:description>
</doc:doc>
</method>
<method name="FindUserById">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="id" direction="in" type="x">
<doc:doc><doc:summary>The uid to look up</doc:summary></doc:doc>
</arg>
<arg name="user" direction="out" type="o">
<doc:doc><doc:summary>Object path of user</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Finds a user by uid.
</doc:para>
</doc:description>
<doc:errors>
<doc:error name="org.freedesktop.Accounts.Error.Failed">if no user with the given uid exists</doc:error>
</doc:errors>
</doc:doc>
</method>
<method name="FindUserByName">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="name" direction="in" type="s">
<doc:doc><doc:summary>The username to look up</doc:summary></doc:doc>
</arg>
<arg name="user" direction="out" type="o">
<doc:doc><doc:summary>Object path of user</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Finds a user by its username.
</doc:para>
</doc:description>
<doc:errors>
<doc:error name="org.freedesktop.Accounts.Error.Failed">if no user with the given username exists</doc:error>
</doc:errors>
</doc:doc>
</method>
<method name="CreateUser">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="name" direction="in" type="s">
<doc:doc><doc:summary>The username for the new user</doc:summary></doc:doc>
</arg>
<arg name="fullname" direction="in" type="s">
<doc:doc><doc:summary>The real name for the new user</doc:summary></doc:doc>
</arg>
<arg name="user" direction="out" type="o">
<doc:doc><doc:summary>Object path of the new user</doc:summary></doc:doc>
</arg>
<arg name="accountType" direction="in" type="i">
<doc:doc>
<doc:summary>The account type, encoded as an integer</doc:summary>
</doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Creates a new user account.
</doc:para>
<doc:para>
The accountType argument can take the following values:
</doc:para>
<doc:list>
<doc:item>
<doc:term>0</doc:term>
<doc:definition>Standard user</doc:definition>
</doc:item>
<doc:item>
<doc:term>1</doc:term>
<doc:definition>Administrator</doc:definition>
</doc:item>
</doc:list>
</doc:description>
<doc:permission>
The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization.
</doc:permission>
<doc:errors>
<doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
<doc:error name="org.freedesktop.Accounts.Error.Failed">if the operation failed</doc:error>
</doc:errors>
</doc:doc>
</method>
<method name="CacheUser">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="name" direction="in" type="s">
<doc:doc><doc:summary>The username for the user</doc:summary></doc:doc>
</arg>
<arg name="user" direction="out" type="o">
<doc:doc><doc:summary>Object path of user</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Caches a user account, so that it shows up in ListCachedUsers() output.
The user name may be a remote user, but the system must be able to lookup
the user name and resolve the user information.
</doc:para>
</doc:description>
<doc:permission>
The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization.
</doc:permission>
<doc:errors>
<doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
<doc:error name="org.freedesktop.Accounts.Error.UserDoesNotExist">if the user name cannot be resolved</doc:error>
</doc:errors>
</doc:doc>
</method>
<method name="UncacheUser">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="name" direction="in" type="s">
<doc:doc><doc:summary>The username for the user</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Releases all metadata about a user account, including icon, language and session. If the user account is
from a remote server and the user has never logged in before, then that account will no longer show up
in ListCachedUsers() output.
</doc:para>
</doc:description>
<doc:permission>
The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization.
</doc:permission>
<doc:errors>
<doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
<doc:error name="org.freedesktop.Accounts.Error.UserDoesNotExist">if the user name cannot be resolved</doc:error>
</doc:errors>
</doc:doc>
</method>
<method name="DeleteUser">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="id" direction="in" type="x">
<doc:doc><doc:summary>The uid to delete</doc:summary></doc:doc>
</arg>
<arg name="removeFiles" direction="in" type="b">
<doc:doc><doc:summary>Whether to remove the users files</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Deletes a user account.
</doc:para>
</doc:description>
<doc:permission>
The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization.
</doc:permission>
<doc:errors>
<doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
<doc:error name="org.freedesktop.Accounts.Error.Failed">if the operation failed</doc:error>
</doc:errors>
</doc:doc>
</method>
<signal name="UserAdded">
<arg name="user" type="o">
<doc:doc><doc:summary>Object path of the user that was added.</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Emitted when a user is added.
</doc:para>
</doc:description>
</doc:doc>
</signal>
<signal name="UserDeleted">
<arg name="user" type="o">
<doc:doc><doc:summary>Object path of the user that was deleted.</doc:summary></doc:doc>
</arg>
<doc:doc>
<doc:description>
<doc:para>
Emitted when a user is deleted.
</doc:para>
</doc:description>
</doc:doc>
</signal>
<property name="DaemonVersion" type="s" access="read">
<doc:doc>
<doc:description>
<doc:para>
The version of the running daemon.
</doc:para>
</doc:description>
</doc:doc>
</property>
<property name="HasNoUsers" type="b" access="read">
<doc:doc>
<doc:description>
<doc:para>
Whether or not the system has no users
</doc:para>
</doc:description>
</doc:doc>
</property>
<property name="HasMultipleUsers" type="b" access="read">
<doc:doc>
<doc:description>
<doc:para>
Whether or not the system has multiple users
</doc:para>
</doc:description>
</doc:doc>
</property>
<property name="AutomaticLoginUsers" type="ao" access="read">
<doc:doc>
<doc:description>
<doc:para>
Users to automatically log in as
</doc:para>
</doc:description>
</doc:doc>
</property>
</interface>
</node>