libmalcontent: Add a SessionLimits interface for time-limited sessions

This is another extension interface on accountsservice which stores
information about time and usage limits on the user session. Currently,
only a ‘daily schedule’ limit (or no limit) is supported, but additional
types and combinations of limits can be supported in future.

The daily schedule limit allows using the computer between a certain
start time and end time each day (the same each day). The user will be
kicked out of their session when the end time is reached, if they
haven’t already logged out.

This includes the getters for the new data, polkit rules for accessing
it, and some documentation. Changes to `malcontent-client` to support
session limits, setters, and unit tests will all follow.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
This commit is contained in:
Philip Withnall 2019-12-06 16:41:08 +00:00
parent 9dcaa10253
commit 5e49cb7831
11 changed files with 678 additions and 8 deletions

View file

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="com.endlessm.ParentalControls.SessionLimits">
<annotation name="org.freedesktop.Accounts.VendorExtension" value="true"/>
<annotation name="org.freedesktop.Accounts.Authentication.ChangeOwn"
value="com.endlessm.ParentalControls.SessionLimits.ChangeOwn"/>
<annotation name="org.freedesktop.Accounts.Authentication.ReadOwn"
value="com.endlessm.ParentalControls.SessionLimits.ReadOwn"/>
<annotation name="org.freedesktop.Accounts.Authentication.ChangeAny"
value="com.endlessm.ParentalControls.SessionLimits.ChangeAny"/>
<annotation name="org.freedesktop.Accounts.Authentication.ReadAny"
value="com.endlessm.ParentalControls.SessionLimits.ReadAny"/>
<!--
LimitType:
The type of session limit applied to the user, as an enumerated type.
Currently, the following values are supported, but more values may be
added in future.
- `0`: No filter enabled. The user is not limited in the times or
durations of their sessions.
- `1`: Daily schedule. The user is limited to using the computer between
a fixed start and end time each day, as set in the `DailySchedule`
property.
-->
<property name="LimitType" type="u" access="readwrite">
<annotation name="org.freedesktop.Accounts.DefaultValue" value="0"/>
</property>
<!--
DailySchedule:
A daily schedule to limit the users computer use. This is a two-tuple of
a start time and an end time, both given as the number of seconds since
midnight. The end time must be greater than the start time, and must be
≤ 86400 (the number of seconds in a day). There is no handling of leap
seconds.
This property will be used if `LimitType` is set to `1`, but it must be
set to a valid value regardless.
-->
<property name="DailySchedule" type="(uu)" access="readwrite">
<annotation name="org.freedesktop.Accounts.DefaultValue" value="(0, 86400)"/>
</property>
</interface>
</node>

View file

@ -39,4 +39,44 @@
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
</policyconfig>
<action id="com.endlessm.ParentalControls.SessionLimits.ChangeOwn">
<description>Change your own session limits</description>
<message>Authentication is required to change your session limits.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
<action id="com.endlessm.ParentalControls.SessionLimits.ReadOwn">
<description>Read your own session limits</description>
<message>Authentication is required to read your session limits.</message>
<defaults>
<allow_any>yes</allow_any>
<allow_inactive>yes</allow_inactive>
<allow_active>yes</allow_active>
</defaults>
</action>
<action id="com.endlessm.ParentalControls.SessionLimits.ChangeAny">
<description>Change another users session limits</description>
<message>Authentication is required to change another users session limits.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
<action id="com.endlessm.ParentalControls.SessionLimits.ReadAny">
<description>Read another users session limits</description>
<message>Authentication is required to read another users session limits.</message>
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
</policyconfig>

View file

@ -23,7 +23,9 @@ polkit.addRule(function(action, subject) {
/* Allow administrators to read parental controls (for any account) without
* needing an additional polkit authorisation dialogue. */
if ((action.id == "com.endlessm.ParentalControls.AppFilter.ReadOwn" ||
action.id == "com.endlessm.ParentalControls.AppFilter.ReadAny") &&
action.id == "com.endlessm.ParentalControls.AppFilter.ReadAny" ||
action.id == "com.endlessm.ParentalControls.SessionLimits.ReadOwn" ||
action.id == "com.endlessm.ParentalControls.SessionLimits.ReadAny") &&
subject.active && subject.local &&
subject.isInGroup("sudo")) {
return polkit.Result.YES;

View file

@ -6,11 +6,19 @@ i18n.merge_file('com.endlessm.ParentalControls.policy',
install_dir: polkitpolicydir,
)
install_data('com.endlessm.ParentalControls.AppFilter.xml',
install_dir: dbusinterfacesdir)
meson.add_install_script(meson_make_symlink,
join_paths(dbusinterfacesdir, 'com.endlessm.ParentalControls.AppFilter.xml'),
join_paths(accountsserviceinterfacesdir, 'com.endlessm.ParentalControls.AppFilter.xml'))
dbus_interfaces = [
'com.endlessm.ParentalControls.AppFilter',
'com.endlessm.ParentalControls.SessionLimits',
]
foreach dbus_interface: dbus_interfaces
filename = dbus_interface + '.xml'
install_data(filename,
install_dir: dbusinterfacesdir)
meson.add_install_script(meson_make_symlink,
join_paths(dbusinterfacesdir, filename),
join_paths(accountsserviceinterfacesdir, filename))
endforeach
install_data('com.endlessm.ParentalControls.rules',
install_dir: join_paths(get_option('datadir'), 'polkit-1', 'rules.d'))