Merge branch 'accounts-service-iface' into 'master'

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

See merge request pwithnall/malcontent!2
This commit is contained in:
Philip Withnall 2019-06-13 15:43:49 +00:00
commit 80288aa05a
6 changed files with 370 additions and 174 deletions

View File

@ -1,12 +1,11 @@
image: debian:unstable
image: fedora:30
before_script:
- apt update -qq
- apt install -y -qq build-essential meson pkg-config gtk-doc-tools
libxml2-utils gobject-introspection
libgirepository1.0-dev libglib2.0-dev
gettext libdbus-1-dev libpolkit-gobject-1-dev git
policykit-1 lcov
- dnf install -y meson pkgconf-pkg-config gtk-doc
libxml2-devel dbus-daemon
glib2-devel dbus-devel gobject-introspection-devel
gettext-devel polkit-devel polkit-gnome git
lcov
- export LANG=C.UTF-8
stages:
@ -17,7 +16,7 @@ cache:
paths:
- _ccache/
debian-unstable:
fedora:
stage: build
except:
- tags
@ -25,7 +24,9 @@ debian-unstable:
- git submodule update --init
- meson --buildtype debug --werror -Db_coverage=true -Ddocumentation=true _build .
- meson test -C _build
- ninja -C _build coverage
# FIXME: lcov doesn't support gcc9 yet:
# https://github.com/linux-test-project/lcov/issues/58
- ninja -C _build coverage || true
coverage: '/^\s+lines\.+:\s+([\d.]+\%)\s+/'
artifacts:
when: always

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. */
@ -47,27 +48,6 @@ assert_strv_equal (const gchar * const *strv_a,
g_assert_null (strv_b[i]);
}
/* FIXME: Use g_assert_cmpvariant() when
* https://gitlab.gnome.org/GNOME/glib/issues/1191 is fixed. */
#define assert_cmpvariant(v1, v2) \
G_STMT_START \
{ \
GVariant *__v1 = (v1), *__v2 = (v2); \
if (!g_variant_equal (__v1, __v2)) \
{ \
gchar *__s1, *__s2, *__msg; \
__s1 = g_variant_print (__v1, TRUE); \
__s2 = g_variant_print (__v2, TRUE); \
__msg = g_strdup_printf ("assertion failed (" #v1 " == " #v2 "): %s does not equal %s", __s1, __s2); \
g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, __msg); \
g_free (__s1); \
g_free (__s2); \
g_free (__msg); \
} \
} \
G_STMT_END
/* A placeholder smoketest which checks that the error quark works. */
static void
test_app_filter_error_quark (void)
@ -445,13 +425,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);
@ -1092,7 +1072,7 @@ set_app_filter_server_cb (GtDBusQueue *queue,
else
{
expected_property_value = g_variant_new_parsed (set_app_filter_data_get_expected_property_value (data, property_name));
assert_cmpvariant (property_value, expected_property_value);
g_assert_cmpvariant (property_value, expected_property_value);
g_dbus_method_invocation_return_value (property_invocation, NULL);
}

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,7 +1,7 @@
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('glib-2.0', version: '>= 2.60.0'),
dependency('gobject-2.0', version: '>= 2.44'),
libmalcontent_dep,
libglib_testing_dep,
@ -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>