Ejemplo n.º 1
0
/* Dispose handler for the file backend */
static void
e_cal_backend_http_dispose (GObject *object)
{
	ECalBackendHttp *cbhttp;
	ECalBackendHttpPrivate *priv;

	cbhttp = E_CAL_BACKEND_HTTP (object);
	priv = cbhttp->priv;

	if (priv->reload_timeout_id) {
		ESource *source = e_backend_get_source (E_BACKEND (cbhttp));
		e_source_refresh_remove_timeout (source, priv->reload_timeout_id);
		priv->reload_timeout_id = 0;
	}

	if (priv->soup_session) {
		soup_session_abort (priv->soup_session);
		g_object_unref (priv->soup_session);
		priv->soup_session = NULL;
	}
	if (priv->source_changed_id) {
		g_signal_handler_disconnect (
			e_backend_get_source (E_BACKEND (cbhttp)),
			priv->source_changed_id);
		priv->source_changed_id = 0;
	}

	/* Chain up to parent's dispose() method. */
	G_OBJECT_CLASS (e_cal_backend_http_parent_class)->dispose (object);
}
static void
ebbm_contacts_open (EBookBackendMAPI *ebma, GCancellable *cancellable, gboolean only_if_exists, GError **perror)
{
	ESource *source = e_backend_get_source (E_BACKEND (ebma));
	ESourceMapiFolder *ext_mapi_folder;
	EBookBackendMAPIContactsPrivate *priv = ((EBookBackendMAPIContacts *) ebma)->priv;
	GError *err = NULL;

	if (e_book_backend_is_opened (E_BOOK_BACKEND (ebma))) {
		if (E_BOOK_BACKEND_MAPI_CLASS (e_book_backend_mapi_contacts_parent_class)->op_open)
			E_BOOK_BACKEND_MAPI_CLASS (e_book_backend_mapi_contacts_parent_class)->op_open (ebma, cancellable, only_if_exists, perror);
		return;
	}

	ext_mapi_folder = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);

	priv->fid = e_source_mapi_folder_get_id (ext_mapi_folder);
	priv->is_public_folder = e_source_mapi_folder_is_public (ext_mapi_folder);
	priv->foreign_username = e_source_mapi_folder_dup_foreign_username (ext_mapi_folder);

	if (priv->foreign_username && !*priv->foreign_username) {
		g_free (priv->foreign_username);
		priv->foreign_username = NULL;
	}

	/* Chain up to parent's op_load_source() method. */
	if (E_BOOK_BACKEND_MAPI_CLASS (e_book_backend_mapi_contacts_parent_class)->op_open)
		E_BOOK_BACKEND_MAPI_CLASS (e_book_backend_mapi_contacts_parent_class)->op_open (ebma, cancellable, only_if_exists, &err);

	if (err)
		g_propagate_error (perror, err);
}
Ejemplo n.º 3
0
/** Load calendar name, owner and permission from the ESource.
 *
 * @param cb 3e calendar backend.
 *
 * @return TRUE on success, FALSE otherwise.
 */
