Skip to content

Commit

Permalink
Better error handling & added loggers
Browse files Browse the repository at this point in the history
Related to issues #5 and #7.
  • Loading branch information
darkgallium committed Jan 23, 2019
1 parent 6b6e2c5 commit a0c88e2
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 35 deletions.
2 changes: 1 addition & 1 deletion langate/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@


class DeviceSerializer(serializers.ModelSerializer):
name = serializers.SlugField(max_length=100)
name = serializers.RegexField("^[a-zA-Z0-9 _]+$", max_length=100)

class Meta:
model = Device
Expand Down
13 changes: 8 additions & 5 deletions langate/api/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.core.exceptions import PermissionDenied
from django.contrib.auth.models import User
from django.contrib.auth import logout
from django.conf import settings

from .serializers import DeviceSerializer, UserSerializer
Expand Down Expand Up @@ -69,15 +70,18 @@ def put(self, request, ident, format=None):

def delete(self, request, ident, format=None):

# Deleting the device you are currently on is not allowed via the API.
# Instead the user can log out from the portal.

client_ip = request.META.get('HTTP_X_FORWARDED_FOR')

dev = self.get_device(ident, request.user)

if dev.ip == client_ip:
raise APIException("Deleting your current device is not allowed via the API.")
# If the user decides to remove the device he is currently on,
# We remove the device and log him out.

dev.delete()
logout(request)

return Response(status=status.HTTP_204_NO_CONTENT)

else:
dev.delete()
Expand All @@ -98,7 +102,6 @@ def get_device(self, ident, user):
else:
raise PermissionDenied


def get(self, request, ident):

dev = self.get_device(ident, request.user)
Expand Down
46 changes: 46 additions & 0 deletions langate/langate/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,49 @@ class Tournament(Enum):
# Network management interface

NETWORK = network.Ipset()


# Logging settings

LOGGING = {
'version': 1,
'disable_existing_loggers': False,


'formatters': {
'verbose': {
'format': '{asctime} [{levelname}] [{module}] {message}',
'style': '{',
},
},

'handlers': {
'django_file': {
'level': 'INFO',
'class': 'logging.FileHandler',
'formatter': 'verbose',
'filename': os.path.join(BASE_DIR, 'logs/django.log'),
},

'langate_file': {
'level': 'INFO',
'class': 'logging.FileHandler',
'formatter': 'verbose',
'filename': os.path.join(BASE_DIR, 'logs/langate.log'),
},
},

'loggers': {
'django': {
'handlers': ['django_file'],
'level': 'DEBUG',
'propagate': True,
},

'langate.events': {
'handlers': ['langate_file'],
'level': 'DEBUG',
'propagate': True,
}
},
}
21 changes: 17 additions & 4 deletions langate/portal/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from enum import Enum

import logging
from django.contrib.auth.models import User
from django.db import models
from django.db.models.signals import post_save, post_delete
Expand All @@ -10,6 +11,7 @@

# Create your models here.

event_logger = logging.getLogger('langate.events')

class Role(Enum):
P = "Player"
Expand Down Expand Up @@ -56,15 +58,17 @@ class Device(models.Model):
# Area of the device, i.e. LAN or WiFi
area = models.CharField(max_length=4, default="LAN")

# FIXME : we should consider also the case when an user deletes its last device !

# Functions listening modifications of user
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
if(instance.is_staff):

if instance.is_staff:
event_logger.info("Added new user {} (with Administrator role).".format(instance.username))
Profile.objects.create(user=instance, role=Role.A.value)
else:
event_logger.info("Added new user {}.".format(instance.username))
Profile.objects.create(user=instance)


Expand All @@ -73,25 +77,34 @@ def save_user_profile(sender, instance, **kwargs):
instance.profile.save()


@receiver(post_delete, sender=User)
def delete_user(sender, instance, **kwargs):
event_logger.info("Removed user {}.".format(instance.username))


@receiver(post_save, sender=Device)
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 # FIXME : IP should exist at this stage but it will fail really bad if it doesn't, should we handle this ?
ip = instance.ip # IP should exist at this stage and it will fail really bad if it doesn't.

instance.mac = network.get_mac(ip)

instance.area = "LAN" # FIXME: replace with a call to the networking module

settings.NETWORK.connect_user(instance.mac)

event_logger.info("Connected device {} at {} to the internet.".format(instance.mac, instance.ip))

instance.save()



@receiver(post_delete, sender=Device)
def delete_device(sender, instance, **kwargs):
# When deleting a device, we need to unregister it from the network.

event_logger.info("Disconnected device {} at {} of the internet.".format(instance.mac, instance.ip))

settings.NETWORK.disconnect_user(instance.mac)
65 changes: 42 additions & 23 deletions langate/portal/templates/portal/connected.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ <h5 class="modal-title">Supprimer ?</h5>
</div>
</div>

<!-- Modal Modify Device -->

<div class="modal modal-insalan" id="modify-device-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg" role="document">
Expand All @@ -95,7 +96,7 @@ <h5 class="modal-title">Modifier un appareil</h5>
</div>
<div class="modal-body">
<div class="container">
<form>
<form id="modify-device-form" action="javascript:void(0);">
<div class="form-group row" id="create_account_nickname_g">
<label for="modify-device-name" class="col-sm-4 col-form-label">Nom de l'appareil : </label>
<input type="text" class="form-control col-sm-8" id="modify-device-name">
Expand All @@ -115,8 +116,11 @@ <h5 class="modal-title">Modifier un appareil</h5>

