From 0e3381dc788670849751dcb01b4257b56095b334 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Thu, 27 Sep 2018 23:31:06 +0200 Subject: [PATCH 1/4] 0001-formats-locale-property.patch --- data/org.freedesktop.Accounts.User.xml | 45 +++++++++++++++ src/libaccountsservice/act-user.c | 69 +++++++++++++++++++++++ src/libaccountsservice/act-user.h | 3 + src/user.c | 76 ++++++++++++++++++++++++++ 4 files changed, 193 insertions(+) diff --git a/data/org.freedesktop.Accounts.User.xml b/data/org.freedesktop.Accounts.User.xml index 4ab989a..0856974 100644 --- a/data/org.freedesktop.Accounts.User.xml +++ b/data/org.freedesktop.Accounts.User.xml @@ -150,6 +150,41 @@ + + + + + + The new regional formats, as a locale specification like "de_DE.UTF-8". + + + + + + + Sets the users regional formats. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own language + + + org.freedesktop.accounts.user-administration + To change the language of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + @@ -668,6 +703,16 @@ + + + + + The users regional formats, as a locale specification like "de_DE.UTF-8". + + + + + diff --git a/src/libaccountsservice/act-user.c b/src/libaccountsservice/act-user.c index dbb9b53..c0b52db 100644 --- a/src/libaccountsservice/act-user.c +++ b/src/libaccountsservice/act-user.c @@ -93,6 +93,7 @@ enum { PROP_LOGIN_HISTORY, PROP_ICON_FILE, PROP_LANGUAGE, + PROP_FORMATS_LOCALE, PROP_X_SESSION, PROP_IS_LOADED }; @@ -122,6 +123,7 @@ struct _ActUser { char *location; char *icon_file; char *language; + char *formats_locale; char *x_session; GList *our_sessions; GList *other_sessions; @@ -308,6 +310,9 @@ act_user_get_property (GObject *object, case PROP_LANGUAGE: g_value_set_string (value, user->language); break; + case PROP_FORMATS_LOCALE: + g_value_set_string (value, user->formats_locale); + break; case PROP_X_SESSION: g_value_set_string (value, user->x_session); break; @@ -463,6 +468,13 @@ act_user_class_init (ActUserClass *class) "User's locale.", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, + PROP_FORMATS_LOCALE, + g_param_spec_string ("formats_locale", + "Regional Formats", + "User's regional formats.", + NULL, + G_PARAM_READABLE)); g_object_class_install_property (gobject_class, PROP_X_SESSION, g_param_spec_string ("x-session", @@ -583,6 +595,7 @@ act_user_finalize (GObject *object) g_free (user->location); if (user->login_history) g_variant_unref (user->login_history); + g_free (user->formats_locale); if (user->accounts_proxy != NULL) { g_object_unref (user->accounts_proxy); @@ -1051,6 +1064,22 @@ act_user_get_language (ActUser *user) return user->language; } +/** + * act_user_get_formats_locale: + * @user: a #ActUser + * + * Returns the path to the configured formats locale of @user. + * + * Returns: (transfer none): a path to an icon + */ +const char * +act_user_get_formats_locale (ActUser *user) +{ + g_return_val_if_fail (ACT_IS_USER (user), NULL); + + return user->formats_locale; +} + /** * act_user_get_x_session: * @user: a #ActUser @@ -1279,6 +1308,17 @@ collect_props (const gchar *key, user->language = g_strdup (new_language); g_object_notify (G_OBJECT (user), "language"); } + + } else if (strcmp (key, "FormatsLocale") == 0) { + const char *new_formats_locale; + + new_formats_locale = g_variant_get_string (value, NULL); + if (g_strcmp0 (user->formats_locale, new_formats_locale) != 0) { + g_free (user->formats_locale); + user->formats_locale = g_strdup (new_formats_locale); + g_object_notify (G_OBJECT (user), "formats_locale"); + } + } else if (strcmp (key, "XSession") == 0) { const char *new_x_session; @@ -1618,6 +1658,35 @@ act_user_get_password_expiration_policy (ActUser *user, } } +/** + * act_user_set_formats_locale: + * @user: the user object to alter. + * @formats_locale: a locale (e.g. en_US.utf8) + * + * Assigns a new formats locale for @user. + * + * Note this function is synchronous and ignores errors. + **/ +void +act_user_set_formats_locale (ActUser *user, + const char *formats_locale) +{ + GError *error = NULL; + + g_return_if_fail (ACT_IS_USER (user)); + g_return_if_fail (formats_locale != NULL); + g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy)); + + if (!accounts_user_call_set_formats_locale_sync (user->accounts_proxy, + formats_locale, + NULL, + &error)) { + g_warning ("SetFormatsLocale call failed: %s", error->message); + g_error_free (error); + return; + } +} + /** * act_user_set_email: * @user: the user object to alter. diff --git a/src/libaccountsservice/act-user.h b/src/libaccountsservice/act-user.h index 76dceb6..e026ce2 100644 --- a/src/libaccountsservice/act-user.h +++ b/src/libaccountsservice/act-user.h @@ -77,6 +77,7 @@ gboolean act_user_is_local_account (ActUser *user); gboolean act_user_is_nonexistent (ActUser *user); const char *act_user_get_icon_file (ActUser *user); const char *act_user_get_language (ActUser *user); +const char *act_user_get_formats_locale (ActUser *user); const char *act_user_get_x_session (ActUser *user); const char *act_user_get_primary_session_id (ActUser *user); @@ -96,6 +97,8 @@ void act_user_set_email (ActUser *user, const char *email); void act_user_set_language (ActUser *user, const char *language); +void act_user_set_formats_locale (ActUser *user, + const char *formats_locale); void act_user_set_x_session (ActUser *user, const char *x_session); void act_user_set_location (ActUser *user, diff --git a/src/user.c b/src/user.c index 802d07a..e0dc56a 100644 --- a/src/user.c +++ b/src/user.c @@ -58,6 +58,7 @@ enum { PROP_SHELL, PROP_EMAIL, PROP_LANGUAGE, + PROP_FORMATS_LOCALE, PROP_X_SESSION, PROP_LOCATION, PROP_LOGIN_FREQUENCY, @@ -93,6 +94,7 @@ struct User { gchar *shell; gchar *email; gchar *language; + gchar *formats_locale; gchar *x_session; gchar *location; guint64 login_frequency; @@ -319,6 +321,13 @@ user_update_from_keyfile (User *user, g_object_notify (G_OBJECT (user), "language"); } + s = g_key_file_get_string (keyfile, "User", "FormatsLocale", NULL); + if (s != NULL) { + g_free (user->formats_locale); + user->formats_locale = s; + g_object_notify (G_OBJECT (user), "formats-locale"); + } + s = g_key_file_get_string (keyfile, "User", "XSession", NULL); if (s != NULL) { g_free (user->x_session); @@ -402,6 +411,9 @@ user_save_to_keyfile (User *user, if (user->language) g_key_file_set_string (keyfile, "User", "Language", user->language); + if (user->formats_locale) + g_key_file_set_string (keyfile, "User", "FormatsLocale", user->formats_locale); + if (user->x_session) g_key_file_set_string (keyfile, "User", "XSession", user->x_session); @@ -1103,6 +1115,61 @@ user_set_language (AccountsUser *auser, return TRUE; } +static void +user_change_formats_locale_authorized_cb (Daemon *daemon, + User *user, + GDBusMethodInvocation *context, + gpointer data) + +{ + gchar *formats_locale = data; + + if (g_strcmp0 (user->formats_locale, formats_locale) != 0) { + g_free (user->formats_locale); + user->formats_locale = g_strdup (formats_locale); + + save_extra_data (user); + + accounts_user_emit_changed (ACCOUNTS_USER (user)); + + g_object_notify (G_OBJECT (user), "formats_locale"); + } + + accounts_user_complete_set_formats_locale (ACCOUNTS_USER (user), context); +} + +gboolean +user_set_formats_locale (AccountsUser *auser, + GDBusMethodInvocation *context, + const gchar *formats_locale) +{ + 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_formats_locale_authorized_cb, + context, + g_strdup (formats_locale), + (GDestroyNotify) g_free); + + return TRUE; +} + static void user_change_x_session_authorized_cb (Daemon *daemon, User *user, @@ -2209,6 +2276,7 @@ user_finalize (GObject *object) g_free (user->default_icon_file); g_free (user->email); g_free (user->language); + g_free (user->formats_locale); g_free (user->x_session); g_free (user->location); g_free (user->password_hint); @@ -2235,6 +2303,9 @@ user_set_property (GObject *object, case PROP_LANGUAGE: user->language = g_value_dup_string (value); break; + case PROP_FORMATS_LOCALE: + user->formats_locale = g_value_dup_string (value); + break; case PROP_X_SESSION: user->x_session = g_value_dup_string (value); break; @@ -2303,6 +2374,9 @@ user_get_property (GObject *object, case PROP_LANGUAGE: g_value_set_string (value, user->language); break; + case PROP_FORMATS_LOCALE: + g_value_set_string (value, user->formats_locale); + break; case PROP_X_SESSION: g_value_set_string (value, user->x_session); break; @@ -2366,6 +2440,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_email = user_set_email; + iface->handle_set_formats_locale = user_set_formats_locale; iface->handle_set_home_directory = user_set_home_directory; iface->handle_set_icon_file = user_set_icon_file; iface->handle_set_language = user_set_language; @@ -2414,6 +2489,7 @@ user_init (User *user) user->default_icon_file = NULL; user->email = NULL; user->language = NULL; + user->formats_locale = NULL; user->x_session = NULL; user->location = NULL; user->password_mode = PASSWORD_MODE_REGULAR; -- 2.20.1