Implement organization overview/creation/deletion in frontend for superusers

This commit is contained in:
Kumi 2019-02-03 09:51:02 +00:00
parent ae590f402f
commit 8cab325f9f
7 changed files with 117 additions and 2 deletions

View file

@ -7,3 +7,7 @@ class NetworkForm(forms.Form):
intip = forms.GenericIPAddressField(label="Internal IP Address", protocol="ipv4")
extip = forms.GenericIPAddressField(label="External IP Address", protocol="ipv4")
orgas = forms.MultipleChoiceField(label="Assigned Organizations", choices=[(orga.id, str(orga)) for orga in Organization.objects.all()])
class OrgaForm(forms.Form):
name = forms.CharField(label="Common Name", max_length=64)
users = forms.IntegerField(label="User Limit", required=False)

View file

@ -0,0 +1,23 @@
# Generated by Django 2.1.5 on 2019-02-03 09:38
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('manager', '0043_auto_20190202_1529'),
]
operations = [
migrations.AddField(
model_name='organization',
name='userlimit',
field=models.IntegerField(blank=True, null=True),
),
migrations.AlterField(
model_name='device',
name='wifi',
field=models.ManyToManyField(blank=True, to='manager.Wifi'),
),
]

View file

@ -8,6 +8,7 @@ def getRandom():
class Organization(models.Model):
name = models.CharField("Organization Name", max_length=300)
users = models.ManyToManyField(settings.AUTH_USER_MODEL)
userlimit = models.IntegerField("User Limit", null=True, blank=True)
def __str__(self):
return self.name

View file