<script>
$(document).on("click", ".delete-device-btn", function (e) {
id = $(this).data("deviceid");
let id = $(this).data("deviceid");
let iscurrent = $(this).data("iscurrent");

$("#delete-device-confirm-btn").data("deviceid", id);
$("#delete-device-confirm-btn").data("iscurrent", iscurrent);

$.getJSON( "/api/device_details/"+id, function( data ) {
$("#delete-device-name").text(data["name"]);
Expand All @@ -126,6 +130,7 @@ <h5 class="modal-title">Modifier un appareil</h5>

$(document).on("click", ".modify-device-btn", function (e) {
$("#modify-device-confirm-btn").data("deviceid", $(this).data("deviceid"));
$("#modify-device-name").val("");
$("#modify-device-modal").modal("show");
});

Expand All @@ -138,20 +143,21 @@ <h5 class="modal-title">Modifier un appareil</h5>
$("#device-table").empty();

$.getJSON( "/api/devices_list/{{ user.id }}", function( data ) {
i = 1;
let i = 1;

$.each(data, function (k, dev) {

dev_hint = (dev.ip == current_ip) ? " <b>(cet appareil)</b>" : "";
let dev_hint = (dev.ip == current_ip) ? " <b>(cet appareil)</b>" : "";
let current_dev = (dev.ip == current_ip) ? "yes" : "no";

$("#device-table").append("<tr>\n" +
" <th scope=\"row\">"+i+"</th>\n" +
" <td>"+dev.name+dev_hint+"</td>\n" +
" <td>"+dev.area+"</td>\n" +
" <td>\n" +
" <div class=\"text-center\" role=\"group\" aria-label=\"Actions\">\n" +
" <button type=\"button\" data-toggle=\"tooltip\" data-placement=\"bottom\" title=\"Modifier l'appareil\" class=\"btn btn-sec-insalan modify-device-btn\" data-deviceid=\""+dev.id+"\"><span class=\"fas fa-pen\" aria-hidden=\"true\"></span></button>\n" +
" <button type=\"button\" data-toggle=\"tooltip\" data-placement=\"bottom\" title=\"Supprimer l'appareil\" class=\"btn btn-sec-insalan delete-device-btn\" data-deviceid=\""+dev.id+"\" aria-label=\"Supprimer l'appareil\"><span class=\"fas fa-trash\" aria-hidden=\"true\"></span></button>\n" +
" <button type=\"button\" data-toggle=\"tooltip\" data-placement=\"bottom\" title=\"Modifier l'appareil\" class=\"btn btn-sec-insalan modify-device-btn\" data-deviceid=\""+dev.id+"\" data-iscurrent=\""+current_dev+"\"><span class=\"fas fa-pen\" aria-hidden=\"true\"></span></button>\n" +
" <button type=\"button\" data-toggle=\"tooltip\" data-placement=\"bottom\" title=\"Supprimer l'appareil\" class=\"btn btn-sec-insalan delete-device-btn\" data-deviceid=\""+dev.id+"\" data-iscurrent=\""+current_dev+"\" aria-label=\"Supprimer l'appareil\"><span class=\"fas fa-trash\" aria-hidden=\"true\"></span></button>\n" +
" </div>\n" +
" </td>\n" +
" </tr>");
Expand All @@ -176,46 +182,61 @@ <h5 class="modal-title">Modifier un appareil</h5>
$("#delete-device-confirm-btn").click( function () {

let id = $(this).data("deviceid");
let iscurrent = $(this).data("iscurrent") == "yes";

$.ajax({
url: '/api/device_details/'+id+'/',
url: '/api/device_details/' + id + '/',
type: 'DELETE',

success: function(result) {
success: function (result) {

if (too_many_devices) {
if (too_many_devices || iscurrent) {
location.reload();
}

else {
reload_device_table();
}
},

error: function (xhr, textStatus, errorThrown) {
handle_error(textStatus, errorThrown, xhr.responseText);
}

// TODO: Handle errors
});


$("#delete-device-modal").modal('hide');


});

$("#modify-device-confirm-btn").click( function () {

let id = $(this).data("deviceid");

$.ajax({
url: '/api/device_details/'+id+'/',
type: 'PUT',
data: "name="+encodeURI($("#modify-device-name").val()),
if (!/^[a-zA-Z0-9 _]+$/.test($("#modify-device-name").val())){
create_error_modal("Oops", "<p>Le nom d'un appareil doit faire au moins un caractère et ne se compose que de caractères alphanumériques non accentués et d'espaces.</p>");
}

success: function(result) {
reload_device_table();
}
else {

// TODO: Handle errors
});
let id = $(this).data("deviceid");

$.ajax({
url: '/api/device_details/' + id + '/',
type: 'PUT',
data: "name=" + encodeURI($("#modify-device-name").val()),

success: function (result) {
reload_device_table();
},

error: function (xhr, textStatus, errorThrown) {
handle_error(textStatus, errorThrown, xhr.responseText);
}
});


}

$("#modify-device-modal").modal('hide');

Expand All @@ -225,9 +246,7 @@ <h5 class="modal-title">Modifier un appareil</h5>

$(document).ready(function() {
reload_device_table();
});

$(document).ready(function() {
$("#device-table").tooltip({offset: "5px, 5px", selector: '[data-toggle=tooltip]' });
});

Expand Down
3 changes: 1 addition & 2 deletions langate/portal/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ def connected(request):
# 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)


Expand All @@ -92,6 +90,7 @@ def disconnect(request):

return redirect(settings.LOGIN_URL)


def faq(request):

context = {"page_name": "faq", "widgets": settings.WIDGETS}
Expand Down
Loading

0 comments on commit a0c88e2

Please sign in to comment.