def create_whitelist_device(sender, instance, created, **kwargs): # On creating a new device, we need to use the networking module to retrieve # some information : for example the MAC address or the area of the device based on the IP. if created: mac = instance.mac name = instance.name netcontrol.query("connect_user", { "mac": instance.mac, "name": instance.name }) event_logger.info("Connected device {} (the mac {} has been connected)".format(instance.mac, instance.name)) instance.save()
def ready(self): from portal.models import WhiteListDevice, Device # the HACK below is brought to you by # https://stackoverflow.com/questions/6791911/execute-code-when-django-starts-once-only if not any(x in sys.argv for x in [ 'makemigrations', 'migrate', 'shell', 'createsuperuser', 'flush', 'collectstatic' ]): print("[PortalConfig] Adding whitelisted devices to the ipset") # Connecting whitelisted devices for dev in WhiteListDevice.objects.all(): connect_res = netcontrol.query("connect_user", { "mac": dev.mac, "name": dev.name }) if not connect_res["success"]: print("[PortalConfig] Could not connect device {}".format( dev.name)) mark_res = netcontrol.query("set_mark", { "mac": dev.mac, "mark": 0 }) if not mark_res["success"]: print("[PortalConfig] Could not set mark 0 for device {}". format(dev.name)) # Reconnecting devices registered in the Device set but not in the Ipset # This is important when for example the Ipset is flushed, you want the users that are already # registered on the gate to be automatically reconnected when the gate restarts. # This is important to maintain the consistency between the device state from django's point of view and # and the device state from the Ipset's point of view. print( "[PortalConfig] Adding previously connected devices to the ipset" ) for dev in Device.objects.all(): connect_res = netcontrol.query("connect_user", { "mac": dev.mac, "name": dev.name }) if not connect_res["success"]: print( "[PortalConfig] Could not connect device {} owned by user {}" .format(dev.mac, dev.user.username))
def get(self, request, ident): dev = self.get_device(ident, request.user) r = netcontrol.query("get_user_info", {"mac": dev.mac}) info = r["info"] # FIXME: was removed from langate2000-netcontrol return Response({"mark": info["mark"]})
def get(self, request, ident, mark): if Device.objects.filter(id=ident).count() > 0: dev = Device.objects.get(id=ident) r = netcontrol.query("set_mark", {"mac": dev.mac, "mark": mark}) if r["success"]: return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
def create_device(sender, instance, created, **kwargs): # On creating a new device, we need to use the networking module to retrieve # some information : for example the MAC address or the area of the device based on the IP. if created: ip = instance.ip # IP should exist at this stage and it will fail really bad if it doesn't. instance.name = generate_dev_name() r = netcontrol.query("get_mac", { "ip": ip }) instance.mac = r["mac"] instance.area = "LAN" # FIXME: replace with a call to the networking module netcontrol.query("connect_user", { "mac": instance.mac, "name": instance.user.username }) event_logger.info("Connected device {} (owned by {}) at {} to the internet.".format(instance.mac, instance.user.username, instance.ip)) instance.save()
def connected(request): user_devices = Device.objects.filter(user=request.user) client_ip = request.META.get('HTTP_X_FORWARDED_FOR') context = {"page_name": "connected", "too_many_devices": False, "current_ip": client_ip, "is_announce_panel_visible": Announces.objects.filter(visible=True).count() > 0, "pinned_announces": Announces.objects.filter(pinned=True).order_by('-last_update_date'), "announces": Announces.objects.filter(pinned=False).order_by('-last_update_date'), "device_quota": request.user.profile.max_device_nb} # Checking if the device accessing the gate is already in user devices if not user_devices.filter(ip=client_ip).exists(): #client_mac = network.get_mac(client_ip) r = netcontrol.query("get_mac", { "ip": client_ip }) client_mac = r["mac"] if Device.objects.filter(mac=client_mac).count() > 0: # If the device MAC is already registered on the network but with a different IP, # * If the registered device is owned by the requesting user, we change the IP of the registered device. # * If the registered device is owned by another user, we delete the old device and we register the new one. # This could happen if the DHCP has changed the IP of the client. # The following should never raise a MultipleObjectsReturned exception # because it would mean that there are more than one devices # already registered with the same MAC. dev = Device.objects.get(mac=client_mac) if request.user != dev.user: dev.delete() new_dev = Device(user=request.user, ip=client_ip) new_dev.save() else: dev.ip = client_ip # We edit the IP to reflect the change. dev.save() elif len(user_devices) >= request.user.profile.max_device_nb: # If user has too much devices already registered, then we can't connect the device to the internet. # We will let him choose to remove one of them. context["too_many_devices"] = True else: # We can add the client device to the user devices. # See the networking functions in the receivers in portal/models.py dev = Device(user=request.user, ip=client_ip) dev.save() # TODO: What shall we do if an user attempts to connect with a device that has the same IP # that another device already registered (ie in the Device array) but from a different user account ? # We could either kick out the already registered user from the network or refuse the connection of # the device that attempts to connect. return render(request, 'portal/connected.html', context)
def delete_whitelist_device(sender, instance, **kwargs): # When deleting a device, we need to unregister it from the network. event_logger.info("Disconnected device {} (the mac {} has been disconnected) ".format(instance.mac, instance.name)) netcontrol.query("disconnect_user", { "mac": instance.mac })
def delete_device(sender, instance, **kwargs): # When deleting a device, we need to unregister it from the network. event_logger.info("Disconnected device {} (owned by {}) at {} of the internet.".format(instance.mac, instance.user.username, instance.ip)) netcontrol.query("disconnect_user", { "mac": instance.mac })