2019-04-16 08:50:04 +00:00
|
|
|
from django.utils import timezone
|
2018-11-25 15:05:26 +00:00
|
|
|
from django.db import models
|
|
|
|
from django.conf import settings
|
2019-04-16 08:50:04 +00:00
|
|
|
|
2019-03-15 18:06:05 +00:00
|
|
|
from macaddress.fields import MACAddressField
|
2019-02-01 15:06:37 +00:00
|
|
|
import uuid
|
2019-04-16 08:50:04 +00:00
|
|
|
import glob
|
|
|
|
import os
|
2019-04-21 08:38:36 +00:00
|
|
|
from datetime import datetime
|
|
|
|
|
2018-11-25 15:05:26 +00:00
|
|
|
|
2018-11-25 21:02:16 +00:00
|
|
|
def getRandom():
|
2018-11-25 15:05:26 +00:00
|
|
|
return str(uuid.uuid4().hex)
|
|
|
|
|
2019-04-21 08:38:36 +00:00
|
|
|
|
2018-11-25 15:05:26 +00:00
|
|
|
class Organization(models.Model):
|
2019-04-21 08:38:36 +00:00
|
|
|
name = models.CharField(
|
|
|
|
"Organization Name",
|
|
|
|
max_length=300
|
|
|
|
)
|
|
|
|
|
|
|
|
users = models.ManyToManyField(
|
|
|
|
settings.AUTH_USER_MODEL
|
|
|
|
)
|
|
|
|
|
|
|
|
userlimit = models.IntegerField(
|
|
|
|
"User Limit",
|
|
|
|
null=True,
|
|
|
|
blank=True
|
|
|
|
)
|
2018-11-25 15:05:26 +00:00
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.name
|
|
|
|
|
2019-03-10 11:45:35 +00:00
|
|
|
def orgausers(self):
|
|
|
|
return self.users.filter(is_superuser=False)
|
|
|
|
|
2019-04-21 08:38:36 +00:00
|
|
|
|
2018-11-25 21:02:16 +00:00
|
|
|
class Network(models.Model):
|
2019-04-21 08:38:36 +00:00
|
|
|
name = models.CharField(
|
|
|
|
max_length=64,
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
|
|
|
extip = models.CharField(
|
|
|
|
"External/Public IP",
|
|
|
|
max_length=15,
|
|
|
|
unique=True
|
|
|
|
)
|
|
|
|
|
|
|
|
intip = models.CharField(
|
|
|
|
"Internal/Private IP",
|
|
|
|
max_length=15,
|
|
|
|
unique=True
|
|
|
|
)
|
|
|
|
|
|
|
|
organization = models.ManyToManyField(
|
|
|
|
Organization
|
|
|
|
)
|
2018-11-25 21:02:16 +00:00
|
|
|
|
|
|
|
def __str__(self):
|
2019-04-21 08:38:36 +00:00
|
|
|
return "%s" % self.intip + (" (%s)" % self.name if self.name else "")
|
|
|
|
|
2018-11-25 21:02:16 +00:00
|
|
|
|
2018-12-15 11:35:00 +00:00
|
|
|
class Model(models.Model):
|
2019-04-21 08:38:36 +00:00
|
|
|
name = models.CharField(
|
|
|
|
"Model Name",
|
|
|
|
max_length=100,
|
|
|
|
unique=True
|
|
|
|
)
|
|
|
|
|
|
|
|
extname = models.CharField(
|
|
|
|
"Manufacturer Model Name",
|
|
|
|
max_length=100
|
|
|
|
)
|
|
|
|
|
|
|
|
config = models.TextField(
|
|
|
|
"OpenWRT Compile Config",
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
|
|
|
firmware = models.DateTimeField(
|
|
|
|
"Last Firmware Change",
|
|
|
|
auto_now=True
|
|
|
|
)
|
|
|
|
|
|
|
|
wwan = models.BooleanField(
|
|
|
|
"Supports WWAN (External WiFi)",
|
|
|
|
default=False
|
|
|
|
)
|
|
|
|
|
|
|
|
deprecated = models.BooleanField(
|
|
|
|
"Outdated device type",
|
|
|
|
default=False
|
|
|
|
)
|
2018-12-15 11:35:00 +00:00
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.name
|
|
|
|
|
2019-04-21 08:38:36 +00:00
|
|
|
|
2018-12-23 09:37:14 +00:00
|
|
|
class Wifi(models.Model):
|
2019-04-21 08:38:36 +00:00
|
|
|
serial = models.CharField(
|
|
|
|
"Device Serial Number",
|
|
|
|
max_length=12,
|
|
|
|
unique=True
|
|
|
|
)
|
|
|
|
|
|
|
|
organization = models.ForeignKey(
|
|
|
|
Organization,
|
|
|
|
on_delete=models.CASCADE
|
|
|
|
)
|
|
|
|
|
|
|
|
ssid = models.CharField(
|
|
|
|
"WiFi SSID",
|
|
|
|
max_length=32
|
|
|
|
)
|
|
|
|
|
|
|
|
bssid = models.CharField(
|
|
|
|
"WiFi BSSID",
|
|
|
|
max_length=64,
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
|
|
|
key = models.CharField(
|
|
|
|
"WiFi key",
|
|
|
|
max_length=32
|
|
|
|
)
|
|
|
|
|
|
|
|
ip = models.GenericIPAddressField(
|
|
|
|
"Configuration IP",
|
|
|
|
protocol="ipv4",
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
|
|
|
user = models.CharField(
|
|
|
|
"Configuration User Name",
|
|
|
|
max_length=32,
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
|
|
|
password = models.CharField(
|
|
|
|
"Configuration Password",
|
|
|
|
max_length=32,
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
2018-12-23 09:37:14 +00:00
|
|
|
|
|
|
|
def __str__(this):
|
|
|
|
return "%s (%s)" % (this.serial, this.ssid)
|
|
|
|
|
2019-04-21 08:38:36 +00:00
|
|
|
|
2018-11-25 15:05:26 +00:00
|
|
|
class Device(models.Model):
|
2019-04-21 08:38:36 +00:00
|
|
|
serial = models.CharField(
|
|
|
|
"Device Serial Number",
|
|
|
|
max_length=12,
|
|
|
|
unique=True
|
|
|
|
)
|
|
|
|
|
|
|
|
name = models.CharField(
|
|
|
|
"Common Name",
|
|
|
|
max_length=100,
|
|
|
|
default="",
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
|
|
|
model = models.ForeignKey(
|
|
|
|
Model,
|
|
|
|
on_delete=models.CASCADE
|
|
|
|
)
|
|
|
|
|
|
|
|
organization = models.ForeignKey(
|
|
|
|
Organization,
|
|
|
|
on_delete=models.CASCADE
|
|
|
|
)
|
|
|
|
|
|
|
|
network = models.ForeignKey(
|
|
|
|
Network,
|
|
|
|
on_delete=models.SET_NULL,
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
|
|
|
wifi = models.ManyToManyField(
|
|
|
|
Wifi,
|
|
|
|
blank=True
|
|
|
|
)
|
|
|
|
|
|
|
|
curip = models.GenericIPAddressField(
|
|
|
|
"Current IP Address",
|
|
|
|
protocol="ipv4",
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
|
|
|
lasttime = models.DateTimeField(
|
|
|
|
"Last Received IP",
|
|
|
|
blank=True,
|
|
|
|
null=True,
|
|
|
|
editable=False
|
|
|
|
)
|
|
|
|
|
|
|
|
lastbeat = models.DateTimeField(
|
|
|
|
"Last Received Timestamp",
|
|
|
|
blank=True,
|
|
|
|
null=True,
|
|
|
|
editable=False
|
|
|
|
)
|
|
|
|
|
|
|
|
secret = models.CharField(
|
|
|
|
"Secret",
|
|
|
|
default=getRandom,
|
|
|
|
max_length=128
|
|
|
|
)
|
|
|
|
|
|
|
|
password = models.CharField(
|
|
|
|
"Device Password",
|
|
|
|
default=getRandom,
|
|
|
|
max_length=128
|
|
|
|
)
|
|
|
|
|
|
|
|
vpnconfig = models.TextField(
|
|
|
|
"VPN Configuration",
|
|
|
|
blank=True,
|
|
|
|
null=True,
|
|
|
|
editable=False
|
|
|
|
)
|
|
|
|
|
|
|
|
update = models.BooleanField(
|
|
|
|
"Trigger Firmware Update",
|
|
|
|
default=False
|
|
|
|
)
|
|
|
|
|
|
|
|
reboot = models.BooleanField(
|
|
|
|
"Trigger Reboot",
|
|
|
|
default=False
|
|
|
|
)
|
|
|
|
|
|
|
|
changed = models.DateTimeField(
|
|
|
|
"Last Change of Device Config",
|
|
|
|
auto_now_add=True
|
|
|
|
)
|
|
|
|
|
|
|
|
wireless = models.DateTimeField(
|
|
|
|
"Last Update of Wireless Config",
|
|
|
|
blank=True,
|
|
|
|
null=True,
|
|
|
|
editable=False
|
|
|
|
)
|
|
|
|
|
|
|
|
ssid = models.CharField(
|
|
|
|
"Broadcast SSID",
|
|
|
|
max_length=32,
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
|
|
|
key = models.CharField(
|
|
|
|
"Broadcast WPA2 Key",
|
|
|
|
max_length=64,
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
|
|
|
mac = MACAddressField(
|
|
|
|
"Device MAC",
|
|
|
|
null=True,
|
|
|
|
blank=True
|
|
|
|
)
|
2018-11-25 15:05:26 +00:00
|
|
|
|
2018-11-25 21:02:16 +00:00
|
|
|
def __str__(self):
|
2019-03-08 15:16:37 +00:00
|
|
|
return "%s%s" % (self.serial, " (%s)" % self.ssid if self.ssid else "")
|
2018-11-28 21:35:57 +00:00
|
|
|
|
2019-04-16 08:50:04 +00:00
|
|
|
def firmware(self):
|
|
|
|
FWDIR = "/opt/vpnmanager/images/"
|
2019-04-21 08:38:36 +00:00
|
|
|
|
|
|
|
try:
|
|
|
|
fwfile = glob.glob(FWDIR + str(self.id) + ".bin")[0]
|
|
|
|
tz = timezone.get_current_timezone()
|
|
|
|
return datetime.fromtimestamp(os.path.getmtime(fwfile), tz)
|
|
|
|
except Exception:
|
|
|
|
return None
|
2019-04-16 08:50:04 +00:00
|
|
|
|
|
|
|
def upgrade_available(self):
|
2019-04-21 08:38:36 +00:00
|
|
|
if self.firmware():
|
|
|
|
return self.firmware() < self.model.firmware
|
|
|
|
return True
|
|
|
|
|
2019-04-16 08:50:04 +00:00
|
|
|
|
2019-01-18 12:50:41 +00:00
|
|
|
class DeviceLog(models.Model):
|
|
|
|
ADD = 0
|
|
|
|
REMOVE = 1
|
|
|
|
NAME = 2
|
|
|
|
NET = 3
|
|
|
|
REBOOT = 4
|
|
|
|
UPDATE = 5
|
|
|
|
STATUS = 6
|
|
|
|
INTERNALIP = 7
|
|
|
|
WIFI = 8
|
2019-01-19 09:51:17 +00:00
|
|
|
ORGA = 9
|
2019-01-18 12:50:41 +00:00
|
|
|
|
|
|
|
ACTION_CHOICES = (
|
|
|
|
(ADD, "ADD"),
|
|
|
|
(REMOVE, "REMOVE"),
|
|
|
|
(NAME, "NAME"),
|
|
|
|
(NET, "NET"),
|
|
|
|
(REBOOT, "REBOOT"),
|
|
|
|
(UPDATE, "UPDATE"),
|
|
|
|
(STATUS, "STATUS"),
|
|
|
|
(INTERNALIP, "INTERNALIP"),
|
2019-01-19 09:51:17 +00:00
|
|
|
(WIFI, "WIFI"),
|
|
|
|
(ORGA, "ORGA")
|
2019-01-18 12:50:41 +00:00
|
|
|
)
|
|
|
|
|
2019-04-21 08:38:36 +00:00
|
|
|
objid = models.CharField(
|
|
|
|
"Device ID",
|
|
|
|
max_length=64
|
|
|
|
)
|
|
|
|
|
|
|
|
user = models.CharField(
|
|
|
|
"User Name",
|
|
|
|
max_length=128,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
|
|
|
date = models.DateTimeField(
|
|
|
|
"Action Date",
|
|
|
|
auto_now_add=True
|
|
|
|
)
|
|
|
|
|
|
|
|
action = models.IntegerField(
|
|
|
|
"Action",
|
|
|
|
choices=ACTION_CHOICES
|
|
|
|
)
|
|
|
|
|
|
|
|
oldvalue = models.CharField(
|
|
|
|
"Old Value",
|
|
|
|
max_length=256,
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
|
|
|
newvalue = models.CharField(
|
|
|
|
"New Value",
|
|
|
|
max_length=256,
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
2019-01-19 09:51:17 +00:00
|
|
|
|
|
|
|
class UserLog(models.Model):
|
|
|
|
ADD = 0
|
|
|
|
REMOVE = 1
|
|
|
|
NAME = 2
|
|
|
|
MAIL = 3
|
|
|
|
STAFF = 4
|
|
|
|
SUPERUSER = 5
|
|
|
|
ORGA = 6
|
|
|
|
|
|
|
|
ACTION_CHOICES = (
|
|
|
|
(ADD, "ADD"),
|
|
|
|
(REMOVE, "REMOVE"),
|
|
|
|
(NAME, "NAME"),
|
|
|
|
(MAIL, "MAIL"),
|
|
|
|
(STAFF, "STAFF"),
|
|
|
|
(SUPERUSER, "SUPERUSER"),
|
|
|
|
(ORGA, "ORGA")
|
|
|
|
)
|
|
|
|
|
2019-04-21 08:38:36 +00:00
|
|
|
objid = models.CharField(
|
|
|
|
"Target User Name",
|
|
|
|
max_length=64
|
|
|
|
)
|
|
|
|
|
|
|
|
user = models.CharField(
|
|
|
|
"Source User Name",
|
|
|
|
max_length=128,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
|
|
|
date = models.DateTimeField(
|
|
|
|
"Action Date",
|
|
|
|
auto_now_add=True
|
|
|
|
)
|
|
|
|
|
|
|
|
action = models.IntegerField(
|
|
|
|
"Action",
|
|
|
|
choices=ACTION_CHOICES
|
|
|
|
)
|
|
|
|
|
|
|
|
oldvalue = models.CharField(
|
|
|
|
"Old Value",
|
|
|
|
max_length=256,
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
|
|
|
newvalue = models.CharField(
|
|
|
|
"New Value",
|
|
|
|
max_length=256,
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
2019-01-19 09:51:17 +00:00
|
|
|
|
|
|
|
class WifiLog(models.Model):
|
|
|
|
ADD = 0
|
|
|
|
REMOVE = 1
|
|
|
|
NAME = 2
|
|
|
|
SSID = 3
|
|
|
|
KEY = 4
|
|
|
|
ORGA = 5
|
2019-04-21 08:38:36 +00:00
|
|
|
|
2019-01-19 09:51:17 +00:00
|
|
|
ACTION_CHOICES = (
|
|
|
|
(ADD, "ADD"),
|
|
|
|
(REMOVE, "REMOVE"),
|
|
|
|
(NAME, "NAME"),
|
|
|
|
(SSID, "SSID"),
|
|
|
|
(KEY, "KEY"),
|
|
|
|
(ORGA, "ORGA")
|
|
|
|
)
|
|
|
|
|
2019-04-21 08:38:36 +00:00
|
|
|
objid = models.CharField(
|
|
|
|
"Wifi Name",
|
|
|
|
max_length=64
|
|
|
|
)
|
|
|
|
|
|
|
|
user = models.CharField(
|
|
|
|
"User Name",
|
|
|
|
max_length=128,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
|
|
|
date = models.DateTimeField(
|
|
|
|
"Action Date",
|
|
|
|
auto_now_add=True
|
|
|
|
)
|
|
|
|
|
|
|
|
action = models.IntegerField(
|
|
|
|
"Action",
|
|
|
|
choices=ACTION_CHOICES
|
|
|
|
)
|
|
|
|
|
|
|
|
oldvalue = models.CharField(
|
|
|
|
"Old Value",
|
|
|
|
max_length=256,
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
|
|
|
newvalue = models.CharField(
|
|
|
|
"New Value",
|
|
|
|
max_length=256,
|
|
|
|
blank=True,
|
|
|
|
null=True
|
|
|
|
)
|
|
|
|
|
2019-01-19 09:51:17 +00:00
|
|
|
|
2019-01-24 12:04:04 +00:00
|
|
|
class Notification(models.Model):
|
|
|
|
NOTICE = 0
|
|
|
|
ALERT = 1
|
|
|
|
EMERGENCY = 2
|
|
|
|
|
|
|
|
STATUS_CHOICES = (
|
|
|
|
(NOTICE, "NOTICE"),
|
|
|
|
(ALERT, "ALERT"),
|
|
|
|
(EMERGENCY, "EMERGENCY")
|
|
|
|
)
|
|
|
|
|
2019-04-21 08:38:36 +00:00
|
|
|
status = models.IntegerField(
|
|
|
|
"Status",
|
|
|
|
choices=STATUS_CHOICES
|
|
|
|
)
|
|
|
|
|
|
|
|
text = models.CharField(
|
|
|
|
"Notification Text",
|
|
|
|
max_length=1024
|
|
|
|
)
|
|
|
|
|
|
|
|
expiry = models.DateTimeField(
|
|
|
|
"Notification Expiry",
|
|
|
|
null=True,
|
|
|
|
blank=True
|
|
|
|
)
|
|
|
|
|
|
|
|
on_login = models.BooleanField(
|
|
|
|
"Display Notification on Login Screen",
|
|
|
|
default=False
|
|
|
|
)
|
|
|
|
|
2019-01-31 19:58:08 +00:00
|
|
|
|
|
|
|
class UserStatus(models.Model):
|
2019-04-21 08:38:36 +00:00
|
|
|
user = models.OneToOneField(
|
|
|
|
settings.AUTH_USER_MODEL,
|
|
|
|
on_delete=models.CASCADE
|
|
|
|
)
|
|
|
|
|
|
|
|
last_action = models.DateTimeField(
|
|
|
|
null=True,
|
|
|
|
blank=True
|
|
|
|
)
|
2019-01-31 19:58:08 +00:00
|
|
|
|
2019-04-21 08:38:36 +00:00
|
|
|
orga = models.ForeignKey(
|
|
|
|
Organization,
|
|
|
|
on_delete=models.SET_NULL,
|
|
|
|
null=True
|
|
|
|
)
|