From 06f3b7c3f0f2afec76d370ff134a2d029c0482c7 Mon Sep 17 00:00:00 2001 From: peijiankang Date: Mon, 18 Sep 2023 10:29:43 +0800 Subject: [PATCH] add-background-file-support --- data/org.freedesktop.Accounts.User.xml | 46 +++++++++++++++ src/libaccountsservice/act-user.c | 57 +++++++++++++++++++ src/libaccountsservice/act-user.h | 3 + src/user.c | 79 ++++++++++++++++++++++++++ 4 files changed, 185 insertions(+) diff --git a/data/org.freedesktop.Accounts.User.xml b/data/org.freedesktop.Accounts.User.xml index d54ba44..7a8a915 100644 --- a/data/org.freedesktop.Accounts.User.xml +++ b/data/org.freedesktop.Accounts.User.xml @@ -420,6 +420,42 @@ + + + + + + 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 + + + + + @@ -893,6 +929,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 77b7b2f..9125d43 100644 --- a/src/libaccountsservice/act-user.c +++ b/src/libaccountsservice/act-user.c @@ -90,6 +90,7 @@ enum PROP_LOGIN_FREQUENCY, PROP_LOGIN_TIME, PROP_LOGIN_HISTORY, + PROP_BACKGROUND_FILE, PROP_ICON_FILE, PROP_LANGUAGE, PROP_X_SESSION, @@ -272,6 +273,13 @@ act_user_class_init (ActUserClass *class) "The real name to display for this user.", 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_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_ACCOUNT_TYPE, @@ -998,6 +1006,25 @@ 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); + + if (user->accounts_proxy == NULL) + return NULL; + + return accounts_user_get_background_file (user->accounts_proxy); +} + /** * act_user_get_icon_file: * @user: a #ActUser @@ -1474,6 +1501,7 @@ act_user_set_language (ActUser *user, } } + /** * act_user_set_languages: * @user: the user object to alter. @@ -1509,6 +1537,35 @@ act_user_set_languages (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) +{ + g_autoptr(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, + G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION, + -1, + NULL, + &error)) { + g_warning ("SetBackgroundFile for backgroundfile %s failed: %s", background_file, error->message); + return; + } +} /** * act_user_set_x_session: * @user: the user object to alter. diff --git a/src/libaccountsservice/act-user.h b/src/libaccountsservice/act-user.h index fe9a8a4..82019f5 100644 --- a/src/libaccountsservice/act-user.h +++ b/src/libaccountsservice/act-user.h @@ -69,6 +69,7 @@ gboolean act_user_get_automatic_login (ActUser *user); gboolean act_user_is_system_account (ActUser *user); gboolean act_user_is_local_account (ActUser *user); gboolean act_user_is_nonexistent (ActUser *user); +const char *act_user_get_background_file (ActUser *user); const char *act_user_get_icon_file (ActUser *user); const char *act_user_get_language (ActUser *user); const char * const *act_user_get_languages (ActUser *user); @@ -100,6 +101,8 @@ void act_user_set_user_expiration_policy (ActUser *user, void act_user_set_language (ActUser *user, const char *language); +void act_user_set_background_file (ActUser *user, + const char *background_file); void act_user_set_languages (ActUser *user, const char * const *languages); diff --git a/src/user.c b/src/user.c index 917d427..16a1cbd 100644 --- a/src/user.c +++ b/src/user.c @@ -521,6 +521,11 @@ user_update_from_keyfile (User *user, GKeyFile *keyfile) { gchar *s, **sl; + s = g_key_file_get_string (keyfile, "User", "Background", NULL); + if (s != NULL) { + accounts_user_set_background_file (ACCOUNTS_USER (user), s); + g_clear_pointer (&s, g_free); + } s = g_key_file_get_string (keyfile, "User", "Language", NULL); sl = g_key_file_get_string_list (keyfile, "User", "Languages", NULL, NULL); @@ -676,6 +681,9 @@ user_save_to_keyfile (User *user, if (accounts_user_get_password_hint (ACCOUNTS_USER (user))) g_key_file_set_string (keyfile, "User", "PasswordHint", accounts_user_get_password_hint (ACCOUNTS_USER (user))); + if (accounts_user_get_background_file (ACCOUNTS_USER (user))) + g_key_file_set_string (keyfile, "User", "Background", accounts_user_get_background_file (ACCOUNTS_USER (user))); + if (accounts_user_get_icon_file (ACCOUNTS_USER (user))) g_key_file_set_string (keyfile, "User", "Icon", accounts_user_get_icon_file (ACCOUNTS_USER (user))); @@ -2026,6 +2034,76 @@ become_user (gpointer data) } } +static void +user_change_background_file_authorized_cb (Daemon *daemon, + User *user, + GDBusMethodInvocation *context, + gpointer data) +{ + g_autofree gchar *filename = NULL; + g_autoptr(GFile) file = NULL; + g_autoptr(GFileInfo) info = NULL; + 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); + + 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); + return; + } + +background_saved: + accounts_user_set_background_file (ACCOUNTS_USER (user), filename); + + save_extra_data (user); + + accounts_user_complete_set_background_file (ACCOUNTS_USER (user), context); +} + +static 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 (accounts_user_get_uid (ACCOUNTS_USER (user)) == (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, + 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, @@ -2722,6 +2800,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_home_directory = user_set_home_directory; iface->handle_set_icon_file = user_set_icon_file; -- 2.27.0