diff --git a/plinth/modules/networks/forms.py b/plinth/modules/networks/forms.py index c80e05530..3467895c5 100644 --- a/plinth/modules/networks/forms.py +++ b/plinth/modules/networks/forms.py @@ -24,9 +24,10 @@ from plinth import network class ConnectionTypeSelectForm(forms.Form): """Form to select type for new connection.""" - conn_type = forms.ChoiceField( + connection_type = forms.ChoiceField( label=_('Connection Type'), - choices=[(k, v) for k, v in network.CONNECTION_TYPE_NAMES.items()]) + choices=[(key, value) + for key, value in network.CONNECTION_TYPE_NAMES.items()]) class AddEthernetForm(forms.Form): diff --git a/plinth/modules/networks/networks.py b/plinth/modules/networks/networks.py index 8054a1413..24e996197 100644 --- a/plinth/modules/networks/networks.py +++ b/plinth/modules/networks/networks.py @@ -21,11 +21,11 @@ from django.core.urlresolvers import reverse_lazy from django.shortcuts import redirect from django.template.response import TemplateResponse from gettext import gettext as _ -import urllib from .forms import ConnectionTypeSelectForm, AddEthernetForm, AddWifiForm from plinth import cfg from plinth import network +from plinth import package subsubmenu = [{'url': reverse_lazy('networks:index'), @@ -43,6 +43,7 @@ def init(): @login_required +@package.required(['network-manager']) def index(request): """Show connection list.""" connections = network.get_connection_list() @@ -72,6 +73,7 @@ def edit(request, uuid): form = AddWifiForm(request.POST) else: form = AddEthernetForm(request.POST) + if form.is_valid(): name = form.cleaned_data['name'] zone = form.cleaned_data['zone'] @@ -93,11 +95,7 @@ def edit(request, uuid): connection, name, zone, ssid, mode, auth_mode, passphrase, ipv4_method, ipv4_address) - else: - messages.error( - request, - _('Cannot edit connection %s: ' - 'Connection type not supported.') % name) + return redirect(reverse_lazy('networks:index')) else: return TemplateResponse(request, 'connections_edit.html', @@ -176,50 +174,12 @@ def deactivate(request, uuid): @login_required def scan(request): - """Show a list of nearby visible wifi APs.""" - aps = network.wifi_scan() + """Show a list of nearby visible Wi-Fi access points.""" + access_points = network.wifi_scan() return TemplateResponse(request, 'wifi_scan.html', {'title': _('Nearby Wi-Fi Networks'), 'subsubmenu': subsubmenu, - 'aps': aps}) - - -@login_required -def connect(request, connect_path): - """Create a new wifi connection to an existing AP.""" - form = None - ssid = urllib.parse.unquote_plus(connect_path) - form_data = {'name': ssid, - 'zone': 'external', - 'ssid': ssid, - 'mode': 'infrastructure', - 'auth_mode': 'wpa', - 'ipv4_method': 'auto'} - - if request.method == 'POST': - form = AddWifiForm(request.POST) - if form.is_valid(): - name = form.cleaned_data['name'] - zone = form.cleaned_data['zone'] - ssid = form.cleaned_data['ssid'] - mode = form.cleaned_data['mode'] - auth_mode = form.cleaned_data['auth_mode'] - passphrase = form.cleaned_data['passphrase'] - ipv4_method = form.cleaned_data['ipv4_method'] - ipv4_address = form.cleaned_data['ipv4_address'] - - network.add_wifi_connection( - name, zone, - ssid, mode, auth_mode, passphrase, - ipv4_method, ipv4_address) - return redirect(reverse_lazy('networks:index')) - else: - form = AddWifiForm(form_data) - - return TemplateResponse(request, 'connections_create.html', - {'title': _('Connect to Wi-Fi Network'), - 'subsubmenu': subsubmenu, - 'form': form}) + 'access_points': access_points}) @login_required @@ -230,10 +190,10 @@ def add(request): if request.method == 'POST': form = ConnectionTypeSelectForm(request.POST) if form.is_valid(): - conn_type = form.cleaned_data['conn_type'] - if conn_type == '802-3-ethernet': + connection_type = form.cleaned_data['connection_type'] + if connection_type == '802-3-ethernet': return redirect(reverse_lazy('networks:add_ethernet')) - elif conn_type == '802-11-wireless': + elif connection_type == '802-11-wireless': return redirect(reverse_lazy('networks:add_wifi')) else: form = ConnectionTypeSelectForm() @@ -264,15 +224,24 @@ def add_ethernet(request): form = AddEthernetForm() return TemplateResponse(request, 'connections_create.html', - {'title': _('Editing New Ethernet Connection'), + {'title': _('Adding New Ethernet Connection'), 'subsubmenu': subsubmenu, 'form': form}) @login_required -def add_wifi(request): +def add_wifi(request, ssid=None): """Serve wifi connection create form.""" form = None + form_data = None + + if ssid: + form_data = {'name': ssid, + 'zone': 'external', + 'ssid': ssid, + 'mode': 'infrastructure', + 'auth_mode': 'wpa', + 'ipv4_method': 'auto'} if request.method == 'POST': form = AddWifiForm(request.POST) @@ -292,10 +261,13 @@ def add_wifi(request): ipv4_method, ipv4_address) return redirect(reverse_lazy('networks:index')) else: - form = AddWifiForm() + if form_data: + form = AddWifiForm(form_data) + else: + form = AddWifiForm() return TemplateResponse(request, 'connections_create.html', - {'title': _('Editing New Wi-Fi Connection'), + {'title': _('Adding New Wi-Fi Connection'), 'subsubmenu': subsubmenu, 'form': form}) diff --git a/plinth/modules/networks/templates/wifi_scan.html b/plinth/modules/networks/templates/wifi_scan.html index 82bee5ae2..54a7a38e8 100644 --- a/plinth/modules/networks/templates/wifi_scan.html +++ b/plinth/modules/networks/templates/wifi_scan.html @@ -25,14 +25,18 @@
- {% for ap in aps %} + {% for access_point in access_points %}
+ {% if access_point.ssid %} - {{ ap.ssid }} + href="{% url 'networks:add_wifi' access_point.ssid %}"> + {{ access_point.ssid }} + {% else %} + -- + {% endif %} - {{ ap.strength }}% + {{ access_point.strength }}%
{% endfor %} diff --git a/plinth/modules/networks/urls.py b/plinth/modules/networks/urls.py index e84a041d1..9ced17d2b 100644 --- a/plinth/modules/networks/urls.py +++ b/plinth/modules/networks/urls.py @@ -32,11 +32,10 @@ urlpatterns = patterns( url(r'^sys/networks/(?P[\w.@+-]+)/deactivate/$', 'deactivate', name='deactivate'), url(r'^sys/networks/scan/$', 'scan', name='scan'), - url(r'^sys/networks/connect/(?P[\w.@+-]+)/$', - 'connect', name='connect'), url(r'^sys/networks/add/$', 'add', name='add'), url(r'^sys/networks/add/ethernet/$', 'add_ethernet', name='add_ethernet'), - url(r'^sys/networks/add/wifi/$', 'add_wifi', name='add_wifi'), + url(r'^sys/networks/add/wifi/(?:(?P[^/]+)/)?$', 'add_wifi', + name='add_wifi'), url(r'^sys/networks/(?P[\w.@+-]+)/delete/$', 'delete', name='delete'), ) diff --git a/plinth/network.py b/plinth/network.py index d6a579e13..fdb00adf2 100644 --- a/plinth/network.py +++ b/plinth/network.py @@ -23,7 +23,6 @@ from dbus.exceptions import DBusException import logging import NetworkManager import uuid -import urllib logger = logging.getLogger(__name__) @@ -102,39 +101,54 @@ def get_active_connection(uuid): raise ConnectionNotFound(uuid) -def edit_ethernet_connection(conn, name, zone, ipv4_method, ipv4_address): - settings = conn.GetSettings() - - new_settings = { +def _create_ethernet_settings(uuid, name, zone, ipv4_method, ipv4_address): + """Create an Ethernet setting structure in network manager format.""" + settings = { 'connection': { 'id': name, - 'type': settings['connection']['type'], + 'type': '802-3-ethernet', 'zone': zone, - 'uuid': settings['connection']['uuid'], + 'uuid': uuid, }, '802-3-ethernet': {}, 'ipv4': {'method': ipv4_method}, } + if ipv4_method == 'manual' and ipv4_address: - new_settings['ipv4']['addresses'] = [ + settings['ipv4']['addresses'] = [ (ipv4_address, 24, # CIDR prefix length '0.0.0.0')] # gateway - conn.Update(new_settings) + return settings -def edit_wifi_connection(conn, name, zone, - ssid, mode, auth_mode, passphrase, - ipv4_method, ipv4_address): - settings = conn.GetSettings() +def add_ethernet_connection(name, zone, ipv4_method, ipv4_address): + """Add an automatic ethernet connection in network manager.""" + settings = _create_ethernet_settings( + str(uuid.uuid4()), name, zone, ipv4_method, ipv4_address) + NetworkManager.Settings.AddConnection(settings) + return settings - new_settings = { + +def edit_ethernet_connection(connection, name, zone, ipv4_method, + ipv4_address): + """Edit an existing ethernet connection in network manager.""" + settings = connection.GetSettings() + new_settings = _create_ethernet_settings( + settings['connection']['uuid'], name, zone, ipv4_method, ipv4_address) + connection.Update(new_settings) + + +def _create_wifi_settings(uuid, name, zone, ssid, mode, auth_mode, passphrase, + ipv4_method, ipv4_address): + """Create a Wi-Fi settings structure in network manager format.""" + settings = { 'connection': { 'id': name, - 'type': settings['connection']['type'], + 'type': '802-11-wireless', 'zone': zone, - 'uuid': settings['connection']['uuid'], + 'uuid': uuid, }, '802-11-wireless': { 'ssid': ssid, @@ -144,19 +158,41 @@ def edit_wifi_connection(conn, name, zone, } if auth_mode == 'wpa' and passphrase: - new_settings['connection']['security'] = '802-11-wireless-security' - new_settings['802-11-wireless-security'] = { + settings['connection']['security'] = '802-11-wireless-security' + settings['802-11-wireless-security'] = { 'key-mgmt': 'wpa-psk', 'psk': passphrase, } if ipv4_method == 'manual' and ipv4_address: - new_settings['ipv4']['addresses'] = [ + settings['ipv4']['addresses'] = [ (ipv4_address, 24, # CIDR prefix length '0.0.0.0')] # gateway - conn.Update(new_settings) + return settings + + +def add_wifi_connection(name, zone, + ssid, mode, auth_mode, passphrase, + ipv4_method, ipv4_address): + """Add an automatic Wi-Fi connection in network manager.""" + settings = _create_wifi_settings( + str(uuid.uuid4()), name, zone, ssid, mode, auth_mode, passphrase, + ipv4_method, ipv4_address) + NetworkManager.Settings.AddConnection(settings) + return settings + + +def edit_wifi_connection(connection, name, zone, + ssid, mode, auth_mode, passphrase, + ipv4_method, ipv4_address): + """Edit an existing wifi connection in network manager.""" + settings = connection.GetSettings() + new_settings = _create_wifi_settings( + settings['connection']['uuid'], name, zone, ssid, mode, auth_mode, + passphrase, ipv4_method, ipv4_address) + connection.Update(new_settings) def activate_connection(uuid): @@ -198,74 +234,27 @@ def deactivate_connection(name): return active_connection -def add_ethernet_connection(name, zone, ipv4_method, ipv4_address): - conn = { - 'connection': { - 'id': name, - 'type': '802-3-ethernet', - 'zone': zone, - 'uuid': str(uuid.uuid4()), - }, - '802-3-ethernet': {}, - 'ipv4': {'method': ipv4_method}, - } +def delete_connection(uuid): + """Delete an exiting connection from network manager. - if ipv4_method == 'manual' and ipv4_address: - conn['ipv4']['addresses'] = [ - (ipv4_address, - 24, # CIDR prefix length - '0.0.0.0')] # gateway - - NetworkManager.Settings.AddConnection(conn) - - -def add_wifi_connection(name, zone, - ssid, mode, auth_mode, passphrase, - ipv4_method, ipv4_address): - conn = { - 'connection': { - 'id': name, - 'type': '802-11-wireless', - 'zone': zone, - 'uuid': str(uuid.uuid4()), - }, - '802-11-wireless': { - 'ssid': ssid, - 'mode': mode, - }, - 'ipv4': {'method': ipv4_method}, - } - - if auth_mode == 'wpa' and passphrase: - conn['connection']['security'] = '802-11-wireless-security' - conn['802-11-wireless-security'] = { - 'key-mgmt': 'wpa-psk', - 'psk': passphrase, - } - - if ipv4_method == 'manual' and ipv4_address: - conn['ipv4']['addresses'] = [ - (ipv4_address, - 24, # CIDR prefix length - '0.0.0.0')] # gateway - - NetworkManager.Settings.AddConnection(conn) - - -def delete_connection(name): - connection = get_connection(name) + Raise ConnectionNotFound if connection does not exist. + """ + connection = get_connection(uuid) name = connection.GetSettings()['connection']['id'] connection.Delete() return name def wifi_scan(): - aps = [] - for dev in NetworkManager.NetworkManager.GetDevices(): - if dev.DeviceType != NetworkManager.NM_DEVICE_TYPE_WIFI: + """Scan for available access points across all Wi-Fi devices.""" + access_points = [] + for device in NetworkManager.NetworkManager.GetDevices(): + if device.DeviceType != NetworkManager.NM_DEVICE_TYPE_WIFI: continue - for ap in dev.SpecificDevice().GetAccessPoints(): - aps.append({'ssid': ap.Ssid, - 'connect_path': urllib.parse.quote_plus(ap.Ssid), - 'strength': ord(ap.Strength)}) - return aps + + for access_point in device.SpecificDevice().GetAllAccessPoints(): + access_points.append({ + 'ssid': access_point.Ssid, + 'strength': access_point.Strength}) + + return access_points