I#1637 - EMailAutoconfig: Autoconfig with Exchange accounts
Let the EMailAutoconfig gather unknown types and pass them to anyone listening to process those known to it. Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/1637
This commit is contained in:
@ -103,11 +103,15 @@ struct _EMailAutoconfigPrivate {
|
||||
EMailAutoconfigResult imap_result;
|
||||
EMailAutoconfigResult pop3_result;
|
||||
EMailAutoconfigResult smtp_result;
|
||||
EMailAutoconfigResult custom_result;
|
||||
GHashTable *custom_types; /* gchar *type ~> ENamedParameters *params */
|
||||
};
|
||||
|
||||
struct _ParserClosure {
|
||||
EMailAutoconfig *autoconfig;
|
||||
EMailAutoconfigResult *result;
|
||||
gchar *current_type;
|
||||
ENamedParameters *custom_params;
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -117,19 +121,33 @@ enum {
|
||||
PROP_USE_DOMAIN
|
||||
};
|
||||
|
||||
enum {
|
||||
PROCESS_CUSTOM_TYPES,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
/* Forward Declarations */
|
||||
static void e_mail_autoconfig_initable_init (GInitableIface *iface);
|
||||
|
||||
/* By default, the GAsyncInitable interface calls GInitable.init()
|
||||
* from a separate thread, so we only have to override GInitable. */
|
||||
G_DEFINE_TYPE_WITH_CODE (
|
||||
EMailAutoconfig,
|
||||
e_mail_autoconfig,
|
||||
G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (
|
||||
G_TYPE_INITABLE, e_mail_autoconfig_initable_init)
|
||||
G_IMPLEMENT_INTERFACE (
|
||||
G_TYPE_ASYNC_INITABLE, NULL))
|
||||
G_DEFINE_TYPE_WITH_CODE (EMailAutoconfig, e_mail_autoconfig, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, e_mail_autoconfig_initable_init)
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, NULL)
|
||||
G_IMPLEMENT_INTERFACE (E_TYPE_EXTENSIBLE, NULL))
|
||||
|
||||
static void
|
||||
e_mail_config_result_clear (EMailAutoconfigResult *result)
|
||||
{
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
g_clear_pointer (&result->user, g_free);
|
||||
g_clear_pointer (&result->host, g_free);
|
||||
g_clear_pointer (&result->auth_mechanism, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
mail_autoconfig_parse_start_element (GMarkupParseContext *context,
|
||||
@ -167,6 +185,16 @@ mail_autoconfig_parse_start_element (GMarkupParseContext *context,
|
||||
closure->result = &priv->pop3_result;
|
||||
if (g_strcmp0 (type, "smtp") == 0)
|
||||
closure->result = &priv->smtp_result;
|
||||
|
||||
if (type != NULL && closure->result == NULL) {
|
||||
g_return_if_fail (closure->current_type == NULL);
|
||||
g_return_if_fail (closure->custom_params == NULL);
|
||||
|
||||
closure->current_type = g_strdup (type);
|
||||
closure->custom_params = e_named_parameters_new ();
|
||||
|
||||
e_named_parameters_set (closure->custom_params, "kind", element_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,8 +211,22 @@ mail_autoconfig_parse_end_element (GMarkupParseContext *context,
|
||||
is_incoming_server = g_str_equal (element_name, "incomingServer");
|
||||
is_outgoing_server = g_str_equal (element_name, "outgoingServer");
|
||||
|
||||
if (is_incoming_server || is_outgoing_server)
|
||||
if (is_incoming_server || is_outgoing_server) {
|
||||
if (closure->custom_params && e_named_parameters_count (closure->custom_params) > 1) {
|
||||
if (!closure->autoconfig->priv->custom_types)
|
||||
closure->autoconfig->priv->custom_types =
|
||||
g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) e_named_parameters_free);
|
||||
|
||||
g_hash_table_insert (closure->autoconfig->priv->custom_types, closure->current_type, closure->custom_params);
|
||||
|
||||
closure->current_type = NULL;
|
||||
closure->custom_params = NULL;
|
||||
}
|
||||
|
||||
g_clear_pointer (&closure->current_type, g_free);
|
||||
g_clear_pointer (&closure->custom_params, e_named_parameters_free);
|
||||
closure->result = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns NULL when not being there */
|
||||
@ -239,7 +281,7 @@ mail_autoconfig_parse_text (GMarkupParseContext *context,
|
||||
|
||||
priv = closure->autoconfig->priv;
|
||||
|
||||
if (closure->result == NULL)
|
||||
if (closure->result == NULL && closure->custom_params == NULL)
|
||||
return;
|
||||
|
||||
to_free = mail_autoconfig_replace_case_insensitive (in_text, FAKE_EVOLUTION_USER_STRING, priv->email_local_part);
|
||||
@ -300,35 +342,58 @@ mail_autoconfig_parse_text (GMarkupParseContext *context,
|
||||
element_name = g_markup_parse_context_get_element (context);
|
||||
|
||||
if (g_str_equal (element_name, "hostname")) {
|
||||
closure->result->host = g_strdup (string->str);
|
||||
closure->result->set = TRUE;
|
||||
if (closure->custom_params) {
|
||||
e_named_parameters_set (closure->custom_params, "host", string->str);
|
||||
} else {
|
||||
closure->result->host = g_strdup (string->str);
|
||||
closure->result->set = TRUE;
|
||||
}
|
||||
|
||||
} else if (g_str_equal (element_name, "username")) {
|
||||
closure->result->user = g_strdup (string->str);
|
||||
closure->result->set = TRUE;
|
||||
if (closure->custom_params) {
|
||||
e_named_parameters_set (closure->custom_params, "user", string->str);
|
||||
} else {
|
||||
closure->result->user = g_strdup (string->str);
|
||||
closure->result->set = TRUE;
|
||||
}
|
||||
|
||||
} else if (g_str_equal (element_name, "port")) {
|
||||
glong port = strtol (string->str, NULL, 10);
|
||||
if (port == CLAMP (port, 1, G_MAXUINT16)) {
|
||||
closure->result->port = (guint16) port;
|
||||
closure->result->set = TRUE;
|
||||
if (closure->custom_params) {
|
||||
e_named_parameters_set (closure->custom_params, "port", string->str);
|
||||
} else {
|
||||
glong port = strtol (string->str, NULL, 10);
|
||||
if (port == CLAMP (port, 1, G_MAXUINT16)) {
|
||||
closure->result->port = (guint16) port;
|
||||
closure->result->set = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (g_str_equal (element_name, "socketType")) {
|
||||
CamelNetworkSecurityMethod security_method = CAMEL_NETWORK_SECURITY_METHOD_NONE;
|
||||
gboolean set = FALSE;
|
||||
|
||||
if (g_str_equal (string->str, "plain")) {
|
||||
closure->result->security_method =
|
||||
CAMEL_NETWORK_SECURITY_METHOD_NONE;
|
||||
closure->result->set = TRUE;
|
||||
security_method = CAMEL_NETWORK_SECURITY_METHOD_NONE;
|
||||
set = TRUE;
|
||||
} else if (g_str_equal (string->str, "SSL")) {
|
||||
closure->result->security_method =
|
||||
CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT;
|
||||
closure->result->set = TRUE;
|
||||
security_method = CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT;
|
||||
set = TRUE;
|
||||
} else if (g_str_equal (string->str, "STARTTLS")) {
|
||||
closure->result->security_method =
|
||||
CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT;
|
||||
closure->result->set = TRUE;
|
||||
security_method = CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT;
|
||||
set = TRUE;
|
||||
}
|
||||
|
||||
if (set) {
|
||||
if (closure->custom_params) {
|
||||
const gchar *enum_str = e_enum_to_string (CAMEL_TYPE_NETWORK_SECURITY_METHOD, security_method);
|
||||
g_warn_if_fail (enum_str != NULL);
|
||||
if (enum_str)
|
||||
e_named_parameters_set (closure->custom_params, "security-method", enum_str);
|
||||
} else {
|
||||
closure->result->set = set;
|
||||
closure->result->security_method = security_method;
|
||||
}
|
||||
}
|
||||
} else if (g_str_equal (element_name, "authentication")) {
|
||||
gboolean use_plain_auth = FALSE;
|
||||
|
||||
@ -358,20 +423,30 @@ mail_autoconfig_parse_text (GMarkupParseContext *context,
|
||||
if (closure->result == &priv->smtp_result)
|
||||
auth_mechanism = g_strdup ("LOGIN");
|
||||
|
||||
closure->result->auth_mechanism = auth_mechanism;
|
||||
closure->result->set = TRUE;
|
||||
}
|
||||
|
||||
/* "password-encrypted" apparently maps to CRAM-MD5,
|
||||
* or at least that's how Thunderbird interprets it. */
|
||||
|
||||
if (g_str_equal (string->str, "password-encrypted")) {
|
||||
closure->result->auth_mechanism = g_strdup ("CRAM-MD5");
|
||||
closure->result->set = TRUE;
|
||||
if (closure->custom_params) {
|
||||
e_named_parameters_set (closure->custom_params, "auth-mechanism", auth_mechanism);
|
||||
g_free (auth_mechanism);
|
||||
} else {
|
||||
closure->result->auth_mechanism = auth_mechanism;
|
||||
closure->result->set = TRUE;
|
||||
}
|
||||
} else if (g_str_equal (string->str, "password-encrypted")) {
|
||||
/* "password-encrypted" apparently maps to CRAM-MD5,
|
||||
* or at least that's how Thunderbird interprets it. */
|
||||
if (closure->custom_params) {
|
||||
e_named_parameters_set (closure->custom_params, "auth-mechanism", "CRAM-MD5");
|
||||
} else {
|
||||
closure->result->auth_mechanism = g_strdup ("CRAM-MD5");
|
||||
closure->result->set = TRUE;
|
||||
}
|
||||
} else if (closure->custom_params) {
|
||||
e_named_parameters_set (closure->custom_params, "auth-mechanism", string->str);
|
||||
}
|
||||
|
||||
/* XXX Other <authentication> values not handled,
|
||||
* but they are corner cases for the most part. */
|
||||
} else if (closure->custom_params) {
|
||||
e_named_parameters_set (closure->custom_params, element_name, string->str);
|
||||
}
|
||||
|
||||
g_string_free (string, TRUE);
|
||||
@ -451,6 +526,8 @@ mail_autoconfig_lookup_uri_sync (EMailAutoconfig *autoconfig,
|
||||
|
||||
closure.autoconfig = autoconfig;
|
||||
closure.result = NULL;
|
||||
closure.current_type = NULL;
|
||||
closure.custom_params = NULL;
|
||||
|
||||
context = g_markup_parse_context_new (
|
||||
&mail_autoconfig_parser, 0,
|
||||
@ -465,6 +542,9 @@ mail_autoconfig_lookup_uri_sync (EMailAutoconfig *autoconfig,
|
||||
if (success)
|
||||
success = g_markup_parse_context_end_parse (context, error);
|
||||
|
||||
g_clear_pointer (&closure.custom_params, e_named_parameters_free);
|
||||
g_clear_pointer (&closure.current_type, g_free);
|
||||
|
||||
g_markup_parse_context_free (context);
|
||||
} else {
|
||||
g_set_error_literal (
|
||||
@ -671,9 +751,7 @@ mail_config_lookup_result_finalize (GObject *object)
|
||||
{
|
||||
EMailConfigLookupResult *mail_result = E_MAIL_CONFIG_LOOKUP_RESULT (object);
|
||||
|
||||
g_free (mail_result->result.user);
|
||||
g_free (mail_result->result.host);
|
||||
g_free (mail_result->result.auth_mechanism);
|
||||
e_mail_config_result_clear (&mail_result->result);
|
||||
g_free (mail_result->extension_name);
|
||||
|
||||
/* Chain up to parent's method. */
|
||||
@ -900,6 +978,15 @@ mail_autoconfig_get_property (GObject *object,
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
mail_autoconfig_constructed (GObject *object)
|
||||
{
|
||||
/* Chain up to parent's method. */
|
||||
G_OBJECT_CLASS (e_mail_autoconfig_parent_class)->constructed (object);
|
||||
|
||||
e_extensible_load_extensions (E_EXTENSIBLE (object));
|
||||
}
|
||||
|
||||
static void
|
||||
mail_autoconfig_dispose (GObject *object)
|
||||
{
|
||||
@ -925,15 +1012,9 @@ mail_autoconfig_finalize (GObject *object)
|
||||
g_free (priv->email_domain_part);
|
||||
g_free (priv->use_domain);
|
||||
|
||||
g_free (priv->imap_result.user);
|
||||
g_free (priv->imap_result.host);
|
||||
g_free (priv->imap_result.auth_mechanism);
|
||||
g_free (priv->pop3_result.user);
|
||||
g_free (priv->pop3_result.host);
|
||||
g_free (priv->pop3_result.auth_mechanism);
|
||||
g_free (priv->smtp_result.user);
|
||||
g_free (priv->smtp_result.host);
|
||||
g_free (priv->smtp_result.auth_mechanism);
|
||||
e_mail_config_result_clear (&priv->imap_result);
|
||||
e_mail_config_result_clear (&priv->pop3_result);
|
||||
e_mail_config_result_clear (&priv->smtp_result);
|
||||
|
||||
/* Chain up to parent's finalize() method. */
|
||||
G_OBJECT_CLASS (e_mail_autoconfig_parent_class)->finalize (object);
|
||||
@ -1058,6 +1139,7 @@ e_mail_autoconfig_class_init (EMailAutoconfigClass *class)
|
||||
object_class = G_OBJECT_CLASS (class);
|
||||
object_class->set_property = mail_autoconfig_set_property;
|
||||
object_class->get_property = mail_autoconfig_get_property;
|
||||
object_class->constructed = mail_autoconfig_constructed;
|
||||
object_class->dispose = mail_autoconfig_dispose;
|
||||
object_class->finalize = mail_autoconfig_finalize;
|
||||
|
||||
@ -1096,6 +1178,15 @@ e_mail_autoconfig_class_init (EMailAutoconfigClass *class)
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
signals[PROCESS_CUSTOM_TYPES] = g_signal_new (
|
||||
"process-custom-types",
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 2,
|
||||
E_TYPE_CONFIG_LOOKUP,
|
||||
G_TYPE_HASH_TABLE);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1334,4 +1425,9 @@ e_mail_autoconfig_copy_results_to_config_lookup (EMailAutoconfig *mail_autoconfi
|
||||
"smtp",
|
||||
_("SMTP server"),
|
||||
E_SOURCE_EXTENSION_MAIL_TRANSPORT);
|
||||
|
||||
if (mail_autoconfig->priv->custom_types) {
|
||||
g_signal_emit (mail_autoconfig, signals[PROCESS_CUSTOM_TYPES], 0,
|
||||
config_lookup, mail_autoconfig->priv->custom_types);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user