diff options
author | Thomas Haller <thaller@redhat.com> | 2016-06-08 13:23:49 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2016-06-13 10:51:17 +0200 |
commit | 7a2b964d6ac3f8407fa82e832e7e1a7550ba2c02 (patch) | |
tree | af7f834efb45d98ddb1e97cefddd187d1ae1030a | |
parent | 84b5f20a73d1754013d130b590ca84b80017507b (diff) | |
download | network-manager-applet-th/vpn-service-info-bgo767197-1.tar.gz |
c-e: support multiple "Add VPN connection" entires per service-typeth/vpn-service-info-bgo767197-1
For one given service-type, the UI shall be able to show multiple
entires in the list for creating a new connection.
This works by asking the plugin whether it supports multiple
"add-details". And if so, create an entry for each add-detail.
When adding a VPN connection, the editor creates a NMConnection
with initializing vpn.service-type and setting the add-detail to a
key according to the plugin's instruction.
For example, nm-openvpn supports multiple "vpn.connection-type" such as
"tls", "static-key", "password", "password-tls". With this change, it could
generate an entry for each type in nm-c-e's connection-add list. To do
that, it should announce add-details to be "tls", "static-key",
"password", "password-tls", and the "add-detail-key" to be "connection-type".
This functionality is not accessible via
$ nm-connection-editor -c -t vpn:<SERVICE_TYPE>:<ADD_DETAIL>
-rw-r--r-- | src/connection-editor/ce-new-connection.ui | 6 | ||||
-rw-r--r-- | src/connection-editor/connection-helpers.c | 106 | ||||
-rw-r--r-- | src/connection-editor/page-vpn.c | 5 | ||||
-rw-r--r-- | src/connection-editor/page-vpn.h | 5 |
4 files changed, 104 insertions, 18 deletions
diff --git a/src/connection-editor/ce-new-connection.ui b/src/connection-editor/ce-new-connection.ui index c9dfa547..66e9ae86 100644 --- a/src/connection-editor/ce-new-connection.ui +++ b/src/connection-editor/ce-new-connection.ui @@ -16,6 +16,12 @@ <column type="GObject"/> <!-- column-name vpn_service_type, COL_VPN_SERVICE_TYPE --> <column type="gchararray"/> + <!-- column-name add_detail, COL_VPN_ADD_DETAIL --> + <column type="gchararray"/> + <!-- column-name add_detail_key, COL_VPN_ADD_DETAIL_KEY --> + <column type="gchararray"/> + <!-- column-name add_detail_val, COL_VPN_ADD_DETAIL_VAL --> + <column type="gchararray"/> </columns> </object> <object class="GtkDialog" id="new_connection_type_dialog"> diff --git a/src/connection-editor/connection-helpers.c b/src/connection-editor/connection-helpers.c index 44921b18..177af4e9 100644 --- a/src/connection-editor/connection-helpers.c +++ b/src/connection-editor/connection-helpers.c @@ -43,6 +43,9 @@ #define COL_DESCRIPTION 3 #define COL_VPN_PLUGIN 4 #define COL_VPN_SERVICE_TYPE 5 +#define COL_VPN_ADD_DETAIL 6 +#define COL_VPN_ADD_DETAIL_KEY 7 +#define COL_VPN_ADD_DETAIL_VAL 8 static gint sort_types (gconstpointer a, gconstpointer b) @@ -273,9 +276,12 @@ set_up_connection_type_combo (GtkComboBox *combo, gs_free char *pretty_name = NULL; gs_free char *description = NULL; NMVpnEditorPluginServiceFlags flags; + gs_strfreev char **add_details_free = NULL; + char **add_details; + const char *i_add_detail; if (!nm_vpn_editor_plugin_get_service_info (plugin, service_type, NULL, &pretty_name, &description, &flags)) { - if (!is_alias) + if (is_alias) goto next; g_object_get (plugin, NM_VPN_EDITOR_PLUGIN_NAME, &pretty_name, @@ -288,21 +294,71 @@ set_up_connection_type_combo (GtkComboBox *combo, if (!NM_FLAGS_HAS (flags, NM_VPN_EDITOR_PLUGIN_SERVICE_FLAGS_CAN_ADD)) goto next; - if (show_headers) - markup = g_markup_printf_escaped (" %s", pretty_name); - else - markup = g_markup_escape_text (pretty_name, -1); - - gtk_list_store_append (model, &iter); - gtk_list_store_set (model, &iter, - COL_MARKUP, markup, - COL_SENSITIVE, TRUE, - COL_NEW_FUNC, list[vpn_index].new_connection_func, - COL_DESCRIPTION, description, - COL_VPN_PLUGIN, plugin, - COL_VPN_SERVICE_TYPE, service_type, - -1); - g_free (markup); + add_details_free = nm_vpn_editor_plugin_get_service_add_details (plugin, service_type); + add_details = add_details_free; + i_add_detail = add_details ? add_details[0] : NULL; + do { + const char *i_pretty_name, *i_description; + gs_free char *i_pretty_name_free = NULL; + gs_free char *i_description_free = NULL; + gs_free char *i_add_detail_key = NULL; + gs_free char *i_add_detail_val = NULL; + + if (i_add_detail) { + if (i_add_detail[0] == '\0') + goto i_next; + if (!nm_vpn_editor_plugin_get_service_add_detail (plugin, service_type, i_add_detail, + &i_pretty_name_free, &i_description_free, + &i_add_detail_key, &i_add_detail_val, NULL)) + goto i_next; + if (!i_add_detail_key || i_add_detail_key[0] == '\0') { + /* currently, the only way for a plugin to know the add-detail of a new connection + * is by returning an "add-detail-key", which then is set in the VPN connection. + * + * We could imaging other schemes, to notify the plugin which connection is to be + * created. This one is sufficient for now, so as is, a plugin must return an + * "add-detail-key", otherwise it cannot work. */ + goto i_next; + } + if (!i_add_detail_val) + i_add_detail_val = g_strdup (i_add_detail); + if (!i_add_detail_val[0]) { + /* nm_setting_vpn_add_data_item() doesn't allow empty values (??). */ + goto i_next; + } + if (!i_pretty_name_free) + goto i_next; + i_pretty_name = i_pretty_name_free; + i_description = i_description_free; + } else { + i_pretty_name = pretty_name; + i_description = description; + } + + if (show_headers) + markup = g_markup_printf_escaped (" %s", i_pretty_name); + else + markup = g_markup_escape_text (i_pretty_name, -1); + + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, + COL_MARKUP, markup, + COL_SENSITIVE, TRUE, + COL_NEW_FUNC, list[vpn_index].new_connection_func, + COL_DESCRIPTION, i_description, + COL_VPN_PLUGIN, plugin, + COL_VPN_SERVICE_TYPE, service_type, + COL_VPN_ADD_DETAIL, i_add_detail, + COL_VPN_ADD_DETAIL_KEY, i_add_detail_key, + COL_VPN_ADD_DETAIL_VAL, i_add_detail_val, + -1); + g_free (markup); + +i_next: + if (!add_details) + break; + i_add_detail = (++add_details)[0]; + } while (i_add_detail); next: if (!aliases || !aliases[0]) @@ -426,8 +482,13 @@ new_connection_dialog_full (GtkWindow *parent_window, int response; PageNewConnectionFunc new_func = NULL; gs_free char *vpn_service_type = NULL; + gs_free char *vpn_add_detail = NULL; + gs_free char *vpn_add_detail_key = NULL; + gs_free char *vpn_add_detail_val = NULL; const char *detail = NULL; + gpointer detail_data = NULL; GError *error = NULL; + CEPageVpnDetailData vpn_data; /* load GUI */ gui = gtk_builder_new (); @@ -462,16 +523,25 @@ new_connection_dialog_full (GtkWindow *parent_window, gtk_tree_model_get (gtk_combo_box_get_model (combo), &iter, COL_NEW_FUNC, &new_func, COL_VPN_SERVICE_TYPE, &vpn_service_type, + COL_VPN_ADD_DETAIL, &vpn_add_detail, + COL_VPN_ADD_DETAIL_KEY, &vpn_add_detail_key, + COL_VPN_ADD_DETAIL_VAL, &vpn_add_detail_val, -1); - if (vpn_service_type) + if (vpn_service_type) { + memset (&vpn_data, 0, sizeof (vpn_data)); + vpn_data.add_detail_key = vpn_add_detail_key; + vpn_data.add_detail_val = vpn_add_detail_val; + detail = vpn_service_type; + detail_data = &vpn_data; + } } gtk_widget_destroy (GTK_WIDGET (type_dialog)); g_object_unref (gui); if (new_func) - new_connection_of_type (parent_window, detail, NULL, client, new_func, result_func, user_data); + new_connection_of_type (parent_window, detail, detail_data, client, new_func, result_func, user_data); else result_func (NULL, user_data); } diff --git a/src/connection-editor/page-vpn.c b/src/connection-editor/page-vpn.c index 4b4a45dd..3d379ecf 100644 --- a/src/connection-editor/page-vpn.c +++ b/src/connection-editor/page-vpn.c @@ -290,6 +290,7 @@ vpn_connection_new (GtkWindow *parent, NMSetting *s_vpn; const char *service_type; gs_free char *service_type_free = NULL; + const CEPageVpnDetailData *data = detail_data; if (!detail) { NewVpnInfo *info; @@ -319,6 +320,10 @@ vpn_connection_new (GtkWindow *parent, user_data); s_vpn = nm_setting_vpn_new (); g_object_set (s_vpn, NM_SETTING_VPN_SERVICE_TYPE, service_type, NULL); + + if (data && data->add_detail_key) + nm_setting_vpn_add_data_item ((NMSettingVpn *) s_vpn, data->add_detail_key, data->add_detail_val); + nm_connection_add_setting (connection, s_vpn); (*result_func) (connection, FALSE, NULL, user_data); diff --git a/src/connection-editor/page-vpn.h b/src/connection-editor/page-vpn.h index e8dddf0e..4564efdd 100644 --- a/src/connection-editor/page-vpn.h +++ b/src/connection-editor/page-vpn.h @@ -43,6 +43,11 @@ typedef struct { CEPageClass parent; } CEPageVpnClass; +typedef struct { + char *add_detail_key; + char *add_detail_val; +} CEPageVpnDetailData; + GType ce_page_vpn_get_type (void); CEPage *ce_page_vpn_new (NMConnectionEditor *editor, |