gboolean e_cal_backend_3e_calendar_info_load(ECalBackend3e *cb)
{
    ESource *source;
    const char *immediate_sync;

    source = e_backend_get_source(E_BACKEND(cb));
    immediate_sync = e_source_get_property(source, "eee-immediate-sync");

    g_free(cb->priv->calname);
    g_free(cb->priv->owner);
    g_free(cb->priv->perm);
    cb->priv->calname = g_strdup(e_source_get_property(source, "eee-calname"));
    cb->priv->owner = g_strdup(e_source_get_property(source, "eee-owner"));
    cb->priv->perm = g_strdup(e_source_get_property(source, "eee-perm"));
    cb->priv->sync_immediately = (immediate_sync == NULL || !g_strcmp0(immediate_sync, "1"));

    g_free(cb->priv->calspec);
    cb->priv->calspec = g_strdup_printf("%s:%s", cb->priv->owner, cb->priv->calname);

    if (cb->priv->calname == NULL || cb->priv->owner == NULL)
    {
        return FALSE;
    }

    return TRUE;
}
Ejemplo n.º 4
0
static const gchar *
cal_backend_http_ensure_uri (ECalBackendHttp *backend)
{
	ESource *source;
	ESourceSecurity *security_extension;
	ESourceWebdav *webdav_extension;
	SoupURI *soup_uri;
	gboolean secure_connection;
	const gchar *extension_name;
	gchar *uri_string;

	if (backend->priv->uri != NULL)
		return backend->priv->uri;

	source = e_backend_get_source (E_BACKEND (backend));

	extension_name = E_SOURCE_EXTENSION_SECURITY;
	security_extension = e_source_get_extension (source, extension_name);

	extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND;
	webdav_extension = e_source_get_extension (source, extension_name);

	secure_connection = e_source_security_get_secure (security_extension);

	soup_uri = e_source_webdav_dup_soup_uri (webdav_extension);
	uri_string = soup_uri_to_string (soup_uri, FALSE);
	soup_uri_free (soup_uri);

	backend->priv->uri = webcal_to_http_method (
		uri_string, secure_connection);

	g_free (uri_string);

	return backend->priv->uri;
}
static ESourceAuthenticationResult
book_backend_webdav_try_password_sync (ESourceAuthenticator *authenticator,
                                       const GString *password,
                                       GCancellable *cancellable,
                                       GError **error)
{
	EBookBackendWebdav *webdav = E_BOOK_BACKEND_WEBDAV (authenticator);
	ESourceAuthentication *auth_extension;
	ESourceAuthenticationResult result;
	ESource *source;
	SoupMessage *message;
	const gchar *extension_name;

	source = e_backend_get_source (E_BACKEND (authenticator));
	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
	auth_extension = e_source_get_extension (source, extension_name);

	webdav->priv->username =
		e_source_authentication_dup_user (auth_extension);
	webdav->priv->password = g_strdup (password->str);

	/* Send a PROPFIND to test whether user/password is correct. */
	message = send_propfind (webdav, cancellable);

	switch (message->status_code) {
		case SOUP_STATUS_OK:
		case SOUP_STATUS_MULTI_STATUS:
			result = E_SOURCE_AUTHENTICATION_ACCEPTED;
			break;

		case SOUP_STATUS_UNAUTHORIZED:
		case SOUP_STATUS_PROXY_UNAUTHORIZED:  /* XXX really? */
			g_free (webdav->priv->username);
			webdav->priv->username = NULL;
			g_free (webdav->priv->password);
			webdav->priv->password = NULL;
			result = E_SOURCE_AUTHENTICATION_REJECTED;
			break;

		default:
			g_set_error (
				error, SOUP_HTTP_ERROR,
				message->status_code,
				"%s", message->reason_phrase);
			result = E_SOURCE_AUTHENTICATION_ERROR;
			break;
	}

	g_object_unref (message);

	return result;
}
static void
outlook_backend_child_added (ECollectionBackend *backend,
                             ESource *child_source)
{
	ESource *collection_source;
	const gchar *extension_name;
	gboolean is_mail = FALSE;

	collection_source = e_backend_get_source (E_BACKEND (backend));

	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
	is_mail |= e_source_has_extension (child_source, extension_name);

	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
	is_mail |= e_source_has_extension (child_source, extension_name);

	extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
	is_mail |= e_source_has_extension (child_source, extension_name);

	/* Synchronize mail-related user with the collection identity. */
	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
	if (is_mail && e_source_has_extension (child_source, extension_name)) {
		ESourceAuthentication *auth_child_extension;
		ESourceCollection *collection_extension;
		const gchar *collection_identity;
		const gchar *auth_child_user;

		extension_name = E_SOURCE_EXTENSION_COLLECTION;
		collection_extension = e_source_get_extension (
			collection_source, extension_name);
		collection_identity = e_source_collection_get_identity (
			collection_extension);

		extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
		auth_child_extension = e_source_get_extension (
			child_source, extension_name);
		auth_child_user = e_source_authentication_get_user (
			auth_child_extension);

		/* XXX Do not override an existing user name setting.
		 *     The IMAP or (especially) SMTP configuration may
		 *     have been modified to use a non-Outlook server. */
		if (auth_child_user == NULL)
			e_source_authentication_set_user (
				auth_child_extension,
				collection_identity);
	}

	/* Chain up to parent's child_added() method. */
	E_COLLECTION_BACKEND_CLASS (e_outlook_backend_parent_class)->
		child_added (backend, child_source);
}
static void
google_backend_add_tasks (ECollectionBackend *backend)
{
	ESource *source;
	ESource *collection_source;
	ESourceRegistryServer *server;
	ESourceExtension *extension;
	ESourceCollection *collection_extension;
	const gchar *backend_name;
	const gchar *extension_name;
	const gchar *resource_id;

	collection_source = e_backend_get_source (E_BACKEND (backend));

	resource_id = GOOGLE_TASKS_RESOURCE_ID;
	source = e_collection_backend_new_child (backend, resource_id);
	e_source_set_display_name (source, _("Tasks"));

	collection_extension = e_source_get_extension (
		collection_source, E_SOURCE_EXTENSION_COLLECTION);

	/* Configure the tasks source. */

	backend_name = GOOGLE_TASKS_BACKEND_NAME;

	extension_name = E_SOURCE_EXTENSION_TASK_LIST;
	extension = e_source_get_extension (source, extension_name);

	e_source_backend_set_backend_name (
		E_SOURCE_BACKEND (extension), backend_name);

	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
	extension = e_source_get_extension (source, extension_name);

	g_object_bind_property (
		collection_extension, "identity",
		extension, "user",
		G_BINDING_SYNC_CREATE);

	extension_name = E_SOURCE_EXTENSION_SECURITY;
	extension = e_source_get_extension (source, extension_name);

	e_source_security_set_secure (
		E_SOURCE_SECURITY (extension), TRUE);

	server = e_collection_backend_ref_server (backend);
	e_source_registry_server_add_source (server, source);
	g_object_unref (server);

	g_object_unref (source);
}
Ejemplo n.º 8
0
static ESourceAuthenticationResult
e_cal_backend_http_authenticate_sync (EBackend *backend,
				      const ENamedParameters *credentials,
				      gchar **out_certificate_pem,
				      GTlsCertificateFlags *out_certificate_errors,
				      GCancellable *cancellable,
				      GError **error)
{
	ECalBackendHttp *cbhttp;
	ESourceAuthenticationResult result;
	const gchar *uri, *username;
	GError *local_error = NULL;

	cbhttp = E_CAL_BACKEND_HTTP (backend);

	g_free (cbhttp->priv->username);
	cbhttp->priv->username = NULL;

	g_free (cbhttp->priv->password);
	cbhttp->priv->password = g_strdup (e_named_parameters_get (credentials, E_SOURCE_CREDENTIAL_PASSWORD));

	username = e_named_parameters_get (credentials, E_SOURCE_CREDENTIAL_USERNAME);
	if (username && *username) {
		cbhttp->priv->username = g_strdup (username);
	}

	uri = cal_backend_http_ensure_uri (cbhttp);
	if (cal_backend_http_load (cbhttp, uri, out_certificate_pem, out_certificate_errors, cancellable, &local_error)) {
		if (!cbhttp->priv->reload_timeout_id) {
			ESource *source = e_backend_get_source (backend);

			cbhttp->priv->reload_timeout_id = e_source_refresh_add_timeout (source, NULL, http_cal_reload_cb, backend, NULL);
		}
	}

	if (local_error == NULL) {
		result = E_SOURCE_AUTHENTICATION_ACCEPTED;
	} else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
		result = E_SOURCE_AUTHENTICATION_REJECTED;
		g_clear_error (&local_error);
	} else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED)) {
		result = E_SOURCE_AUTHENTICATION_ERROR_SSL_FAILED;
		g_propagate_error (error, local_error);
	} else {
		result = E_SOURCE_AUTHENTICATION_ERROR;
		g_propagate_error (error, local_error);
	}

	return result;
}
static void
google_backend_add_contacts (ECollectionBackend *backend)
{
	ESource *source;
	ESource *collection_source;
	ESourceRegistryServer *server;
	ESourceExtension *extension;
	ESourceCollection *collection_extension;
	const gchar *backend_name;
	const gchar *extension_name;
	const gchar *resource_id;

	collection_source = e_backend_get_source (E_BACKEND (backend));

	resource_id = GOOGLE_CONTACTS_RESOURCE_ID;
	source = e_collection_backend_new_child (backend, resource_id);
	e_source_set_display_name (source, _("Contacts"));

	/* Add the address book source to the collection. */
	collection_extension = e_source_get_extension (
		collection_source, E_SOURCE_EXTENSION_COLLECTION);

	/* Configure the address book source. */

	backend_name = GOOGLE_CONTACTS_BACKEND_NAME;

	extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
	extension = e_source_get_extension (source, extension_name);

	e_source_backend_set_backend_name (
		E_SOURCE_BACKEND (extension), backend_name);

	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
	extension = e_source_get_extension (source, extension_name);

	e_source_authentication_set_host (
		E_SOURCE_AUTHENTICATION (extension),
		GOOGLE_CONTACTS_HOST);

	g_object_bind_property (
		collection_extension, "identity",
		extension, "user",
		G_BINDING_SYNC_CREATE);

	server = e_collection_backend_ref_server (backend);
	e_source_registry_server_add_source (server, source);
	g_object_unref (server);

	g_object_unref (source);
}
Ejemplo n.º 10
0
static void
eee_backend_child_added (ECollectionBackend *backend,
                         ESource *child_source)
{
	ESource *collection_source;
	const gchar *extension_name;
	gboolean is_mail = FALSE;

	collection_source = e_backend_get_source (E_BACKEND (backend));

	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
	is_mail |= e_source_has_extension (child_source, extension_name);

	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
	is_mail |= e_source_has_extension (child_source, extension_name);

	extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
	is_mail |= e_source_has_extension (child_source, extension_name);

	/* Synchronize mail-related display names with the collection. */
	if (is_mail)
		g_object_bind_property (
			collection_source, "display-name",
			child_source, "display-name",
			G_BINDING_SYNC_CREATE);

	/* Synchronize mail-related user with the collection identity. */
	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
	if (is_mail && e_source_has_extension (child_source, extension_name)) {
		ESourceAuthentication *auth_child_extension;
		ESourceCollection *collection_extension;

		extension_name = E_SOURCE_EXTENSION_COLLECTION;
		collection_extension = e_source_get_extension (
			collection_source, extension_name);

		extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
		auth_child_extension = e_source_get_extension (
			child_source, extension_name);

		g_object_bind_property (
			collection_extension, "identity",
			auth_child_extension, "user",
			G_BINDING_SYNC_CREATE);
	}

	/* Chain up to parent's child_added() method. */
	E_COLLECTION_BACKEND_CLASS (e_eee_backend_parent_class)->
		child_added (backend, child_source);
}
Ejemplo n.º 11
0
/**
 * kolab_util_backend_get_foldername:
 * @backend: an #EBackend
 *
 * Returns the Kolab foldername for @backend.
 *
 * Returns: the foldername for @backend
 **/