@ -8,6 +8,7 @@ urlpatterns = [
path('wifi/', views.devices, name='wifi'),
path('users/', views.devices, name='users'),
path('networks/', views.devices, name='networks'),
path('organizations/', views.devices, name='organizations'),
path('hosts', views.hosts, name='hosts'),
path('devices/<int:device_id>/edit/', views.editdevice, name='editdevice'),
path('devices/<int:device_id>/ping/', views.ping, name="ping"),
@ -20,10 +21,12 @@ urlpatterns = [
path('makewifi/', views.makewifi, name='makewifi'),
path('makeuser/', views.makeuser, name='makeuser'),
path('makenet/', views.makenetwork, name='makenet'),
path('makeorga/', views.makeorganization, name='makeorga'),
path('networks/<int:network_id>/delete', views.deletenetwork, name='deletenetwork'),
path('wifi/<int:wifi_id>/edit/', views.editwifi, name='editwifi'),
path('wifi/<int:wifi_id>/delete/', views.deletewifi, name='deletewifi'),
path('users/<int:user_id>/edit/', views.edituser, name='edituser'),
path('users/<int:user_id>/delete/', views.deleteuser, name='deleteuser'),
path('organizations/<int:orga_id>/delete/', views.deleteorga, name='deleteorga'),
path('update', views.update, name='update')
]

View file

@ -204,7 +204,7 @@ def devices(request):
@login_required
def editdevice(request, device_id):
device = get_object_or_404(Organization, id=device_id, organization__in=request.user.organization_set.all())
device = get_object_or_404(Device, id=device_id, organization__in=request.user.organization_set.all())
subnets = Network.objects.filter(organization=device.organization)
wifis = Wifi.objects.filter(organization=device.organization)
@ -459,6 +459,12 @@ def deletenetwork(request, network_id):
network.delete()
return redirect("/networks/")
@user_passes_test(is_superuser)
def deleteorga(request, orga_id):
orga = get_object_or_404(Organization, id=orga_id)
orga.delete()
return redirect("/organizations/")
@user_passes_test(is_staff)
def makewifi(request):
wifi_serial = request.POST.get("serial", "")
@ -497,6 +503,21 @@ def makenetwork(request):
return render(request, "manager/form.html", { "title": "Add Network", "form": form })
@user_passes_test(is_superuser)
def makeorganization(request):
if request.method == "POST":
form = OrgaForm(request.POST)
if form.is_valid():
data = form.cleaned_data
orga = Organization.objects.create(name=data["name"], userlimit=data["users"])
request.user.organization_set.add(orga)
return redirect("/organizations/")
else:
form = OrgaForm()
return render(request, "manager/form.html", { "title": "Add Organization", "form": form })
@user_passes_test(is_superuser)
def makedevice(request):
CADIR = "/etc/openvpn/ca/"

View file

@ -66,6 +66,10 @@ function askdeletenet(network_id) {
if (confirm("Are you sure you want to delete this Network?")) window.location.href = "/networks/" + network_id + "/delete";
};
function askdeleteorga(organization_id) {
if (confirm("Are you sure you want to delete this Organization? Any associated Networks, WiFis, Devices and Users will also be deleted irreversibly!")) window.location.href = "/organizations/" + organization_id + "/delete";
};
function askreboot(device_id) {
if (confirm("Are you sure you want to reboot this Device?")) window.location.href = "/devices/" + device_id + "/reboot";
};
@ -79,11 +83,13 @@ function showdevices() {
$("#wifipart").hide();
$("#userpart").hide();
$("#netpart").hide();
$("#orgapart").hide();
$("#linkdevices").css("font-weight", "bold");
$("#linkwifi").css("font-weight", "normal");
$("#linkusers").css("font-weight", "normal");
$("#linknets").css("font-weight", "normal");
$("#linkorgas").css("font-weight", "normal");
window.history.pushState("", "", "/devices/");
};
@ -93,11 +99,14 @@ function showwifi() {
$("#wifipart").show();
$("#userpart").hide();
$("#netpart").hide();
$("#orgapart").hide();
$("#linkdevices").css("font-weight", "normal");
$("#linkwifi").css("font-weight", "bold");
$("#linkusers").css("font-weight", "normal");
$("#linknets").css("font-weight", "normal");
$("#linkorgas").css("font-weight", "normal");
window.history.pushState("", "", "/wifi/");
};
@ -107,11 +116,13 @@ function showusers() {
$("#wifipart").hide();
$("#userpart").show();
$("#netpart").hide();
$("#orgapart").hide();
$("#linkdevices").css("font-weight", "normal");
$("#linkwifi").css("font-weight", "normal");
$("#linkusers").css("font-weight", "bold");
$("#linknets").css("font-weight", "normal");
$("#linkorgas").css("font-weight", "normal");
window.history.pushState("", "", "/users/");
};
@ -121,19 +132,38 @@ function shownets() {
$("#wifipart").hide();
$("#userpart").hide();
$("#netpart").show();
$("#orgapart").hide();
$("#linkdevices").css("font-weight", "normal");
$("#linkwifi").css("font-weight", "normal");
$("#linkusers").css("font-weight", "normal");
$("#linknets").css("font-weight", "bold");
$("#linkorgas").css("font-weight", "normal");
window.history.pushState("", "", "/networks/");
};
function showorgas() {
$("#devicespart").hide();
$("#wifipart").hide();
$("#userpart").hide();
$("#netpart").hide();
$("#orgapart").show();
$("#linkdevices").css("font-weight", "normal");
$("#linkwifi").css("font-weight", "normal");
$("#linkusers").css("font-weight", "normal");
$("#linknets").css("font-weight", "normal");
$("#linkorgas").css("font-weight", "bold");
window.history.pushState("", "", "/organizations/");
};
var page = document.location.pathname.substring(1, document.location.pathname.lastIndexOf('/'));
if (page == "users") showusers();
else if (page == "wifi") showwifi();
else if (page == "networks") shownets();
else if (page == "organizations") showorgas();
else showdevices();
$("div[id$='-indicator']").each(function() {

View file

@ -6,7 +6,15 @@
<p><b>Organization:</b> {% orgaString %}</p>
<p><b>User:</b> {{ user.first_name }} {{ user.last_name }} ({{ user.username }}) <a href="/users/{{ user.id }}/edit"><i class="fas fa-edit" title="Edit User"></i></a></p>
<div align="center"><b>Manage:</b> <a id="linkdevices" href="#" onclick="showdevices();">Devices</a> &dash; <a id="linkwifi" href="#" onclick="showwifi();">WiFi</a>{% if user.is_staff %} &dash; <a id="linkusers" href="#" onclick="showusers();">Users</a>{% endif %}{% if user.is_superuser %} &dash; <a id="linknets" href="#" onclick="shownets();">Networks</a>{% endif %}</div>
<div align="center"><b>Manage:</b>
<a id="linkdevices" href="#" onclick="showdevices();">Devices</a>
&dash; <a id="linkwifi" href="#" onclick="showwifi();">WiFi</a>
{% if user.is_staff %} &dash; <a id="linkusers" href="#" onclick="showusers();">Users</a>{% endif %}
{% if user.is_superuser %}
&dash; <a id="linknets" href="#" onclick="shownets();">Networks</a>
&dash; <a id="linkorgas" href="#" onclick="showorgas();">Organizations</a>
{% endif %}
</div>
{% getNotifications %}
@ -122,6 +130,31 @@
</table>
</div>
</div>
<div name ="orgapart" id="orgapart">
<h2>Organizations</h2>
<div class="table-responsive">
<table id="organizations" name="organizations" class="table">
<thead>
<tr>
<th>Name</th>
<th>Users</th>
<th>Options <a href="/makeorga/" style="font-weight:bold;color:green;"><i class="fas fa-plus" title="Add Organization"></i></a></th>
</tr>
</thead>
{% allOrgas as organizations %}
{% for orga in organizations %}
<tr>
<td><div style="display:inline;">{{ orga.name }}</div></td>
<td>{{ orga.users.all|length }}{% if orga.userlimit %}/{{ orga.userlimit }}{% endif %}</td>
<td><a href="#"><i style="color: darkred;" onclick="askdeleteorga({{ orga.id }});" class="fas fa-trash-alt" title="Delete Organization"></i></a></td>
</tr>
{% endfor %}
</table>
</div>
</div>
{% endif %}
<script src="/js/devices.js"></script>