[evolution-ews/wip/mcrha/office365] Add impersonate settings
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews/wip/mcrha/office365] Add impersonate settings
- Date: Wed, 17 Jun 2020 08:43:55 +0000 (UTC)
commit 5597aa44ae9e36f208ab1caeac980724609765d4
Author: Milan Crha <mcrha redhat com>
Date: Wed Jun 17 10:43:40 2020 +0200
Add impersonate settings
src/Office365/common/camel-o365-settings.c | 123 ++++++++++++++
src/Office365/common/camel-o365-settings.h | 12 ++
src/Office365/common/e-o365-connection.c | 187 ++++++++++++++++++---
.../evolution/e-mail-config-o365-backend.c | 35 ++++
4 files changed, 332 insertions(+), 25 deletions(-)
---
diff --git a/src/Office365/common/camel-o365-settings.c b/src/Office365/common/camel-o365-settings.c
index c103962f..52579232 100644
--- a/src/Office365/common/camel-o365-settings.c
+++ b/src/Office365/common/camel-o365-settings.c
@@ -24,12 +24,14 @@
struct _CamelO365SettingsPrivate {
GMutex property_lock;
+ gboolean use_impersonation;
gboolean check_all;
gboolean filter_junk;
gboolean filter_junk_inbox;
gboolean override_oauth2;
guint timeout;
guint concurrent_connections;
+ gchar *impersonate_user;
gchar *email;
gchar *oauth2_tenant;
gchar *oauth2_client_id;
@@ -48,6 +50,8 @@ enum {
PROP_SECURITY_METHOD,
PROP_TIMEOUT,
PROP_USER,
+ PROP_USE_IMPERSONATION,
+ PROP_IMPERSONATE_USER,
PROP_OVERRIDE_OAUTH2,
PROP_OAUTH2_TENANT,
PROP_OAUTH2_CLIENT_ID,
@@ -126,6 +130,18 @@ o365_settings_set_property (GObject *object,
g_value_get_string (value));
return;
+ case PROP_USE_IMPERSONATION:
+ camel_o365_settings_set_use_impersonation (
+ CAMEL_O365_SETTINGS (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_IMPERSONATE_USER:
+ camel_o365_settings_set_impersonate_user (
+ CAMEL_O365_SETTINGS (object),
+ g_value_get_string (value));
+ return;
+
case PROP_OVERRIDE_OAUTH2:
camel_o365_settings_set_override_oauth2 (
CAMEL_O365_SETTINGS (object),
@@ -237,6 +253,20 @@ o365_settings_get_property (GObject *object,
CAMEL_NETWORK_SETTINGS (object)));
return;
+ case PROP_USE_IMPERSONATION:
+ g_value_set_boolean (
+ value,
+ camel_o365_settings_get_use_impersonation (
+ CAMEL_O365_SETTINGS (object)));
+ return;
+
+ case PROP_IMPERSONATE_USER:
+ g_value_take_string (
+ value,
+ camel_o365_settings_dup_impersonate_user (
+ CAMEL_O365_SETTINGS (object)));
+ return;
+
case PROP_OVERRIDE_OAUTH2:
g_value_set_boolean (
value,
@@ -392,6 +422,30 @@ camel_o365_settings_class_init (CamelO365SettingsClass *class)
PROP_USER,
"user");
+ g_object_class_install_property (
+ object_class,
+ PROP_USE_IMPERSONATION,
+ g_param_spec_boolean (
+ "use-impersonation",
+ "Use Impersonation",
+ "Use Impersonation",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_IMPERSONATE_USER,
+ g_param_spec_string (
+ "impersonate-user",
+ "Impersonate User",
+ "Impersonate User",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
g_object_class_install_property (
object_class,
PROP_OVERRIDE_OAUTH2,
@@ -500,6 +554,75 @@ camel_o365_settings_get_from_backend (struct _EBackend *backend,
return CAMEL_O365_SETTINGS (settings);
}
+gboolean
+camel_o365_settings_get_use_impersonation (CamelO365Settings *settings)
+{
+ g_return_val_if_fail (CAMEL_IS_O365_SETTINGS (settings), FALSE);
+
+ return settings->priv->use_impersonation;
+}
+
+void
+camel_o365_settings_set_use_impersonation (CamelO365Settings *settings,
+ gboolean use_impersonation)
+{
+ g_return_if_fail (CAMEL_IS_O365_SETTINGS (settings));
+
+ if ((settings->priv->use_impersonation ? 1 : 0) == (use_impersonation ? 1 : 0))
+ return;
+
+ settings->priv->use_impersonation = use_impersonation;
+
+ g_object_notify (G_OBJECT (settings), "use-impersonation");
+}
+
+const gchar *
+camel_o365_settings_get_impersonate_user (CamelO365Settings *settings)
+{
+ g_return_val_if_fail (CAMEL_IS_O365_SETTINGS (settings), NULL);
+
+ return settings->priv->impersonate_user;
+}
+
+gchar *
+camel_o365_settings_dup_impersonate_user (CamelO365Settings *settings)
+{
+ const gchar *protected;
+ gchar *duplicate;
+
+ g_return_val_if_fail (CAMEL_IS_O365_SETTINGS (settings), NULL);
+
+ g_mutex_lock (&settings->priv->property_lock);
+
+ protected = camel_o365_settings_get_impersonate_user (settings);
+ duplicate = g_strdup (protected);
+
+ g_mutex_unlock (&settings->priv->property_lock);
+
+ return duplicate;
+}
+
+void
+camel_o365_settings_set_impersonate_user (CamelO365Settings *settings,
+ const gchar *impersonate_user)
+{
+ g_return_if_fail (CAMEL_IS_O365_SETTINGS (settings));
+
+ g_mutex_lock (&settings->priv->property_lock);
+
+ if (g_strcmp0 (settings->priv->impersonate_user, impersonate_user) == 0) {
+ g_mutex_unlock (&settings->priv->property_lock);
+ return;
+ }
+
+ g_free (settings->priv->impersonate_user);
+ settings->priv->impersonate_user = e_util_strdup_strip (impersonate_user);
+
+ g_mutex_unlock (&settings->priv->property_lock);
+
+ g_object_notify (G_OBJECT (settings), "impersonate-user");
+}
+
gboolean
camel_o365_settings_get_check_all (CamelO365Settings *settings)
{
diff --git a/src/Office365/common/camel-o365-settings.h b/src/Office365/common/camel-o365-settings.h
index 3f05b178..8cc038be 100644
--- a/src/Office365/common/camel-o365-settings.h
+++ b/src/Office365/common/camel-o365-settings.h
@@ -66,6 +66,18 @@ CamelO365Settings *
camel_o365_settings_get_from_backend
(struct _EBackend *backend,
struct _ESourceRegistry *registry);
+gboolean camel_o365_settings_get_use_impersonation
+ (CamelO365Settings *settings);
+void camel_o365_settings_set_use_impersonation
+ (CamelO365Settings *settings,
+ gboolean use_impersonation);
+const gchar * camel_o365_settings_get_impersonate_user
+ (CamelO365Settings *settings);
+gchar * camel_o365_settings_dup_impersonate_user
+ (CamelO365Settings *settings);
+void camel_o365_settings_set_impersonate_user
+ (CamelO365Settings *settings,
+ const gchar *impersonate_user);
gboolean camel_o365_settings_get_check_all
(CamelO365Settings *settings);
void camel_o365_settings_set_check_all
diff --git a/src/Office365/common/e-o365-connection.c b/src/Office365/common/e-o365-connection.c
index ca1fc975..1f6db867 100644
--- a/src/Office365/common/e-o365-connection.c
+++ b/src/Office365/common/e-o365-connection.c
@@ -45,6 +45,9 @@ struct _EO365ConnectionPrivate {
GProxyResolver *proxy_resolver;
ESoupAuthBearer *bearer_auth;
+ gchar *user; /* The default user for the URL */
+ gchar *impersonate_user;
+
gboolean ssl_info_set;
gchar *ssl_certificate_pem;
GTlsCertificateFlags ssl_certificate_errors;
@@ -62,7 +65,10 @@ enum {
PROP_PROXY_RESOLVER,
PROP_SETTINGS,
PROP_SOURCE,
- PROP_CONCURRENT_CONNECTIONS
+ PROP_CONCURRENT_CONNECTIONS,
+ PROP_USER, /* This one is hidden, write only */
+ PROP_USE_IMPERSONATION, /* This one is hidden, write only */
+ PROP_IMPERSONATE_USER /* This one is hidden, write only */
};
G_DEFINE_TYPE_WITH_PRIVATE (EO365Connection, e_o365_connection, G_TYPE_OBJECT)
@@ -326,6 +332,24 @@ o365_connection_set_settings (EO365Connection *cnc,
g_return_if_fail (cnc->priv->settings == NULL);
cnc->priv->settings = g_object_ref (settings);
+
+ e_binding_bind_property (
+ cnc->priv->settings, "user",
+ cnc, "user",
+ G_BINDING_DEFAULT |
+ G_BINDING_SYNC_CREATE);
+
+ e_binding_bind_property (
+ cnc->priv->settings, "use-impersonation",
+ cnc, "use-impersonation",
+ G_BINDING_DEFAULT |
+ G_BINDING_SYNC_CREATE);
+
+ /* No need to G_BINDING_SYNC_CREATE, because the 'use-impersonation' already updated the value */
+ e_binding_bind_property (
+ cnc->priv->settings, "impersonate-user",
+ cnc, "impersonate-user",
+ G_BINDING_DEFAULT);
}
static void
@@ -339,6 +363,62 @@ o365_connection_set_source (EO365Connection *cnc,
cnc->priv->source = g_object_ref (source);
}
+static void
+o365_connection_take_user (EO365Connection *cnc,
+ gchar *user)
+{
+ g_return_if_fail (E_IS_O365_CONNECTION (cnc));
+
+ LOCK (cnc);
+
+ if (!user || !*user)
+ g_clear_pointer (&user, g_free);
+
+ g_free (cnc->priv->user);
+ cnc->priv->user = user;
+
+ UNLOCK (cnc);
+}
+
+static void
+o365_connection_take_impersonate_user (EO365Connection *cnc,
+ gchar *impersonate_user)
+{
+ g_return_if_fail (E_IS_O365_CONNECTION (cnc));
+
+ LOCK (cnc);
+
+ if (!impersonate_user || !*impersonate_user ||
+ !camel_o365_settings_get_use_impersonation (cnc->priv->settings)) {
+ g_clear_pointer (&impersonate_user, g_free);
+ }
+
+ if (g_strcmp0 (impersonate_user, cnc->priv->impersonate_user) != 0) {
+ g_free (cnc->priv->impersonate_user);
+ cnc->priv->impersonate_user = impersonate_user;
+ } else {
+ g_clear_pointer (&impersonate_user, g_free);
+ }
+
+ UNLOCK (cnc);
+}
+
+static void
+o365_connection_set_use_impersonation (EO365Connection *cnc,
+ gboolean use_impersonation)
+{
+ g_return_if_fail (E_IS_O365_CONNECTION (cnc));
+
+ LOCK (cnc);
+
+ if (!use_impersonation)
+ o365_connection_take_impersonate_user (cnc, NULL);
+ else
+ o365_connection_take_impersonate_user (cnc, camel_o365_settings_dup_impersonate_user
(cnc->priv->settings));
+
+ UNLOCK (cnc);
+}
+
static void
o365_connection_set_property (GObject *object,
guint property_id,
@@ -369,6 +449,24 @@ o365_connection_set_property (GObject *object,
E_O365_CONNECTION (object),
g_value_get_uint (value));
return;
+
+ case PROP_USER:
+ o365_connection_take_user (
+ E_O365_CONNECTION (object),
+ g_value_dup_string (value));
+ return;
+
+ case PROP_USE_IMPERSONATION:
+ o365_connection_set_use_impersonation (
+ E_O365_CONNECTION (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_IMPERSONATE_USER:
+ o365_connection_take_impersonate_user (
+ E_O365_CONNECTION (object),
+ g_value_dup_string (value));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -494,6 +592,8 @@ o365_connection_finalize (GObject *object)
g_rec_mutex_clear (&cnc->priv->property_lock);
g_clear_pointer (&cnc->priv->ssl_certificate_pem, g_free);
+ g_clear_pointer (&cnc->priv->user, g_free);
+ g_clear_pointer (&cnc->priv->impersonate_user, g_free);
g_free (cnc->priv->hash_key);
/* Chain up to parent's method. */
@@ -561,6 +661,39 @@ e_o365_connection_class_init (EO365ConnectionClass *class)
G_PARAM_READWRITE |
G_PARAM_EXPLICIT_NOTIFY |
G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_USER,
+ g_param_spec_string (
+ "user",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_WRITABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_USE_IMPERSONATION,
+ g_param_spec_boolean (
+ "use-impersonation",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_WRITABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_IMPERSONATE_USER,
+ g_param_spec_string (
+ "impersonate-user",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_WRITABLE |
+ G_PARAM_STATIC_STRINGS));
}
static void
@@ -1195,35 +1328,29 @@ e_o365_construct_uri (EO365Connection *cnc,
}
if (include_user) {
- if (user_override) {
+ const gchar *use_user;
+
+ LOCK (cnc);
+
+ if (user_override)
+ use_user = user_override;
+ else if (cnc->priv->impersonate_user)
+ use_user = cnc->priv->impersonate_user;
+ else
+ use_user = cnc->priv->user;
+
+ if (use_user) {
gchar *encoded;
- encoded = soup_uri_encode (user_override, NULL);
+ encoded = soup_uri_encode (use_user, NULL);
g_string_append_c (uri, '/');
g_string_append (uri, encoded);
g_free (encoded);
- } else {
- CamelO365Settings *settings;
- gchar *user;
-
- settings = e_o365_connection_get_settings (cnc);
- user = camel_network_settings_dup_user (CAMEL_NETWORK_SETTINGS (settings));
-
- if (user && *user) {
- gchar *encoded;
-
- encoded = soup_uri_encode (user, NULL);
-
- g_string_append_c (uri, '/');
- g_string_append (uri, encoded);
-
- g_free (encoded);
- }
-
- g_free (user);
}
+
+ UNLOCK (cnc);
}
if (resource && *resource) {
@@ -1419,10 +1546,20 @@ e_o365_connection_authenticate_sync (EO365Connection *cnc,
bearer = e_o365_connection_ref_bearer_auth (cnc);
- if (bearer)
- result = E_SOURCE_AUTHENTICATION_REJECTED;
- else
+ if (bearer) {
+ LOCK (cnc);
+
+ if (cnc->priv->impersonate_user) {
+ g_propagate_error (error, local_error);
+ local_error = NULL;
+ } else {
+ result = E_SOURCE_AUTHENTICATION_REJECTED;
+ }
+
+ UNLOCK (cnc);
+ } else {
result = E_SOURCE_AUTHENTICATION_REQUIRED;
+ }
g_clear_object (&bearer);
g_clear_error (&local_error);
diff --git a/src/Office365/evolution/e-mail-config-o365-backend.c
b/src/Office365/evolution/e-mail-config-o365-backend.c
index eedad28a..73781265 100644
--- a/src/Office365/evolution/e-mail-config-o365-backend.c
+++ b/src/Office365/evolution/e-mail-config-o365-backend.c
@@ -33,6 +33,7 @@
struct _EMailConfigO365BackendPrivate {
GtkWidget *user_entry;
+ GtkWidget *impersonate_user_entry;
GtkGrid *oauth2_settings_grid;
GtkWidget *oauth2_override_check;
GtkWidget *oauth2_tenant_entry;
@@ -204,6 +205,40 @@ mail_config_o365_backend_insert_widgets (EMailConfigServiceBackend *backend,
o365_backend->priv->user_entry = widget; /* do not reference */
gtk_widget_show (widget);
+ widget = gtk_check_button_new_with_mnemonic (_("Open _Mailbox of other user"));
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 1, 1);
+ gtk_widget_show (widget);
+
+ if (camel_o365_settings_get_use_impersonation (CAMEL_O365_SETTINGS (settings))) {
+ const gchar *impersonate_user = camel_o365_settings_get_impersonate_user (CAMEL_O365_SETTINGS
(settings));
+
+ if (impersonate_user && !*impersonate_user) {
+ camel_o365_settings_set_impersonate_user (CAMEL_O365_SETTINGS (settings), NULL);
+ camel_o365_settings_set_use_impersonation (CAMEL_O365_SETTINGS (settings), FALSE);
+ }
+ }
+
+ e_binding_bind_property (
+ settings, "use-impersonation",
+ widget, "active",
+ G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+
+ widget = gtk_entry_new ();
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_grid_attach (GTK_GRID (container), widget, 1, 2, 1, 1);
+ gtk_widget_show (widget);
+ o365_backend->priv->impersonate_user_entry = widget; /* do not reference */
+
+ e_binding_bind_object_text_property (
+ settings, "impersonate-user",
+ widget, "text",
+ G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+
+ e_binding_bind_property (
+ settings, "use-impersonation",
+ widget, "sensitive",
+ G_BINDING_SYNC_CREATE);
+
text = _("Authentication");
markup = g_markup_printf_escaped ("<b>%s</b>", text);
widget = gtk_label_new (markup);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]