const gchar *
kolab_util_backend_get_foldername (EBackend *backend)
{
	ESource *source;
	ESourceResource *extension;
	const gchar *extension_name;

	g_return_val_if_fail (E_IS_BACKEND (backend), NULL);

	source = e_backend_get_source (backend);
	extension_name = E_SOURCE_EXTENSION_KOLAB_FOLDER;
	extension = e_source_get_extension (source, extension_name);

	return e_source_resource_get_identity (extension);
}
static void
ebbm_contacts_connection_status_changed (EBookBackendMAPI *ebma, gboolean is_online)
{
	ESource *source;
	ESourceMapiFolder *ext_mapi_folder;

	e_book_backend_set_writable (E_BOOK_BACKEND (ebma), is_online);

	if (!is_online)
		return;

	source = e_backend_get_source (E_BACKEND (ebma));
	ext_mapi_folder = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER);

	if (e_source_mapi_folder_get_server_notification (ext_mapi_folder)) {
		EMapiConnection *conn;
		mapi_object_t obj_folder;
		gboolean status;
		GError *mapi_error = NULL;

		e_book_backend_mapi_lock_connection (ebma);

		conn = e_book_backend_mapi_get_connection (ebma, NULL, NULL);
		if (!conn) {
			e_book_backend_mapi_unlock_connection (ebma);
			return;
		}

		status = ebbm_contacts_open_folder (E_BOOK_BACKEND_MAPI_CONTACTS (ebma), conn, &obj_folder, NULL, &mapi_error);

		if (status) {
			e_mapi_connection_enable_notifications (conn, &obj_folder,
				fnevObjectCreated | fnevObjectModified | fnevObjectDeleted | fnevObjectMoved | fnevObjectCopied,
				NULL, &mapi_error);

			e_mapi_connection_close_folder (conn, &obj_folder, NULL, &mapi_error);
		}

		e_book_backend_mapi_maybe_disconnect (ebma, mapi_error);
		g_clear_error (&mapi_error);

		g_signal_connect (conn, "server-notification", G_CALLBACK (ebbmc_server_notification_cb), ebma);

		e_book_backend_mapi_unlock_connection (ebma);
	}
}
static guint
send_and_handle_ssl (EBookBackendWebdav *webdav,
                     SoupMessage *message,
                     GCancellable *cancellable)
{
	guint status_code;

	status_code = soup_session_send_message (webdav->priv->session, message);
	if (status_code == SOUP_STATUS_SSL_FAILED) {
		ESource *source;
		ESourceWebdav *extension;
		ESourceRegistry *registry;
		EBackend *backend;
		ETrustPromptResponse response;
		ENamedParameters *parameters;

		backend = E_BACKEND (webdav);
		source = e_backend_get_source (backend);
		registry = e_book_backend_get_registry (E_BOOK_BACKEND (backend));
		extension = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND);

		parameters = e_named_parameters_new ();

		response = e_source_webdav_prepare_ssl_trust_prompt (extension, message, registry, parameters);
		if (response == E_TRUST_PROMPT_RESPONSE_UNKNOWN) {
			response = e_backend_trust_prompt_sync (backend, parameters, cancellable, NULL);
			if (response != E_TRUST_PROMPT_RESPONSE_UNKNOWN)
				e_source_webdav_store_ssl_trust_prompt (extension, message, response);
		}

		e_named_parameters_free (parameters);

		if (response == E_TRUST_PROMPT_RESPONSE_ACCEPT ||
		    response == E_TRUST_PROMPT_RESPONSE_ACCEPT_TEMPORARILY) {
			g_object_set (webdav->priv->session, SOUP_SESSION_SSL_STRICT, FALSE, NULL);
			status_code = soup_session_send_message (webdav->priv->session, message);
		}
	}

	return status_code;
}
Ejemplo n.º 14
0
static void
e_cal_backend_http_refresh (ECalBackendSync *backend,
                            EDataCal *cal,
                            GCancellable *cancellable,
                            GError **perror)
{
	ECalBackendHttp *cbhttp;
	ECalBackendHttpPrivate *priv;
	ESource *source;

	cbhttp = E_CAL_BACKEND_HTTP (backend);
	priv = cbhttp->priv;

	if (!priv->opened ||
	    priv->is_loading)
		return;

	source = e_backend_get_source (E_BACKEND (cbhttp));
	g_return_if_fail (source != NULL);

	e_source_refresh_force_timeout (source);
}
Ejemplo n.º 15
0
/** Setup 3e server connection information.
 *
 * @param cb 3e calendar backend.
 * @param username Username used for authentication.
 * @param password Password.
 * @param err Error pointer.
 */
