From bf5c35a6ffec43378f7a7483642e866b5efbcfdb Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Thu, 27 Sep 2018 23:31:07 +0200 Subject: [PATCH 3/4] 0011-add-background-file-support.patch --- data/org.freedesktop.Accounts.User.xml | 45 ++++++++++++ src/libaccountsservice/act-user.c | 67 ++++++++++++++++++ src/user.c | 98 ++++++++++++++++++++++++++ 3 files changed, 210 insertions(+) diff --git a/data/org.freedesktop.Accounts.User.xml b/data/org.freedesktop.Accounts.User.xml index 0856974..103661c 100644 --- a/data/org.freedesktop.Accounts.User.xml +++ b/data/org.freedesktop.Accounts.User.xml @@ -331,6 +331,41 @@ + + + + + + The absolute filename of a png file to use as the users background. + + + + + + + Sets the users background. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own background + + + org.freedesktop.accounts.user-administration + To change the background of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + @@ -770,6 +805,16 @@ + + + + + The filename of a png file containing the users background. + + + + + diff --git a/src/libaccountsservice/act-user.c b/src/libaccountsservice/act-user.c index c0b52db..36d1ade 100644 --- a/src/libaccountsservice/act-user.c +++ b/src/libaccountsservice/act-user.c @@ -91,6 +91,7 @@ enum { PROP_LOGIN_FREQUENCY, PROP_LOGIN_TIME, PROP_LOGIN_HISTORY, + PROP_BACKGROUND_FILE, PROP_ICON_FILE, PROP_LANGUAGE, PROP_FORMATS_LOCALE, @@ -121,6 +122,7 @@ struct _ActUser { char *shell; char *email; char *location; + char *background_file; char *icon_file; char *language; char *formats_locale; @@ -304,6 +306,9 @@ act_user_get_property (GObject *object, case PROP_LOCATION: g_value_set_string (value, user->location); break; + case PROP_BACKGROUND_FILE: + g_value_set_string (value, user->background_file); + break; case PROP_ICON_FILE: g_value_set_string (value, user->icon_file); break; @@ -454,6 +459,13 @@ act_user_class_init (ActUserClass *class) G_VARIANT_TYPE ("a(xxa{sv})"), NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, + PROP_BACKGROUND_FILE, + g_param_spec_string ("background-file", + "Background File", + "The path to a background for this user.", + NULL, + G_PARAM_READABLE)); g_object_class_install_property (gobject_class, PROP_ICON_FILE, g_param_spec_string ("icon-file", @@ -585,6 +597,7 @@ act_user_finalize (GObject *object) g_free (user->user_name); g_free (user->real_name); + g_free (user->background_file); g_free (user->icon_file); g_free (user->language); g_free (user->object_path); @@ -1032,6 +1045,22 @@ act_user_is_nonexistent (ActUser *user) return user->nonexistent; } +/** + * act_user_get_background_file: + * @user: a #ActUser + * + * Returns the path to the account background belonging to @user. + * + * Returns: (transfer none): a path to a background + */ +const char * +act_user_get_background_file (ActUser *user) +{ + g_return_val_if_fail (ACT_IS_USER (user), NULL); + + return user->background_file; +} + /** * act_user_get_icon_file: * @user: a #ActUser @@ -1290,6 +1319,15 @@ collect_props (const gchar *key, user->login_history = g_variant_ref (new_login_history); g_object_notify (G_OBJECT (user), "login-history"); } + } else if (strcmp (key, "BackgroundFile") == 0) { + const char *new_background_file; + + new_background_file = g_variant_get_string (value, NULL); + if (g_strcmp0 (user->background_file, new_background_file) != 0) { + g_free (user->background_file); + user->background_file = g_strdup (new_background_file); + g_object_notify (G_OBJECT (user), "background-file"); + } } else if (strcmp (key, "IconFile") == 0) { const char *new_icon_file; @@ -1745,6 +1783,35 @@ act_user_set_language (ActUser *user, } } +/** + * act_user_set_background_file: + * @user: the user object to alter. + * @background_file: path to an background + * + * Assigns a new background for @user. + * + * Note this function is synchronous and ignores errors. + **/ +void +act_user_set_background_file (ActUser *user, + const char *background_file) +{ + GError *error = NULL; + + g_return_if_fail (ACT_IS_USER (user)); + g_return_if_fail (background_file != NULL); + g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy)); + + if (!accounts_user_call_set_background_file_sync (user->accounts_proxy, + background_file, + NULL, + &error)) { + g_warning ("SetBackgroundFile call failed: %s", error->message); + g_error_free (error); + return; + } +} + /** * act_user_set_x_session: * @user: the user object to alter. diff --git a/src/user.c b/src/user.c index e0dc56a..c32971e 100644 --- a/src/user.c +++ b/src/user.c @@ -64,6 +64,7 @@ enum { PROP_LOGIN_FREQUENCY, PROP_LOGIN_TIME, PROP_LOGIN_HISTORY, + PROP_BACKGROUND_FILE, PROP_ICON_FILE, PROP_LOCKED, PROP_PASSWORD_MODE, @@ -98,6 +99,7 @@ struct User { gchar *x_session; gchar *location; guint64 login_frequency; + gchar *background_file; gint64 login_time; gint64 expiration_time; gint64 last_change_time; @@ -356,6 +358,13 @@ user_update_from_keyfile (User *user, g_object_notify (G_OBJECT (user), "password-hint"); } + s = g_key_file_get_string (keyfile, "User", "Background", NULL); + if (s != NULL) { + g_free (user->background_file); + user->background_file = s; + g_object_notify (G_OBJECT (user), "background-file"); + } + s = g_key_file_get_string (keyfile, "User", "Icon", NULL); if (s != NULL) { g_free (user->icon_file); @@ -423,6 +432,9 @@ user_save_to_keyfile (User *user, if (user->password_hint) g_key_file_set_string (keyfile, "User", "PasswordHint", user->password_hint); + if (user->background_file) + g_key_file_set_string (keyfile, "User", "Background", user->background_file); + if (user->icon_file) g_key_file_set_string (keyfile, "User", "Icon", user->icon_file); @@ -1460,6 +1472,86 @@ become_user (gpointer data) } } +static void +user_change_background_file_authorized_cb (Daemon *daemon, + User *user, + GDBusMethodInvocation *context, + gpointer data) +{ + gchar *filename; + GFile *file; + GFileInfo *info; + GFileType type; + + filename = g_strdup (data); + + if (filename == NULL || + *filename == '\0') { + g_free (filename); + filename = NULL; + + goto background_saved; + } + + file = g_file_new_for_path (filename); + info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE, + 0, NULL, NULL); + type = g_file_info_get_file_type (info); + + g_object_unref (info); + g_object_unref (file); + + if (type != G_FILE_TYPE_REGULAR) { + g_debug ("not a regular file\n"); + throw_error (context, ERROR_FAILED, "file '%s' is not a regular file", filename); + g_free (filename); + return; + } + +background_saved: + g_free (user->background_file); + user->background_file = filename; + + save_extra_data (user); + + accounts_user_emit_changed (ACCOUNTS_USER (user)); + + g_object_notify (G_OBJECT (user), "background-file"); + + accounts_user_complete_set_background_file (ACCOUNTS_USER (user), context); +} + +gboolean +user_set_background_file (AccountsUser *auser, + GDBusMethodInvocation *context, + const gchar *filename) +{ + User *user = (User*)auser; + int uid; + const gchar *action_id; + + if (!get_caller_uid (context, &uid)) { + throw_error (context, ERROR_FAILED, "identifying caller failed"); + return FALSE; + } + + if (user->uid == (uid_t) uid) + action_id = "org.freedesktop.accounts.change-own-user-data"; + else + action_id = "org.freedesktop.accounts.user-administration"; + + daemon_local_check_auth (user->daemon, + user, + action_id, + TRUE, + user_change_background_file_authorized_cb, + context, + g_strdup (filename), + (GDestroyNotify)g_free); + + return TRUE; +} + static void user_change_icon_file_authorized_cb (Daemon *daemon, User *user, @@ -2274,6 +2366,7 @@ user_finalize (GObject *object) g_free (user->shell); g_free (user->icon_file); g_free (user->default_icon_file); + g_free (user->background_file); g_free (user->email); g_free (user->language); g_free (user->formats_locale); @@ -2383,6 +2476,9 @@ user_get_property (GObject *object, case PROP_LOCATION: g_value_set_string (value, user->location); break; + case PROP_BACKGROUND_FILE: + g_value_set_string (value, user->background_file); + break; case PROP_ICON_FILE: if (user->icon_file) g_value_set_string (value, user->icon_file); @@ -2439,6 +2535,7 @@ user_accounts_user_iface_init (AccountsUserIface *iface) { iface->handle_set_account_type = user_set_account_type; iface->handle_set_automatic_login = user_set_automatic_login; + iface->handle_set_background_file = user_set_background_file; iface->handle_set_email = user_set_email; iface->handle_set_formats_locale = user_set_formats_locale; iface->handle_set_home_directory = user_set_home_directory; @@ -2485,6 +2582,7 @@ user_init (User *user) user->account_type = ACCOUNT_TYPE_STANDARD; user->home_dir = NULL; user->shell = NULL; + user->background_file = NULL; user->icon_file = NULL; user->default_icon_file = NULL; user->email = NULL; -- 2.20.1