From 1f08d409f8b76aa22fd0af80b31312189f28967b Mon Sep 17 00:00:00 2001 From: Chenthill Palanisamy Date: Mon, 9 Jul 2007 11:23:34 +0000 Subject: reviewed by: Veerapuram Varadhan 2007-07-09 Chenthill Palanisamy reviewed by: Veerapuram Varadhan * gui/dialogs/comp-editor.c: (save_comp), (save_comp_with_send), (real_edit_comp): Organizer/Sentby can save/edit components. * gui/dialogs/event-editor.c: (event_editor_edit_comp): * gui/e-calendar-view.c: (e_calendar_view_add_event), (e_calendar_view_cut_clipboard), (delete_event), (e_calendar_view_delete_selected_occurrence), (set_attendee_status_for_delegate), (e_calendar_view_edit_appointment), (e_calendar_view_modify_and_send): * gui/itip-utils.c: (get_attendee), (get_attendee_if_attendee_sentby_is_user), (sanitize_component), (itip_get_comp_attendee), (comp_to_list), (comp_subject), (comp_limit_attendees), (comp_sentby), (itip_send_comp), (reply_to_calendar_comp): Adding the exchange delegation feature. Committing on behalf of Suman Manjunath svn path=/trunk/; revision=33786 --- calendar/ChangeLog | 21 +++++ calendar/gui/dialogs/comp-editor.c | 8 +- calendar/gui/dialogs/event-editor.c | 3 +- calendar/gui/e-calendar-view.c | 14 +-- calendar/gui/itip-utils.c | 183 ++++++++++++++++++++++++++++++------ 5 files changed, 186 insertions(+), 43 deletions(-) (limited to 'calendar') diff --git a/calendar/ChangeLog b/calendar/ChangeLog index ed73814a53..f45d787f33 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,24 @@ +2007-07-09 Chenthill Palanisamy + + reviewed by: Veerapuram Varadhan + + * gui/dialogs/comp-editor.c: (save_comp), (save_comp_with_send), + (real_edit_comp): Organizer/Sentby can save/edit components. + * gui/dialogs/event-editor.c: (event_editor_edit_comp): + * gui/e-calendar-view.c: (e_calendar_view_add_event), + (e_calendar_view_cut_clipboard), (delete_event), + (e_calendar_view_delete_selected_occurrence), + (set_attendee_status_for_delegate), + (e_calendar_view_edit_appointment), + (e_calendar_view_modify_and_send): + * gui/itip-utils.c: (get_attendee), + (get_attendee_if_attendee_sentby_is_user), (sanitize_component), + (itip_get_comp_attendee), (comp_to_list), (comp_subject), + (comp_limit_attendees), (comp_sentby), (itip_send_comp), + (reply_to_calendar_comp): Adding the exchange delegation feature. + + Committing on behalf of Suman Manjunath + 2006-08-31 Matthew Barnes * gui/e-memos.c: (e_memos_setup_view_menus) diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c index 3e4a77d0ee..4a6c1468af 100644 --- a/calendar/gui/dialogs/comp-editor.c +++ b/calendar/gui/dialogs/comp-editor.c @@ -749,7 +749,7 @@ save_comp (CompEditor *editor) } /* If we are not the organizer, we don't update the sequence number */ - if (!e_cal_component_has_organizer (clone) || itip_organizer_is_user (clone, priv->client)) + if (!e_cal_component_has_organizer (clone) || itip_organizer_is_user (clone, priv->client) || itip_sentby_is_user (clone)) e_cal_component_commit_sequence (clone); else e_cal_component_abort_sequence (clone); @@ -784,7 +784,7 @@ save_comp (CompEditor *editor) if (result && priv->mod == CALOBJ_MOD_THIS) { /* FIXME do we really need to do this ? */ - if ((priv->flags & COMP_EDITOR_DELEGATE) || !e_cal_component_has_organizer (clone) || itip_organizer_is_user (clone, priv->client)) + if ((priv->flags & COMP_EDITOR_DELEGATE) || !e_cal_component_has_organizer (clone) || itip_organizer_is_user (clone, priv->client) || itip_sentby_is_user (clone)) e_cal_component_commit_sequence (clone); else e_cal_component_abort_sequence (clone); @@ -881,7 +881,7 @@ save_comp_with_send (CompEditor *editor) return FALSE; if ((delegate && !e_cal_get_save_schedules (priv->client)) || (send && send_component_dialog ((GtkWindow *) editor, priv->client, priv->comp, !priv->existing_org))) { - if (itip_organizer_is_user (priv->comp, priv->client)) { + if ((itip_organizer_is_user (priv->comp, priv->client) || itip_sentby_is_user (priv->comp))) { if (e_cal_component_get_vtype (priv->comp) == E_CAL_COMPONENT_JOURNAL) return comp_editor_send_comp (editor, E_CAL_COMPONENT_METHOD_PUBLISH); else @@ -2495,7 +2495,7 @@ real_edit_comp (CompEditor *editor, ECalComponent *comp) priv->comp = e_cal_component_clone (comp); priv->existing_org = e_cal_component_has_organizer (comp); - priv->user_org = itip_organizer_is_user (comp, priv->client); + priv->user_org = (itip_organizer_is_user (comp, priv->client) || itip_sentby_is_user (comp)); priv->warned = FALSE; set_title_from_comp (editor); diff --git a/calendar/gui/dialogs/event-editor.c b/calendar/gui/dialogs/event-editor.c index eac3de7832..7ebf2a1871 100644 --- a/calendar/gui/dialogs/event-editor.c +++ b/calendar/gui/dialogs/event-editor.c @@ -66,7 +66,6 @@ static void model_row_delete_cb (GtkTreeModel *model, GtkTreePath *path, gpointe static gboolean window_delete_event (GtkWidget *widget, GdkEvent *event, gpointer user_data); static void create_schedule_page (EventEditor *ee); - G_DEFINE_TYPE (EventEditor, event_editor, TYPE_COMP_EDITOR) /* Class initialization function for the event editor */ @@ -757,7 +756,7 @@ event_editor_edit_comp (CompEditor *editor, ECalComponent *comp) } e_cal_component_free_attendee_list (attendees); - comp_editor_set_needs_send (COMP_EDITOR (ee), priv->meeting_shown && itip_organizer_is_user (comp, client)); + comp_editor_set_needs_send (COMP_EDITOR (ee), priv->meeting_shown && (itip_organizer_is_user (comp, client) || itip_sentby_is_user (comp))); priv->updating = FALSE; } diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c index 524b94c913..0ef3fde70c 100644 --- a/calendar/gui/e-calendar-view.c +++ b/calendar/gui/e-calendar-view.c @@ -381,7 +381,7 @@ e_calendar_view_add_event (ECalendarView *cal_view, ECal *client, time_t dtstart g_free (uid); } - if (itip_organizer_is_user (comp, client) && + if ((itip_organizer_is_user (comp, client) || itip_sentby_is_user (comp)) && send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), client, comp, TRUE)) { itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, @@ -686,7 +686,7 @@ e_calendar_view_cut_clipboard (ECalendarView *cal_view) comp = e_cal_component_new (); e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - if (itip_organizer_is_user (comp, event->comp_data->client) + if ((itip_organizer_is_user (comp, event->comp_data->client) || itip_sentby_is_user (comp)) && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), event->comp_data->client, comp, TRUE)) itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, @@ -956,7 +956,7 @@ delete_event (ECalendarView *cal_view, ECalendarViewEvent *event) if (delete) { const char *uid; - if (itip_organizer_is_user (comp, event->comp_data->client) + if ((itip_organizer_is_user (comp, event->comp_data->client) || itip_sentby_is_user (comp)) && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), event->comp_data->client, comp, TRUE)) @@ -1093,7 +1093,7 @@ e_calendar_view_delete_selected_occurrence (ECalendarView *cal_view) e_cal_component_free_datetime (&dt); - if (itip_organizer_is_user (comp, event->comp_data->client) + if ((itip_organizer_is_user (comp, event->comp_data->client) || itip_sentby_is_user (comp)) && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), event->comp_data->client, comp, TRUE) && !e_cal_get_save_schedules (event->comp_data->client)) { @@ -1411,7 +1411,7 @@ set_attendee_status_for_delegate (icalcomponent *icalcomp, ECal *client) prop = icalcomponent_get_next_property (icalcomp, ICAL_ATTENDEE_PROPERTY)) { const char *attendee = icalproperty_get_attendee (prop); - if (g_str_equal (itip_strip_mailto (attendee), address)) { + if (!g_ascii_strcasecmp (itip_strip_mailto (attendee), address)) { param = icalparameter_new_role (ICAL_ROLE_NONPARTICIPANT); icalproperty_set_parameter (prop, param); @@ -1989,7 +1989,7 @@ e_calendar_view_edit_appointment (ECalendarView *cal_view, ECalComponent *comp = e_cal_component_new (); e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp)); flags |= COMP_EDITOR_MEETING; - if (itip_organizer_is_user (comp, client) || !e_cal_component_has_attendees (comp)) + if (itip_organizer_is_user (comp, client) || itip_sentby_is_user (comp) || !e_cal_component_has_attendees (comp)) flags |= COMP_EDITOR_USER_ORG; g_object_unref (comp); } @@ -2006,7 +2006,7 @@ e_calendar_view_modify_and_send (ECalComponent *comp, gboolean new) { if (e_cal_modify_object (client, e_cal_component_get_icalcomponent (comp), mod, NULL)) { - if (itip_organizer_is_user (comp, client) && + if ((itip_organizer_is_user (comp, client) || itip_sentby_is_user (comp)) && send_component_dialog (toplevel, client, comp, new)) itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL, NULL, NULL); } else { diff --git a/calendar/gui/itip-utils.c b/calendar/gui/itip-utils.c index 10a598211e..06a1b9a91e 100644 --- a/calendar/gui/itip-utils.c +++ b/calendar/gui/itip-utils.c @@ -145,10 +145,13 @@ get_attendee (GSList *attendees, char *address) { GSList *l; + if (!address) + return NULL; + for (l = attendees; l; l = l->next) { ECalComponentAttendee *attendee = l->data; - if (g_str_equal (itip_strip_mailto (attendee->value), address)) { + if (!g_ascii_strcasecmp (itip_strip_mailto (attendee->value), address)) { return attendee; } } @@ -156,6 +159,21 @@ get_attendee (GSList *attendees, char *address) return NULL; } +static ECalComponentAttendee * +get_attendee_if_attendee_sentby_is_user (GSList *attendees, char *address) +{ + GSList *l; + + for (l = attendees; l; l = l->next) { + ECalComponentAttendee *attendee = l->data; + + if (attendee->sentby && g_str_equal (itip_strip_mailto (attendee->sentby), address)) { + return attendee; + } + } + + return NULL; +} static char * html_new_lines_for (char *string) @@ -204,6 +222,78 @@ html_new_lines_for (char *string) return html_string; } +void +sanitize_component (ECalComponent *comp, ECal *client) +{ + GSList *attendees; + EAccountList *al; + EAccount *a; + EIterator *it; + ECalComponentOrganizer organizer; + ECalComponentAttendee *attendee = NULL; + ESource *cal_source = NULL; + char *backend_address = NULL; + char *subscriber_address = NULL; + + e_cal_component_get_attendee_list (comp, &attendees); + al = itip_addresses_get (); + e_cal_get_cal_address (client, &backend_address, NULL); + if (!al || !backend_address) + return; + + /* Look for the backend address in the list of enabled accounts */ + for (it = e_list_get_iterator((EList *)al); + e_iterator_is_valid(it); + e_iterator_next(it)) { + + a = (EAccount *) e_iterator_get(it); + if (!a->enabled) + continue; + + if (!g_ascii_strcasecmp (a->id->address, backend_address)) { + e_cal_component_free_attendee_list (attendees); + g_free (backend_address); + return; + } + } + + /* Backend address was not found in the list of accounts. Check if its a foreign/susbcribed backend */ + cal_source = e_cal_get_source (client); + if (!cal_source) { + e_cal_component_free_attendee_list (attendees); + g_free (backend_address); + return; + } + + subscriber_address = e_source_get_property (cal_source, "subscriber"); + if (!subscriber_address) { + e_cal_component_free_attendee_list (attendees); + g_free (backend_address); + return; + } + + attendee = get_attendee (attendees, backend_address); + e_cal_component_get_organizer (comp, &organizer) ; + + e_cal_component_free_attendee_list (attendees); + + if (organizer.value && !g_ascii_strcasecmp (itip_strip_mailto (organizer.value), subscriber_address)) { + ECalComponentOrganizer new_organizer; + new_organizer.value = g_strdup_printf ("MAILTO:%s", backend_address); + new_organizer.cn = (attendee && attendee->cn) ? g_strdup (attendee->cn) : g_strdup (backend_address); + new_organizer.sentby = g_strdup (organizer.value); + new_organizer.language = g_strdup (organizer.language); + e_cal_component_set_organizer (comp, &new_organizer); + } + else if (attendee) { + attendee->sentby = g_strdup_printf ("MAILTO:%s", subscriber_address); + } + + e_cal_component_rescan (comp); + g_free (backend_address); + g_free (subscriber_address); +} + char * itip_get_comp_attendee (ECalComponent *comp, ECal *client) { @@ -218,7 +308,7 @@ itip_get_comp_attendee (ECalComponent *comp, ECal *client) al = itip_addresses_get (); if (client) - e_cal_get_cal_address (client, &address, NULL); + e_cal_get_cal_address (client, &address, NULL); if (address && *address) { attendee = get_attendee (attendees, address); @@ -228,8 +318,19 @@ itip_get_comp_attendee (ECalComponent *comp, ECal *client) e_cal_component_free_attendee_list (attendees); g_free (address); - return user_email; + return user_email; } + + attendee = get_attendee_if_attendee_sentby_is_user (attendees, address); + + if (attendee) { + char *user_email = g_strdup (itip_strip_mailto (attendee->sentby)); + + e_cal_component_free_attendee_list (attendees); + g_free (address); + return user_email; + } + g_free (address); address = NULL; } @@ -238,7 +339,7 @@ itip_get_comp_attendee (ECalComponent *comp, ECal *client) e_iterator_is_valid(it); e_iterator_next(it)) { a = (EAccount *) e_iterator_get(it); - + if (!a->enabled) continue; @@ -249,6 +350,16 @@ itip_get_comp_attendee (ECalComponent *comp, ECal *client) e_cal_component_free_attendee_list (attendees); return user_email; } + + /* If the account was not found in the attendees list, then let's + check the 'sentby' fields of the attendees if we can find the account */ + attendee = get_attendee_if_attendee_sentby_is_user (attendees, a->id->address); + if (attendee) { + char *user_email = g_strdup (itip_strip_mailto (attendee->sentby)); + + e_cal_component_free_attendee_list (attendees); + return user_email; + } } /* We could not find the attendee in the component, so just give the default @@ -461,6 +572,7 @@ comp_to_list (ECalComponentItipMethod method, ECalComponent *comp, GList *users, _("An organizer must be set.")); return NULL; } + sender = itip_get_comp_attendee (comp, NULL); for (l = attendees; l != NULL; l = l->next) { @@ -468,15 +580,18 @@ comp_to_list (ECalComponentItipMethod method, ECalComponent *comp, GList *users, if (users_has_attendee (users, att->value)) continue; + else if (att->sentby && users_has_attendee (users, att->sentby)) + continue; else if (!g_ascii_strcasecmp (att->value, organizer.value)) continue; + else if (att->sentby && !g_ascii_strcasecmp (att->sentby, organizer.sentby)) + continue; else if (!g_ascii_strcasecmp (itip_strip_mailto (att->value), sender)) continue; else if (att->status == ICAL_PARTSTAT_DELEGATED && (att->delto && *att->delto) && !(att->rsvp) && method == E_CAL_COMPONENT_METHOD_REQUEST) continue; - - + recipient = &(to_list->_buffer[to_list->_length]); if (att->cn) recipient->name = CORBA_string_dup (att->cn); @@ -579,14 +694,14 @@ comp_to_list (ECalComponentItipMethod method, ECalComponent *comp, GList *users, recipient->name = CORBA_string_dup (""); recipient->address = CORBA_string_dup (itip_strip_mailto (organizer.value)); - /* send the status to delegatee to the delegate also*/ + /* send the status to delegatee to the delegate also*/ e_cal_component_get_attendee_list (comp, &attendees); sender = itip_get_comp_attendee (comp, NULL); for (l = attendees; l != NULL; l = l->next) { ECalComponentAttendee *att = l->data; - if (!g_ascii_strcasecmp (itip_strip_mailto (att->value), sender)){ + if (!g_ascii_strcasecmp (itip_strip_mailto (att->value), sender) || (att->sentby && !g_ascii_strcasecmp (itip_strip_mailto (att->sentby), sender))){ if (!(att->delfrom && *att->delfrom)) break; @@ -674,7 +789,7 @@ comp_subject (ECalComponentItipMethod method, ECalComponent *comp) for (l = alist; l != NULL ; l = l->next) { a = l->data; - if ((sender && *sender) && g_str_equal (itip_strip_mailto (a->value), sender)) + if ((sender && *sender) && (g_ascii_strcasecmp (itip_strip_mailto (a->value), sender) || (a->sentby && g_ascii_strcasecmp (itip_strip_mailto (a->sentby), sender)))) break; } g_free (sender); @@ -843,9 +958,11 @@ comp_limit_attendees (ECalComponent *comp) prop != NULL; prop = icalcomponent_get_next_property (icomp, ICAL_ATTENDEE_PROPERTY)) { - icalvalue *value; const char *attendee; - char *text; + char *attendee_text; + icalparameter *param; + const char *attendee_sentby; + char *attendee_sentby_text; /* If we've already found something, just erase the rest */ if (found) { @@ -853,16 +970,26 @@ comp_limit_attendees (ECalComponent *comp) continue; } - value = icalproperty_get_value (prop); - if (!value) + attendee = icalproperty_get_value_as_string (prop); + if (!attendee) continue; - attendee = icalvalue_get_string (value); + attendee_text = g_strdup (itip_strip_mailto (attendee)); + attendee_text = g_strstrip (attendee_text); + found = match = e_account_list_find(itip_addresses_get(), E_ACCOUNT_FIND_ID_ADDRESS, attendee_text) != NULL; + + if (!found) { + param = icalproperty_get_first_parameter (prop, ICAL_SENTBY_PARAMETER); + if (param) { + attendee_sentby = icalparameter_get_sentby (param); + attendee_sentby_text = g_strdup (itip_strip_mailto (attendee_sentby)); + attendee_sentby_text = g_strstrip (attendee_sentby_text); + found = match = e_account_list_find(itip_addresses_get(), E_ACCOUNT_FIND_ID_ADDRESS, attendee_sentby_text) != NULL; + } + } - text = g_strdup (itip_strip_mailto (attendee)); - text = g_strstrip (text); - found = match = e_account_list_find(itip_addresses_get(), E_ACCOUNT_FIND_ID_ADDRESS, text) != NULL; - g_free (text); + g_free(attendee_text); + g_free (attendee_sentby_text); if (!match) list = g_slist_prepend (list, prop); @@ -907,7 +1034,7 @@ comp_sentby (ECalComponent *comp, ECal *client) for (l = attendees; l; l = l->next) { ECalComponentAttendee *a = l->data; - if (g_str_equal (itip_strip_mailto (a->value), user)) { + if (!g_ascii_strcasecmp (itip_strip_mailto (a->value), user) || (a->sentby && !g_ascii_strcasecmp (itip_strip_mailto (a->sentby), user))) { g_free (user); return; } @@ -1178,7 +1305,7 @@ itip_send_comp (ECalComponentItipMethod method, ECalComponent *send_comp, CORBA_Environment ev; gboolean retval = FALSE; - /* check whether backend could handle sending resuests/updates */ + /* check whether backend could handle sending requests/updates */ if (method != E_CAL_COMPONENT_METHOD_PUBLISH && e_cal_get_save_schedules (client)) return TRUE; @@ -1186,12 +1313,14 @@ itip_send_comp (ECalComponentItipMethod method, ECalComponent *send_comp, /* Give the server a chance to manipulate the comp */ if (method != E_CAL_COMPONENT_METHOD_PUBLISH) { + sanitize_component (send_comp, client); if (!comp_server_send (method, send_comp, client, zones, &users)) goto cleanup; } /* Tidy up the comp */ comp = comp_compliant (method, send_comp, client, zones); + if (comp == NULL) goto cleanup; @@ -1243,7 +1372,6 @@ itip_send_comp (ECalComponentItipMethod method, ECalComponent *send_comp, top_level = comp_toplevel_with_zones (method, comp, client, zones); ical_string = icalcomponent_as_ical_string (top_level); - if (e_cal_component_get_vtype (comp) == E_CAL_COMPONENT_EVENT) { GNOME_Evolution_Composer_setBody (composer_server, ical_string, content_type, &ev); } else { @@ -1358,6 +1486,9 @@ reply_to_calendar_comp (ECalComponentItipMethod method, ECalComponent *send_comp CORBA_exception_init (&ev); + /* Sanitize the component */ + sanitize_component (send_comp, client); + /* Tidy up the comp */ comp = comp_compliant (method, send_comp, client, zones); if (comp == NULL) @@ -1375,15 +1506,7 @@ reply_to_calendar_comp (ECalComponentItipMethod method, ECalComponent *send_comp subject = comp_subject (method, comp); /* From address */ - { - GError *error = NULL; - char *address = NULL; - - if (e_cal_get_cal_address (client, &address, &error)) - from = CORBA_string_dup (address); - } - if (!from) - from = comp_from (method, comp); + from = comp_from (method, comp); /* Obtain an object reference for the Composer. */ composer_server = bonobo_activation_activate_from_id (GNOME_EVOLUTION_COMPOSER_OAFIID, 0, NULL, &ev); -- cgit