gboolean e_cal_backend_3e_setup_connection(ECalBackend3e *cb, const char *username, const char *password)
{
    ESource *source;

    g_return_val_if_fail(cb != NULL, FALSE);
    g_return_val_if_fail(username != NULL, FALSE);
    g_return_val_if_fail(password != NULL, FALSE);

    source = e_backend_get_source(E_BACKEND(cb));

    g_free(cb->priv->username);
    g_free(cb->priv->password);
    g_free(cb->priv->server_uri);
    cb->priv->server_uri = NULL;

    if (e_source_get_property(source, "eee-server"))
    {
        cb->priv->server_uri = g_strdup_printf("https://%s/RPC2", e_source_get_property(source, "eee-server"));
    }
    cb->priv->username = g_strdup(username);
    cb->priv->password = g_strdup(password);

    return TRUE;
}
Ejemplo n.º 16
0
static void
soup_authenticate (SoupSession *session,
                   SoupMessage *msg,
                   SoupAuth *auth,
                   gboolean retrying,
                   gpointer data)
{
	ECalBackendHttp *cbhttp;
	ESourceAuthentication *auth_extension;
	ESource *source;
	const gchar *extension_name;
	const gchar *username;
	gchar *auth_user;

	if (retrying)
		return;

	cbhttp = E_CAL_BACKEND_HTTP (data);

	source = e_backend_get_source (E_BACKEND (data));
	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
	auth_extension = e_source_get_extension (source, extension_name);

	auth_user = e_source_authentication_dup_user (auth_extension);

	username = cbhttp->priv->username;
	if (!username || !*username)
		username = auth_user;

	if (!username || !*username || !cbhttp->priv->password)
		soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);
	else
		soup_auth_authenticate (auth, username, cbhttp->priv->password);

	g_free (auth_user);
}
static guint
upload_contact (EBookBackendWebdav *webdav,
                EContact *contact,
                gchar **reason,
                GCancellable *cancellable)
{
	ESource     *source;
	ESourceWebdav *webdav_extension;
	SoupMessage *message;
	gchar       *uri;
	gchar       *etag;
	const gchar  *new_etag, *redir_uri;
	gchar        *request;
	guint        status;
	gboolean     avoid_ifmatch;
	const gchar *extension_name;

	source = e_backend_get_source (E_BACKEND (webdav));

	extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND;
	webdav_extension = e_source_get_extension (source, extension_name);

	source = e_backend_get_source (E_BACKEND (webdav));

	uri = e_contact_get (contact, E_CONTACT_UID);
	if (uri == NULL) {
		g_warning ("can't upload contact without UID");
		return 400;
	}

	message = soup_message_new (SOUP_METHOD_PUT, uri);
	soup_message_headers_append (message->request_headers, "User-Agent", USERAGENT);
	soup_message_headers_append (message->request_headers, "Connection", "close");

	avoid_ifmatch = e_source_webdav_get_avoid_ifmatch (webdav_extension);

	/* some servers (like apache < 2.2.8) don't handle If-Match, correctly so
	 * we can leave it out */
	if (!avoid_ifmatch) {
		/* only override if etag is still the same on the server */
		etag = e_contact_get (contact, E_CONTACT_REV);
		if (etag == NULL) {
			soup_message_headers_append (
				message->request_headers,
				"If-None-Match", "*");
		} else if (etag[0] == 'W' && etag[1] == '/') {
			g_warning ("we only have a weak ETag, don't use If-Match synchronisation");
		} else {
			soup_message_headers_append (
				message->request_headers,
				"If-Match", etag);
			g_free (etag);
		}
	}

	request = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
	soup_message_set_request (
		message, "text/vcard", SOUP_MEMORY_TEMPORARY,
		request, strlen (request));

	status   = send_and_handle_ssl (webdav, message, cancellable);
	new_etag = soup_message_headers_get_list (message->response_headers, "ETag");

	redir_uri = soup_message_headers_get_list (message->response_headers, "Location");

	/* set UID and REV fields */
	e_contact_set (contact, E_CONTACT_REV, (gconstpointer) new_etag);
	if (redir_uri && *redir_uri) {
		if (!strstr (redir_uri, "://")) {
			/* it's a relative URI */
			SoupURI *suri = soup_uri_new (uri);
			gchar *full_uri;

			soup_uri_set_path (suri, redir_uri);
			full_uri = soup_uri_to_string (suri, TRUE);

			e_contact_set (contact, E_CONTACT_UID, full_uri);

			g_free (full_uri);
			soup_uri_free (suri);
		} else {
			e_contact_set (contact, E_CONTACT_UID, redir_uri);
		}
	} else {
		e_contact_set (contact, E_CONTACT_UID, uri);
	}

	if (reason) {
		*reason = g_strdup (message->reason_phrase && *message->reason_phrase ? message->reason_phrase :
				    (soup_status_get_phrase (message->status_code) ? soup_status_get_phrase (message->status_code) : _("Unknown error")));
	}

	g_object_unref (message);
	g_free (request);
	g_free (uri);

	return status;
}
Ejemplo n.º 18
0
static void
eee_backend_add_calendar (ECollectionBackend *backend)
{
	ESource *source;
	ESource *collection_source;
	ESourceRegistryServer *server;
	ESourceExtension *extension;
	ESourceCollection *collection_extension;
	const gchar *backend_name;
	const gchar *extension_name;
	const gchar *identity;
	const gchar *resource_id;
	gchar *path;

	/* FIXME As a future enhancement, we should query Eee
	 *       for a list of user calendars and add them to the
	 *       collection with matching display names and colors. */

	collection_source = e_backend_get_source (E_BACKEND (backend));
/*
	resource_id = GOOGLE_CALENDAR_RESOURCE_ID;
	source = e_collection_backend_new_child (backend, resource_id);
	e_source_set_display_name (source, _("Calendar"));

	collection_extension = e_source_get_extension (
		collection_source, E_SOURCE_EXTENSION_COLLECTION);
*/
	/* Configure the calendar source. */
/*
	backend_name = "eee";

	extension_name = E_SOURCE_EXTENSION_CALENDAR;
	extension = e_source_get_extension (source, extension_name);

	e_source_backend_set_backend_name (
		E_SOURCE_BACKEND (extension), backend_name);

	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
	extension = e_source_get_extension (source, extension_name);

	e_source_authentication_set_host (
		E_SOURCE_AUTHENTICATION (extension),
		GOOGLE_CALENDAR_HOST);

	g_object_bind_property (
		collection_extension, "identity",
		extension, "user",
		G_BINDING_SYNC_CREATE);

	extension_name = E_SOURCE_EXTENSION_SECURITY;
	extension = e_source_get_extension (source, extension_name);

	e_source_security_set_secure (
		E_SOURCE_SECURITY (extension), TRUE);

	extension_name = E_SOURCE_EXTENSION_RESOURCE;
	extension = e_source_get_extension (source, extension_name);

	identity = e_source_collection_get_identity (collection_extension);
	path = g_strdup_printf (GOOGLE_CALENDAR_CALDAV_PATH, identity);
	e_source_webdav_set_resource_path (
		E_SOURCE_WEBDAV (extension), path);
	g_free (path);

	server = e_collection_backend_ref_server (backend);
	e_source_registry_server_add_source (server, source);
	g_object_unref (server);

	g_object_unref (source);
*/
}
static void
e_book_backend_webdav_open (EBookBackend *backend,
                            EDataBook *book,
                            guint opid,
                            GCancellable *cancellable,
                            gboolean only_if_exists)
{
	EBookBackendWebdav        *webdav = E_BOOK_BACKEND_WEBDAV (backend);
	EBookBackendWebdavPrivate *priv   = webdav->priv;
	ESourceAuthentication     *auth_extension;
	ESourceOffline            *offline_extension;
	ESourceWebdav             *webdav_extension;
	ESource                   *source;
	const gchar               *extension_name;
	const gchar               *cache_dir;
	gchar                     *filename;
	SoupSession               *session;
	SoupURI                   *suri;
	GError                    *error = NULL;

	/* will try fetch ctag for the first time, if it fails then sets this to FALSE */
	priv->supports_getctag = TRUE;

	source = e_backend_get_source (E_BACKEND (backend));
	cache_dir = e_book_backend_get_cache_dir (backend);

	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
	auth_extension = e_source_get_extension (source, extension_name);

	extension_name = E_SOURCE_EXTENSION_OFFLINE;
	offline_extension = e_source_get_extension (source, extension_name);

	extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND;
	webdav_extension = e_source_get_extension (source, extension_name);

	priv->marked_for_offline =
		e_source_offline_get_stay_synchronized (offline_extension);

	if (!e_backend_get_online (E_BACKEND (backend)) && !priv->marked_for_offline ) {
		e_book_backend_respond_opened (backend, book, opid, EDB_ERROR (OFFLINE_UNAVAILABLE));
		return;
	}

	suri = e_source_webdav_dup_soup_uri (webdav_extension);

	priv->uri = soup_uri_to_string (suri, FALSE);
	if (!priv->uri || !*priv->uri) {
		g_free (priv->uri);
		priv->uri = NULL;
		soup_uri_free (suri);
		e_book_backend_respond_opened (backend, book, opid, EDB_ERROR_EX (OTHER_ERROR, _("Cannot transform SoupURI to string")));
		return;
	}

	g_mutex_lock (&priv->cache_lock);

	/* make sure the priv->uri ends with a forward slash */
	if (priv->uri[strlen (priv->uri) - 1] != '/') {
		gchar *tmp = priv->uri;
		priv->uri = g_strconcat (tmp, "/", NULL);
		g_free (tmp);
	}

	if (!priv->cache) {
		filename = g_build_filename (cache_dir, "cache.xml", NULL);
		priv->cache = e_book_backend_cache_new (filename);
		g_free (filename);
	}
	g_mutex_unlock (&priv->cache_lock);

	session = soup_session_sync_new ();
	g_object_set (
		session,
		SOUP_SESSION_TIMEOUT, 90,
		SOUP_SESSION_SSL_STRICT, TRUE,
		SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE,
		NULL);

	e_source_webdav_unset_temporary_ssl_trust (webdav_extension);

	g_signal_connect (
		session, "authenticate",
		G_CALLBACK (soup_authenticate), webdav);

	priv->session = session;
	priv->proxy = e_proxy_new ();
	e_proxy_setup_proxy (priv->proxy);
	g_signal_connect (
		priv->proxy, "changed",
		G_CALLBACK (proxy_settings_changed), priv);
	proxy_settings_changed (priv->proxy, priv);
	webdav_debug_setup (priv->session);

	e_book_backend_notify_online (backend, TRUE);
	e_book_backend_notify_readonly (backend, FALSE);

	if (e_source_authentication_required (auth_extension))
		e_backend_authenticate_sync (
			E_BACKEND (backend),
			E_SOURCE_AUTHENTICATOR (backend),
			cancellable, &error);

	soup_uri_free (suri);

	/* This function frees the GError passed to it. */
	e_book_backend_respond_opened (backend, book, opid, error);
}
Ejemplo n.º 20
0
static gboolean
cal_backend_http_load (ECalBackendHttp *backend,
                       const gchar *uri,
		       gchar **out_certificate_pem,
		       GTlsCertificateFlags *out_certificate_errors,
                       GCancellable *cancellable,
                       GError **error)
{
	ECalBackendHttpPrivate *priv = backend->priv;
	ETimezoneCache *timezone_cache;
	SoupMessage *soup_message;
	SoupSession *soup_session;
	icalcomponent *icalcomp, *subcomp;
	icalcomponent_kind kind;
	const gchar *newuri;
	SoupURI *uri_parsed;
	GHashTable *old_cache;
	GSList *comps_in_cache;
	ESource *source;
	guint status_code;
	gulong cancel_id = 0;

	struct {
		SoupSession *soup_session;
		SoupMessage *soup_message;
	} cancel_data;

	timezone_cache = E_TIMEZONE_CACHE (backend);

	soup_session = backend->priv->soup_session;
	soup_message = cal_backend_http_new_message (backend, uri);

	if (soup_message == NULL) {
		g_set_error (
			error, SOUP_HTTP_ERROR,
			SOUP_STATUS_MALFORMED,
			_("Malformed URI: %s"), uri);
		return FALSE;
	}

	if (G_IS_CANCELLABLE (cancellable)) {
		cancel_data.soup_session = soup_session;
		cancel_data.soup_message = soup_message;

		cancel_id = g_cancellable_connect (
			cancellable,
			G_CALLBACK (cal_backend_http_cancelled),
			&cancel_data, (GDestroyNotify) NULL);
	}

	source = e_backend_get_source (E_BACKEND (backend));

	e_soup_ssl_trust_connect (soup_message, source);

	e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTING);

	status_code = soup_session_send_message (soup_session, soup_message);

	if (G_IS_CANCELLABLE (cancellable))
		g_cancellable_disconnect (cancellable, cancel_id);

	if (status_code == SOUP_STATUS_NOT_MODIFIED) {
		e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED);

		/* attempts with ETag can result in 304 status code */
		g_object_unref (soup_message);
		priv->opened = TRUE;
		return TRUE;
	}

	/* Handle redirection ourselves */
	if (SOUP_STATUS_IS_REDIRECTION (status_code)) {
		gboolean success;

		newuri = soup_message_headers_get_list (
			soup_message->response_headers, "Location");

		d (g_message ("Redirected from %s to %s\n", async_context->uri, newuri));

		if (newuri != NULL) {
			gchar *redirected_uri;

			if (newuri[0]=='/') {
				g_warning ("Hey! Relative URI returned! Working around...\n");

				uri_parsed = soup_uri_new (uri);
				soup_uri_set_path (uri_parsed, newuri);
				soup_uri_set_query (uri_parsed, NULL);
				/* g_free (newuri); */

				newuri = soup_uri_to_string (uri_parsed, FALSE);
				g_message ("Translated URI: %s\n", newuri);
				soup_uri_free (uri_parsed);
			}

			redirected_uri =
				webcal_to_http_method (newuri, FALSE);
			success = cal_backend_http_load (
				backend, redirected_uri, out_certificate_pem, out_certificate_errors, cancellable, error);
			g_free (redirected_uri);

		} else {
			g_set_error (
				error, SOUP_HTTP_ERROR,
				SOUP_STATUS_BAD_REQUEST,
				_("Redirected to Invalid URI"));
			success = FALSE;
		}

		if (success) {
			e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED);
		} else {
			e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED);
		}

		g_object_unref (soup_message);
		return success;
	}

	/* check status code */
	if (!SOUP_STATUS_IS_SUCCESSFUL (status_code)) {
		/* because evolution knows only G_IO_ERROR_CANCELLED */
		if (status_code == SOUP_STATUS_CANCELLED)
			g_set_error (
				error, G_IO_ERROR, G_IO_ERROR_CANCELLED,
				"%s", soup_message->reason_phrase);
		else
			g_set_error (
				error, SOUP_HTTP_ERROR, status_code,
				"%s", soup_message->reason_phrase);

		if (status_code == SOUP_STATUS_SSL_FAILED) {
			e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_SSL_FAILED);
			cal_backend_http_extract_ssl_failed_data (soup_message, out_certificate_pem, out_certificate_errors);
		} else {
			e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED);
		}

		g_object_unref (soup_message);
		empty_cache (backend);
		return FALSE;
	}

	e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED);

	if (priv->store) {
		const gchar *etag;

		etag = soup_message_headers_get_one (
			soup_message->response_headers, "ETag");

		if (etag != NULL && *etag == '\0')
			etag = NULL;

		e_cal_backend_store_put_key_value (priv->store, "ETag", etag);
	}

	/* get the calendar from the response */
	icalcomp = icalparser_parse_string (soup_message->response_body->data);

	if (!icalcomp) {
		g_set_error (
			error, SOUP_HTTP_ERROR,
			SOUP_STATUS_MALFORMED,
			_("Bad file format."));
		g_object_unref (soup_message);
		empty_cache (backend);
		return FALSE;
	}

	if (icalcomponent_isa (icalcomp) != ICAL_VCALENDAR_COMPONENT) {
		g_set_error (
			error, SOUP_HTTP_ERROR,
			SOUP_STATUS_MALFORMED,
			_("Not a calendar."));
		icalcomponent_free (icalcomp);
		g_object_unref (soup_message);
		empty_cache (backend);
		return FALSE;
	}

	g_object_unref (soup_message);
	soup_message = NULL;

	/* Update cache */
	old_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

	comps_in_cache = e_cal_backend_store_get_components (priv->store);
	while (comps_in_cache != NULL) {
		const gchar *uid;
		ECalComponent *comp = comps_in_cache->data;

		e_cal_component_get_uid (comp, &uid);
		g_hash_table_insert (old_cache, g_strdup (uid), e_cal_component_get_as_string (comp));

		comps_in_cache = g_slist_remove (comps_in_cache, comps_in_cache->data);
		g_object_unref (comp);
	}

	kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend));
	subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT);
	e_cal_backend_store_freeze_changes (priv->store);
	while (subcomp) {
		ECalComponent *comp;
		icalcomponent_kind subcomp_kind;
		icalproperty *prop = NULL;

		subcomp_kind = icalcomponent_isa (subcomp);
		prop = icalcomponent_get_first_property (subcomp, ICAL_UID_PROPERTY);
		if (!prop && subcomp_kind == kind) {
			gchar *new_uid = e_cal_component_gen_uid ();
			icalcomponent_set_uid (subcomp, new_uid);
			g_free (new_uid);
		}

		if (subcomp_kind == kind) {
			comp = e_cal_component_new ();
			if (e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (subcomp))) {
				const gchar *uid;
				gpointer orig_key, orig_value;

				e_cal_component_get_uid (comp, &uid);

				if (!put_component_to_store (backend, comp)) {
					g_hash_table_remove (old_cache, uid);
				} else if (g_hash_table_lookup_extended (old_cache, uid, &orig_key, &orig_value)) {
					ECalComponent *orig_comp = e_cal_component_new_from_string (orig_value);

					e_cal_backend_notify_component_modified (E_CAL_BACKEND (backend), orig_comp, comp);

					g_hash_table_remove (old_cache, uid);
					if (orig_comp)
						g_object_unref (orig_comp);
				} else {
					e_cal_backend_notify_component_created (E_CAL_BACKEND (backend), comp);
				}
			}

			g_object_unref (comp);
		} else if (subcomp_kind == ICAL_VTIMEZONE_COMPONENT) {
			icaltimezone *zone;

			zone = icaltimezone_new ();
			icaltimezone_set_component (zone, icalcomponent_new_clone (subcomp));
			e_timezone_cache_add_timezone (timezone_cache, zone);

			icaltimezone_free (zone, 1);
		}

		subcomp = icalcomponent_get_next_component (icalcomp, ICAL_ANY_COMPONENT);
	}

	e_cal_backend_store_thaw_changes (priv->store);

	/* notify the removals */
	g_hash_table_foreach_remove (old_cache, (GHRFunc) notify_and_remove_from_cache, backend);
	g_hash_table_destroy (old_cache);

	/* free memory */
	icalcomponent_free (icalcomp);

	priv->opened = TRUE;

	return TRUE;
}
static void
yahoo_backend_config_calendar_child (ECollectionBackend *backend,
                                     ESource *source)
{
	EYahooBackend *yahoo_backend;
	ESource *collection_source;
	ESource *mail_identity_source;
	ESourceExtension *extension;
	ESourceCollection *collection_extension;
	const gchar *extension_name;
	const gchar *identity;
	gchar *display_name = NULL;

	/* FIXME As a future enhancement, we should query Yahoo!
	 *       for a list of user calendars and add them to the
	 *       collection with matching display names and colors. */

	yahoo_backend = E_YAHOO_BACKEND (backend);

	collection_source = e_backend_get_source (E_BACKEND (backend));

	collection_extension = e_source_get_extension (
		collection_source, E_SOURCE_EXTENSION_COLLECTION);

	identity = e_source_collection_get_identity (collection_extension);

	/* XXX Assume the calendar's display name can be derived from
	 *     the user's mail identity.  As mentioned above, we should
	 *     really just query Yahoo! for a list of user calendars. */
	mail_identity_source =
		g_weak_ref_get (&yahoo_backend->mail_identity_source);
	if (mail_identity_source != NULL) {
		extension = e_source_get_extension (
			mail_identity_source,
			E_SOURCE_EXTENSION_MAIL_IDENTITY);
		display_name = e_source_mail_identity_dup_name (
			E_SOURCE_MAIL_IDENTITY (extension));
		if (display_name != NULL)
			g_strdelimit (display_name, " ", '_');
		g_object_unref (mail_identity_source);
	}

	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
	extension = e_source_get_extension (source, extension_name);

	e_source_authentication_set_host (
		E_SOURCE_AUTHENTICATION (extension),
		YAHOO_CALENDAR_HOST);

	e_binding_bind_property (
		collection_extension, "identity",
		extension, "user",
		G_BINDING_SYNC_CREATE);

	extension_name = E_SOURCE_EXTENSION_SECURITY;
	extension = e_source_get_extension (source, extension_name);

	e_source_security_set_secure (
		E_SOURCE_SECURITY (extension), TRUE);

	extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND;
	extension = e_source_get_extension (source, extension_name);

	e_source_webdav_set_display_name (
		E_SOURCE_WEBDAV (extension), display_name);

	if (identity != NULL && display_name != NULL) {
		gchar *resource_path;

		resource_path = g_strdup_printf (
			YAHOO_CALENDAR_CALDAV_PATH, identity, display_name);
		e_source_webdav_set_resource_path (
			E_SOURCE_WEBDAV (extension), resource_path);
		g_free (resource_path);
	}

	g_free (display_name);
}
static void
yahoo_backend_child_added (ECollectionBackend *backend,
                           ESource *child_source)
{
	EYahooBackend *yahoo_backend;
	ESource *collection_source;
	const gchar *extension_name;
	gboolean is_mail = FALSE;

	/* Chain up to parent's child_added() method. */
	E_COLLECTION_BACKEND_CLASS (e_yahoo_backend_parent_class)->
		child_added (backend, child_source);

	yahoo_backend = E_YAHOO_BACKEND (backend);
	collection_source = e_backend_get_source (E_BACKEND (backend));

	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
	is_mail |= e_source_has_extension (child_source, extension_name);

	/* Take special note of the mail identity source.
	 * We need it to build the calendar CalDAV path. */
	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
	if (e_source_has_extension (child_source, extension_name)) {
		GWeakRef *weak_ref;

		weak_ref = &yahoo_backend->mail_identity_source;
		g_weak_ref_set (weak_ref, child_source);
		is_mail = TRUE;
	}

	extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
	is_mail |= e_source_has_extension (child_source, extension_name);

	/* Synchronize mail-related user with the collection identity. */
	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
	if (is_mail && e_source_has_extension (child_source, extension_name)) {
		ESourceAuthentication *auth_child_extension;
		ESourceCollection *collection_extension;
		const gchar *collection_identity;
		const gchar *auth_child_user;

		extension_name = E_SOURCE_EXTENSION_COLLECTION;
		collection_extension = e_source_get_extension (
			collection_source, extension_name);
		collection_identity = e_source_collection_get_identity (
			collection_extension);

		extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
		auth_child_extension = e_source_get_extension (
			child_source, extension_name);
		auth_child_user = e_source_authentication_get_user (
			auth_child_extension);

		/* XXX Do not override an existing user name setting.
		 *     The IMAP or (especially) SMTP configuration may
		 *     have been modified to use a non-Yahoo! server. */
		if (auth_child_user == NULL)
			e_source_authentication_set_user (
				auth_child_extension,
				collection_identity);
	}
}
static void
google_backend_child_added (ECollectionBackend *backend,
                            ESource *child_source)
{
	ESource *collection_source;
	const gchar *extension_name;
	gboolean is_mail = FALSE;

	collection_source = e_backend_get_source (E_BACKEND (backend));

	extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
	is_mail |= e_source_has_extension (child_source, extension_name);

	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
	is_mail |= e_source_has_extension (child_source, extension_name);

	extension_name = E_SOURCE_EXTENSION_MAIL_TRANSPORT;
	is_mail |= e_source_has_extension (child_source, extension_name);

	/* Synchronize mail-related user with the collection identity. */
	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
	if (is_mail && e_source_has_extension (child_source, extension_name)) {
		ESourceAuthentication *auth_child_extension;
		ESourceCollection *collection_extension;
		const gchar *collection_identity;
		const gchar *auth_child_user;

		extension_name = E_SOURCE_EXTENSION_COLLECTION;
		collection_extension = e_source_get_extension (
			collection_source, extension_name);
		collection_identity = e_source_collection_get_identity (
			collection_extension);

		extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
		auth_child_extension = e_source_get_extension (
			child_source, extension_name);
		auth_child_user = e_source_authentication_get_user (
			auth_child_extension);

		/* XXX Do not override an existing user name setting.
		 *     The IMAP or (especially) SMTP configuration may
		 *     have been modified to use a non-Google server. */
		if (auth_child_user == NULL)
			e_source_authentication_set_user (
				auth_child_extension,
				collection_identity);
	}

	/* Keep the calendar authentication method up-to-date.
	 *
	 * XXX Not using a property binding here in case I end up adding
	 *     other "support" interfaces which influence authentication.
	 *     Many-to-one property bindinds tend not to work so well. */
	extension_name = E_SOURCE_EXTENSION_CALENDAR;
	if (e_source_has_extension (child_source, extension_name)) {
		google_backend_calendar_update_auth_method (child_source);
		g_signal_connect (
			child_source, "notify::oauth2-support",
			G_CALLBACK (google_backend_calendar_update_auth_method),
			NULL);
	}

	/* Keep the contacts authentication method up-to-date.
	 *
	 * XXX Not using a property binding here in case I end up adding
	 *     other "support" interfaces which influence authentication.
	 *     Many-to-one property bindings tend not to work so well. */
	extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
	if (e_source_has_extension (child_source, extension_name)) {
		google_backend_contacts_update_auth_method (child_source);
		g_signal_connect (
			child_source, "notify::oauth2-support",
			G_CALLBACK (google_backend_contacts_update_auth_method),
			NULL);
	}

	/* Chain up to parent's child_added() method. */
	E_COLLECTION_BACKEND_CLASS (e_google_backend_parent_class)->
		child_added (backend, child_source);
}
static void
google_backend_add_calendar (ECollectionBackend *backend)
{
	ESource *source;
	ESource *collection_source;
	ESourceRegistryServer *server;
	ESourceExtension *extension;
	ESourceCollection *collection_extension;
	const gchar *backend_name;
	const gchar *extension_name;
	const gchar *resource_id;

	/* FIXME As a future enhancement, we should query Google
	 *       for a list of user calendars and add them to the
	 *       collection with matching display names and colors. */

	/* NOTE: Host name and WebDAV resource path are set in
	 *       google_backend_calendar_update_auth_method(),
	 *       since they depend on the auth method used. */

	collection_source = e_backend_get_source (E_BACKEND (backend));

	resource_id = GOOGLE_CALENDAR_RESOURCE_ID;
	source = e_collection_backend_new_child (backend, resource_id);
	e_source_set_display_name (source, _("Calendar"));

	collection_extension = e_source_get_extension (
		collection_source, E_SOURCE_EXTENSION_COLLECTION);

	/* Configure the calendar source. */

	backend_name = GOOGLE_CALENDAR_BACKEND_NAME;

	extension_name = E_SOURCE_EXTENSION_CALENDAR;
	extension = e_source_get_extension (source, extension_name);

	e_source_backend_set_backend_name (
		E_SOURCE_BACKEND (extension), backend_name);

	extension_name = E_SOURCE_EXTENSION_AUTHENTICATION;
	extension = e_source_get_extension (source, extension_name);

	g_object_bind_property (
		collection_extension, "identity",
		extension, "user",
		G_BINDING_SYNC_CREATE);

	/* Make sure the WebDAV resource path is up-to-date, since
	 * it's built from the "user" property that we just set. */
	google_backend_calendar_update_auth_method (source);

	extension_name = E_SOURCE_EXTENSION_SECURITY;
	extension = e_source_get_extension (source, extension_name);

	e_source_security_set_secure (
		E_SOURCE_SECURITY (extension), TRUE);

	extension_name = E_SOURCE_EXTENSION_ALARMS;
	extension = e_source_get_extension (source, extension_name);
	if (!e_source_alarms_get_last_notified (E_SOURCE_ALARMS (extension))) {
		GTimeVal today_tv;
		gchar *today;

		g_get_current_time (&today_tv);
		today = g_time_val_to_iso8601 (&today_tv);
		e_source_alarms_set_last_notified (
			E_SOURCE_ALARMS (extension), today);
		g_free (today);
	}

	server = e_collection_backend_ref_server (backend);
	e_source_registry_server_add_source (server, source);
	g_object_unref (server);

	g_object_unref (source);
}
Ejemplo n.º 25
0
/* Open handler for the file backend */
static void
e_cal_backend_http_open (ECalBackendSync *backend,
                         EDataCal *cal,
                         GCancellable *cancellable,
                         gboolean only_if_exists,
                         GError **perror)
{
	ECalBackendHttp *cbhttp;
	ECalBackendHttpPrivate *priv;
	ESource *source;
	ESourceWebdav *webdav_extension;
	const gchar *extension_name;
	const gchar *cache_dir;
	gboolean opened = TRUE;
	gchar *tmp;
	GError *local_error = NULL;

	cbhttp = E_CAL_BACKEND_HTTP (backend);
	priv = cbhttp->priv;

	/* already opened, thus can skip all this initialization */
	if (priv->opened)
		return;

	source = e_backend_get_source (E_BACKEND (backend));
	cache_dir = e_cal_backend_get_cache_dir (E_CAL_BACKEND (backend));

	extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND;
	webdav_extension = e_source_get_extension (source, extension_name);

	e_source_webdav_unset_temporary_ssl_trust (webdav_extension);

	if (priv->source_changed_id == 0) {
		priv->source_changed_id = g_signal_connect (
			source, "changed",
			G_CALLBACK (source_changed_cb), cbhttp);
	}

	/* always read uri again */
	tmp = priv->uri;
	priv->uri = NULL;
	g_free (tmp);

	if (priv->store == NULL) {
		/* remove the old cache while migrating to ECalBackendStore */
		e_cal_backend_cache_remove (cache_dir, "cache.xml");
		priv->store = e_cal_backend_store_new (
			cache_dir, E_TIMEZONE_CACHE (backend));
		e_cal_backend_store_load (priv->store);

		if (!priv->store) {
			g_propagate_error (
				perror, EDC_ERROR_EX (OtherError,
				_("Could not create cache file")));
			return;
		}
	}

	e_cal_backend_set_writable (E_CAL_BACKEND (backend), FALSE);

	if (e_backend_get_online (E_BACKEND (backend))) {
		gchar *certificate_pem = NULL;
		GTlsCertificateFlags certificate_errors = 0;
		const gchar *uri;

		uri = cal_backend_http_ensure_uri (cbhttp);

		opened = cal_backend_http_load (cbhttp, uri, &certificate_pem,
			&certificate_errors, cancellable, &local_error);

		if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED) ||
		    g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED) ||
		    (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_FORBIDDEN) &&
		    !cbhttp->priv->password)) {
			GError *local_error2 = NULL;
			ESourceCredentialsReason reason = E_SOURCE_CREDENTIALS_REASON_REQUIRED;

			if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED)) {
				reason = E_SOURCE_CREDENTIALS_REASON_SSL_FAILED;
			}

			e_backend_credentials_required_sync (E_BACKEND (cbhttp), reason, certificate_pem,
				certificate_errors, local_error, cancellable, &local_error2);
			g_clear_error (&local_error);
			local_error = local_error2;
		} else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_FORBIDDEN)) {
			GError *local_error2 = NULL;

			e_backend_credentials_required_sync (E_BACKEND (cbhttp), E_SOURCE_CREDENTIALS_REASON_REJECTED,
				certificate_pem, certificate_errors, local_error, cancellable, &local_error2);

			g_clear_error (&local_error);
			local_error = local_error2;
		}

		g_free (certificate_pem);

		if (local_error != NULL)
			g_propagate_error (perror, local_error);
	}

	if (opened) {
		if (!priv->reload_timeout_id)
			priv->reload_timeout_id = e_source_refresh_add_timeout (source, NULL, http_cal_reload_cb, backend, NULL);
	}
}