/* sunone-account.c * * Copyright (C) 2002-2004 Sun Microsystems, Inc * * AUTHORS * Jack Jia * Harry Lu * Alfred Peng * Jedy Wang * Rodrigo Moya * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include "sunone-util.h" #include "sunone-account.h" #include "sunone-component.h" struct _SunOneAccountPrivate { char *name; char *uid; char *server; char *protocol; char *user; char *password; char *id_email; char *proxy; int poll_interval; gboolean save_password; gboolean dont_ask_password; gboolean account_online; gboolean connecting; SunOneConnection *cnc; }; static void sunone_account_dispose (GObject *object); static void sunone_account_finalize (GObject *object); static SunOneConnection * sunone_account_connect (SunOneAccount *account); #define DEFAULT_POLL_INTERVAL 30 static GObjectClass *parent_class = NULL; G_DEFINE_TYPE (SunOneAccount, sunone_account, G_TYPE_OBJECT) static void sunone_account_class_init (SunOneAccountClass *klass) { GObjectClass *object_class = (GObjectClass *) klass; parent_class = g_type_class_ref (G_TYPE_OBJECT); object_class->dispose = sunone_account_dispose; object_class->finalize = sunone_account_finalize; } static void sunone_account_init (SunOneAccount *object) { SunOneAccount *account = SUNONE_ACCOUNT (object); SunOneAccountPrivate *priv = account->priv; account->priv = g_new0 (SunOneAccountPrivate, 1); priv = account->priv; /* initialize private members */ priv->poll_interval = DEFAULT_POLL_INTERVAL; priv->account_online = TRUE; priv->connecting = FALSE; } static void sunone_account_dispose (GObject *object) { SunOneAccount *account = SUNONE_ACCOUNT (object); SunOneAccountPrivate *priv = account->priv; g_return_if_fail (IS_SUNONE_ACCOUNT (account)); if (priv) { if (priv->name) { g_free (priv->name); priv->name = NULL; } if (priv->uid) { g_free (priv->uid); priv->uid = NULL; } if (priv->server) { g_free (priv->server); priv->server = NULL; } if (priv->protocol) { g_free (priv->protocol); priv->protocol = NULL; } if (priv->user) { g_free (priv->user); priv->user = NULL; } if (priv->password) { g_free (priv->password); priv->password = NULL; } if (priv->id_email) { g_free (priv->id_email); priv->id_email = NULL; } if (priv->proxy) { g_free (priv->proxy); priv->proxy = NULL; } if (priv->cnc) { g_object_unref (priv->cnc); priv->cnc = NULL; } g_free (priv); account->priv = NULL; } if (G_OBJECT_CLASS (parent_class)->dispose) (* G_OBJECT_CLASS (parent_class)->dispose) (object); } static void sunone_account_finalize (GObject *object) { if (G_OBJECT_CLASS (parent_class)->finalize) (* G_OBJECT_CLASS (parent_class)->finalize) (object); } gboolean sunone_account_get_dont_ask_password (SunOneAccount *account) { SunOneAccountPrivate *priv = account->priv; g_return_val_if_fail (IS_SUNONE_ACCOUNT (account), FALSE); return priv->dont_ask_password; } void sunone_account_set_dont_ask_password (SunOneAccount *account, gboolean dont_ask_password) { SunOneAccountPrivate *priv = account->priv; g_return_if_fail (IS_SUNONE_ACCOUNT (account)); priv->dont_ask_password = dont_ask_password; } const char * sunone_account_get_email (SunOneAccount *account) { SunOneAccountPrivate *priv = account->priv; g_return_val_if_fail (IS_SUNONE_ACCOUNT (account), NULL); return (const char *) priv->id_email; } void sunone_account_set_email (SunOneAccount *account, const char *id_email) { SunOneAccountPrivate *priv = account->priv; g_return_if_fail (IS_SUNONE_ACCOUNT (account)); if (priv->id_email) g_free (priv->id_email); priv->id_email = g_strdup (id_email); } const char * sunone_account_get_name (SunOneAccount *account) { SunOneAccountPrivate *priv = account->priv; g_return_val_if_fail (IS_SUNONE_ACCOUNT (account), NULL); return (const char *) priv->name; } void sunone_account_set_name (SunOneAccount *account, const char *name) { SunOneAccountPrivate *priv = account->priv; g_return_if_fail (IS_SUNONE_ACCOUNT (account)); if (priv->name) g_free (priv->name); priv->name = g_strdup (name); } const char * sunone_account_get_uid (SunOneAccount *account) { g_return_val_if_fail (IS_SUNONE_ACCOUNT (account), NULL); return (const char *) account->priv->uid; } void sunone_account_set_uid (SunOneAccount *account, const char *uid) { g_return_if_fail (IS_SUNONE_ACCOUNT (account)); if (account->priv->uid) g_free (account->priv->uid); account->priv->uid = g_strdup (uid); } const char * sunone_account_get_server (SunOneAccount *account) { SunOneAccountPrivate *priv = account->priv; g_return_val_if_fail (IS_SUNONE_ACCOUNT (account), NULL); return (const char *) priv->server; } void sunone_account_set_server (SunOneAccount *account, const char *server) { SunOneAccountPrivate *priv = account->priv; g_return_if_fail (IS_SUNONE_ACCOUNT (account)); if (priv->server) g_free (priv->server); #ifdef ENABLE_IDN priv->server = sunone_util_get_encoded_server_port_name (server); #else priv->server = g_strdup (server); #endif } const char * sunone_account_get_protocol (SunOneAccount *account) { SunOneAccountPrivate *priv = account->priv; g_return_val_if_fail (IS_SUNONE_ACCOUNT (account), NULL); return (const char *) priv->protocol; } void sunone_account_set_protocol (SunOneAccount *account, const char *protocol) { SunOneAccountPrivate *priv = account->priv; g_return_if_fail (IS_SUNONE_ACCOUNT (account)); if (priv->protocol) g_free (priv->protocol); priv->protocol = g_strdup (protocol); } const char * sunone_account_get_user (SunOneAccount *account) { SunOneAccountPrivate *priv = account->priv; g_return_val_if_fail (IS_SUNONE_ACCOUNT (account), NULL); return (const char *) priv->user; } void sunone_account_set_user (SunOneAccount *account, const char *user) { SunOneAccountPrivate *priv = account->priv; g_return_if_fail (IS_SUNONE_ACCOUNT (account)); if (priv->user) g_free (priv->user); priv->user = g_strdup (user); } int sunone_account_get_poll_interval (SunOneAccount *account) { SunOneAccountPrivate *priv = account->priv; g_return_val_if_fail (IS_SUNONE_ACCOUNT (account), DEFAULT_POLL_INTERVAL); return priv->poll_interval; } void sunone_account_set_poll_interval (SunOneAccount *account, int poll_interval) { SunOneAccountPrivate *priv = account->priv; g_return_if_fail (IS_SUNONE_ACCOUNT (account)); priv->poll_interval = poll_interval; } const char * sunone_account_get_password (SunOneAccount *account, gboolean is_interactive, const char *prompt) { SunOneAccountPrivate *priv = account->priv; g_return_val_if_fail (IS_SUNONE_ACCOUNT (account), NULL); if (!priv->password) { gboolean remember; char *password; char *key = g_strdup_printf ("wcap://%s@%s", priv->user, priv->server); password = e_passwords_get_password ("Evolution-jescs", key); if (password) { priv->password = g_strdup (password); g_free (password); } else if (is_interactive) { if (priv->dont_ask_password) { g_free (key); return NULL; } if (priv->password) { g_free (key); return (const char *) priv->password; } remember = priv->save_password; priv->password = e_passwords_ask_password ( _("Enter password"), "Evolution-jescs", key, prompt, E_PASSWORDS_REMEMBER_FOREVER | E_PASSWORDS_SECRET, &remember, NULL); if (priv->password == NULL) { /*user canceled the dialog*/ priv->dont_ask_password = TRUE; } sunone_account_set_save_password (account, remember); } g_free (key); } return (const char *) priv->password; } void sunone_account_set_password (SunOneAccount *account, const char *password) { SunOneAccountPrivate *priv = account->priv; g_return_if_fail (IS_SUNONE_ACCOUNT (account)); if (priv->password) g_free (priv->password); priv->password = g_strdup (password); } gboolean sunone_account_get_save_password (SunOneAccount *account) { SunOneAccountPrivate *priv = account->priv; g_return_val_if_fail (IS_SUNONE_ACCOUNT (account), FALSE); return priv->save_password; } void sunone_account_set_save_password (SunOneAccount *account, gboolean save) { SunOneAccountPrivate *priv = account->priv; g_return_if_fail (IS_SUNONE_ACCOUNT (account)); priv->save_password = save; } void sunone_account_forget_password (SunOneAccount *account) { gchar *key; SunOneAccountPrivate *priv = account->priv; g_return_if_fail (IS_SUNONE_ACCOUNT (account)); key = g_strdup_printf ("wcap://%s@%s", priv->user, priv->server); e_passwords_forget_password ("Evolution-jescs", key); g_free (key); if (priv->password) { g_free (priv->password); priv->password = NULL; } } void sunone_account_set_proxy (SunOneAccount *account, const char *proxy) { g_return_if_fail (IS_SUNONE_ACCOUNT (account)); if (account->priv->proxy) g_free (account->priv->proxy); account->priv->proxy = g_strdup (proxy); } const char * sunone_account_get_proxy (SunOneAccount *account) { SunOneAccountPrivate *priv = account->priv; g_return_val_if_fail (IS_SUNONE_ACCOUNT (account), NULL); return (const char *) priv->proxy; } static char * get_proxy_url () { GConfClient *conf_client; char *proxy_uri = NULL; conf_client = gconf_client_get_default (); if (gconf_client_get_bool (conf_client, "/system/http_proxy/use_http_proxy", NULL)) { char *server; int port; server = gconf_client_get_string (conf_client, "/system/http_proxy/host", NULL); port = gconf_client_get_int (conf_client, "/system/http_proxy/port", NULL); if (server && server[0]) { if (gconf_client_get_bool (conf_client, "/system/http_proxy/use_authentication", NULL)) { char *user, *password; user = gconf_client_get_string (conf_client, "/system/http_proxy/authentication_user", NULL); password = gconf_client_get_string (conf_client, "/system/http_proxy/authentication_password", NULL); proxy_uri = g_strdup_printf("http://%s:%s@%s:%d", user, password, server, port); g_free (user); g_free (password); } else proxy_uri = g_strdup_printf ("http://%s:%d", server, port); g_free (server); } } g_object_unref (conf_client); return proxy_uri; } SunOneAccount * sunone_account_new (EAccountList *account_list, EAccount *edata) { SunOneAccount *sunone_account; SunOneAccountPrivate *priv; const char *use_proxy; char *new_url; int port; CamelURL *url; CamelURL *server_url; url = camel_url_new (edata->source->url, NULL); if (!url) { g_warning ("Could not parse sunone uri '%s'", edata->source->url); return NULL; } new_url = g_strdup (camel_url_get_param (url, "serverurl")); if (!new_url) { /*we have no new url, so convert from old settings*/ const char * use_ssl = camel_url_get_param (url, "use_ssl"); if (use_ssl && !strcmp (use_ssl, "always")) new_url = g_strdup_printf ("https://%s:%d", url->host ? url->host : "", url->port); else new_url = g_strdup_printf ("http://%s:%d", url->host ? url->host : "", url->port); } else if (strncasecmp (new_url, "http", 4) && strncasecmp (new_url, "https", 5)){ char *tmp_url; tmp_url = g_strconcat ("http://", new_url, NULL); g_free (new_url); new_url = tmp_url; } server_url = camel_url_new (new_url, NULL); g_free (new_url); if (!server_url) { g_warning ("Could not parse sunone uri '%s'", edata->source->url); return NULL; } sunone_account = g_object_new (SUNONE_ACCOUNT_TYPE, NULL); priv = sunone_account->priv; priv->name = g_strdup (edata->name); priv->uid = g_strdup (edata->uid); priv->user = g_strdup (url->user); priv->id_email = g_strdup (edata->id->address); port = server_url->port; if (!strcmp (server_url->protocol, "https")) { priv->protocol = g_strdup ("https"); if (port == 0) port = 443; } else { priv->protocol = g_strdup ("http"); if (port == 0) port = 80; } priv->server = g_strdup_printf ("%s:%d", server_url->host ? server_url->host : "", port); use_proxy = camel_url_get_param (url, "useproxy"); if (use_proxy) priv->proxy = get_proxy_url (); if (edata->source->auto_check) priv->poll_interval = edata->source->auto_check_time; camel_url_free (server_url); camel_url_free (url); return sunone_account; } gboolean sunone_account_set_offline (SunOneAccount *account) { SunOneAccountPrivate *priv; g_return_val_if_fail (account != NULL, FALSE); g_return_val_if_fail (IS_SUNONE_ACCOUNT (account), FALSE); priv = account->priv; if (priv->cnc) { g_object_unref (priv->cnc); priv->cnc = NULL; } priv->account_online = FALSE; return TRUE; } gboolean sunone_account_set_online (SunOneAccount *account) { SunOneAccountPrivate *priv = account->priv; g_return_val_if_fail (IS_SUNONE_ACCOUNT (account), FALSE); if (!priv->account_online) { if (sunone_account_get_connection (account)) return TRUE; else return FALSE; } else { return TRUE; } } void sunone_account_is_offline (SunOneAccount *account, int *state) { g_return_if_fail (IS_SUNONE_ACCOUNT (account)); sunone_component_is_offline (global_sunone_component, state); } SunOneConnection * sunone_account_get_connection (SunOneAccount *account) { SunOneAccountPrivate *priv = account->priv; static GStaticMutex mutex = G_STATIC_MUTEX_INIT; g_return_val_if_fail (IS_SUNONE_ACCOUNT (account), NULL); if (!priv->cnc) { g_static_mutex_lock (&mutex); priv->cnc = sunone_account_connect (account); g_static_mutex_unlock (&mutex); } return priv->cnc; } void sunone_account_set_connecting (SunOneAccount *account, gboolean status) { g_return_if_fail (IS_SUNONE_ACCOUNT (account)); account->priv->connecting = status; } gboolean sunone_account_is_connecting (SunOneAccount *account) { g_return_val_if_fail (IS_SUNONE_ACCOUNT (account), FALSE); return account->priv->connecting; } static SunOneConnection * sunone_account_connect (SunOneAccount *account) { SunOneAccountPrivate *priv = account->priv; SunOneConnection *so_cnc; const char *password; #ifdef ENABLE_IDN const char *t; #endif char *full_uri; char *prompt; char *hname; guint error_code; int state; g_return_val_if_fail (IS_SUNONE_ACCOUNT (account), NULL); sunone_account_is_offline (account, &state); if (state == OFFLINE_MODE) { e_notice (NULL, GTK_MESSAGE_ERROR, _("Sun JESCS Account is offline")); return NULL; } /*try to connect to calendar server unless user canceled password dialog*/ #ifdef ENABLE_IDN t = sunone_account_get_server (account); hname = sunone_util_get_decoded_server_port_name (t); #else hname = g_strdup (sunone_account_get_server (account)); #endif prompt = g_strdup_printf (_("Please enter the password for %s@%s"), sunone_account_get_user (account), hname); do { password = sunone_account_get_password (account, TRUE, prompt); g_free (prompt); if (!password) { /*password dialog is canceled*/ g_free (hname); return NULL; } full_uri = g_strdup_printf ("%s://%s", sunone_account_get_protocol (account), sunone_account_get_server (account)); so_cnc = sunone_connection_new (full_uri, sunone_account_get_proxy (account), sunone_account_get_user (account), password); g_free (full_uri); error_code = sunone_connection_login (so_cnc); if (SUNONE_ERROR_IS_SUCCESSFUL (error_code)) break; sunone_account_forget_password (account); g_object_unref (G_OBJECT (so_cnc)); prompt = g_strdup_printf (_("Unable to authenticate to WCAP server.\n" "Wrong password or could not connect to server.\n" "Please enter the password for %s@%s\n" "or click Cancel button to cancel"), sunone_account_get_user (account), hname); } while (1); g_free (hname); error_code = sunone_connection_version (so_cnc); if (!SUNONE_ERROR_IS_SUCCESSFUL (error_code)) { /* do nothing for now */ } priv->cnc = so_cnc; priv->account_online = TRUE; return so_cnc; } char * sunone_account_get_physical_uri (SunOneAccount *account, const char *calid, const char *type) { return g_strdup_printf ("wcap://%s@%s/?protocol=%s&uid=%s&calid=%s&type=%s", sunone_account_get_user (account), sunone_account_get_server (account), sunone_account_get_protocol (account), sunone_account_get_uid (account), calid, type); }