split the project into more apps

This commit is contained in:
Andreas Zweili 2020-01-10 00:01:06 +01:00
parent a45790ee99
commit e3d1d73db9
119 changed files with 1764 additions and 415 deletions

View File

@ -10,7 +10,10 @@ from guardian.shortcuts import assign_perm
@pytest.fixture(scope='session')
def django_db_setup(django_db_setup, django_db_blocker):
with django_db_blocker.unblock():
call_command('loaddata', 'core.yaml')
call_command('loaddata', 'devices.yaml')
call_command('loaddata', 'inventory.yaml')
call_command('loaddata', 'nets.yaml')
@pytest.fixture
@ -19,7 +22,7 @@ def create_admin_user():
User = get_user_model()
admin = User.objects.create_user("novartis-admin", "admin@novartis.com",
"password", is_staff=True)
customer = mixer.blend('customer.Customer')
customer = mixer.blend('customers.Customer')
group = Group.objects.create(name="Novartis Admin")
admin.groups.add(group)
assign_perm('view_customer', admin, customer)

View File

@ -7,7 +7,7 @@ def customer_view_permission(old_function):
def new_function(request, pk, *args, **kwargs):
customer = Customer.objects.get(pk=pk)
user = request.user
if user.has_perm('customer.view_customer', customer):
if user.has_perm('customers.view_customer', customer):
return old_function(request, pk)
else:
return HttpResponseForbidden(

View File

@ -0,0 +1,28 @@
{% load static %}
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css">
<title>Network Inventory</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="ui container">
<a href="{% url 'customers' %}">Home</a> |
<a href="{% url 'all_computers' %}">All Computers</a> |
{% if user.is_authenticated %}
<a href="{% url 'logout' %}">Logout</a> |
{% else %}
<a href="{% url 'login' %}" >Login</a> |
{% endif %}
<h1>{% block section_title %}Device Inventory{% endblock %}</h1>
{% block content %}{% endblock %}
<footer>
{% block footer %}
<p class="copyright">Created by Andreas Zweili licensed under GPL v3.0</p>
{% endblock %}
</footer>
</div>
<script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.js"></script>
</body>
</html>

View File

@ -0,0 +1,24 @@
{% extends 'inventory/base.html' %}
{% block section_title %}Login{% endblock %}
{% block content %}
<form id="login" name="login" method="post">
{% csrf_token %}
<p>
<label for="id_username">Username:</label>
<div class="ui input">
<input type="text" name="username" autofocus required id="id_username">
</div>
</p>
<p>
<label for="id_password">Password:</label>
<div class="ui input">
<input type="password" name="password" required id="id_password">
</div>
</p>
<p>
<button name="button_login" type="submit" class="ui button">Login</button>
</form>
</p>
{% endblock %}

View File

@ -5,6 +5,6 @@ pytestmark = pytest.mark.django_db
def test_customer_reverse_url():
customer = mixer.blend('customer.Customer')
customer = mixer.blend('customers.Customer')
assert (customer.get_absolute_url()
== "/customer/" + str(customer.id) + "/")

View File

@ -37,7 +37,7 @@ def test_customer_detail_view_no_permissions():
User.objects.create_user("novartis-admin", "admin@novartis.com",
"password", is_staff=True)
client = Client()
customer = mixer.blend('customer.Customer')
customer = mixer.blend('customers.Customer')
client.login(username="novartis-admin", password="password")
response = client.get('/customer/' + str(customer.id) + '/')
assert response.status_code == 302 and 'login' in response.url

View File

@ -63,7 +63,7 @@ def test_customer_list_view(create_admin_user):
def test_customer_list_view_multiple_customers(create_admin_user):
fixture = create_admin_user()
customer1 = fixture['customer']
customer2 = mixer.blend('customer.Customer')
customer2 = mixer.blend('customers.Customer')
assign_perm('view_customer', fixture['admin'], customer2)
client = Client()
client.login(username="novartis-admin", password="password")

View File

@ -15,7 +15,7 @@ from .tables import CustomersTable
def customers_table_view(request):
table = CustomersTable(
get_objects_for_user(request.user,
'customer.view_customer',
'customers.view_customer',
klass=Customer))
RequestConfig(request).configure(table)
return render(request, 'inventory/customer_list.html', {'customers': table})

View File

@ -1,3 +1,39 @@
from django.contrib import admin
import nested_admin
# Register your models here.
from .models import (
ConnectedDevice,
Device,
DeviceCategory,
DeviceInNet,
DeviceManufacturer,
)
class DeviceCategoryAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
Return empty perms dict thus hiding the model from admin index.
"""
return {}
class DeviceManufacturerAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
Return empty perms dict thus hiding the model from admin index.
"""
return {}
class DeviceInNetInline(nested_admin.NestedStackedInline):
model = DeviceInNet
extra = 0
verbose_name_plural = 'Nets'
admin.site.register(ConnectedDevice)
admin.site.register(Device)
admin.site.register(DeviceCategory, DeviceCategoryAdmin)
admin.site.register(DeviceInNet)
admin.site.register(DeviceManufacturer, DeviceManufacturerAdmin)

View File

@ -1,5 +1,5 @@
from django.apps import AppConfig
class DeviceConfig(AppConfig):
name = 'device'
class DevicesConfig(AppConfig):
name = 'devices'

31
devices/decorators.py Normal file
View File

@ -0,0 +1,31 @@
from django.http import HttpResponseForbidden
from django.shortcuts import get_object_or_404
from .models import Device
from .models import ConnectedDevice
def device_view_permission(old_function):
def new_function(request, pk, *args, **kwargs):
device = get_object_or_404(Device, pk=pk)
user = request.user
if user.has_perm('customers.view_customer', device.customer):
return old_function(request, pk)
else:
return HttpResponseForbidden(
"You're not allowed to access this device."
)
return new_function
def connect_device_view_permission(old_function):
def new_function(request, pk, *args, **kwargs):
device = get_object_or_404(ConnectedDevice, pk=pk)
user = request.user
if user.has_perm('customers.view_customer', device.customer):
return old_function(request, pk)
else:
return HttpResponseForbidden(
"You're not allowed to access this device."
)
return new_function

View File

@ -0,0 +1,21 @@
- model: devices.DeviceManufacturer
fields:
name: Dell
- model: devices.DeviceManufacturer
fields:
name: HP
- model: devices.DeviceManufacturer
fields:
name: Axxiv
- model: devices.DeviceManufacturer
fields:
name: Acer
- model: devices.DeviceManufacturer
fields:
name: Asus
- model: devices.DeviceManufacturer
fields:
name: Lenovo
- model: devices.DeviceManufacturer
fields:
name: Samsung

View File

@ -1,8 +1,8 @@
from django.db import models
from core.models import Category, Company
from customer.models import Customer, Owner
from customer.models import Location
from inventory.models import User, Net, IpStatus
from customers.models import Customer, Owner, Location
from users.models import User
from nets.models import Net, IpStatus
class DeviceManufacturer(Company):

12
devices/tables.py Normal file
View File

@ -0,0 +1,12 @@
import django_tables2 as tables
from .models import Device
class DevicesTable(tables.Table):
id = tables.Column(visible=False)
name = tables.Column('Device', linkify=True)
class Meta:
template_name = 'django_tables2/semantic.html'
model = Device

View File

@ -0,0 +1,23 @@
{% extends "inventory/base.html" %}
{% load render_table from django_tables2 %}
{% block section_title %}List of Computers{% endblock %}
{% block content %}
<div class="ui form">
<form action="" method="get" class="ui form">
<div class="fields">
<div class="field">
{{ filter.form.name__contains.label_tag }}
{{ filter.form.name__contains }}
</div>
<div class="field">
{{ filter.form.owner.label_tag }}
{{ filter.form.owner }}
</div>
<div class="field">
<button type="submit" class="ui button">Submit</button>
</div>
</div>
</form>
</div>
{% render_table table %}
{% endblock %}

View File

@ -0,0 +1,82 @@
{% extends "inventory/base.html" %}
{% block section_title %}{{ backup.name }}{% endblock %}
{% block content %}
<div class="ui cards">
<div class="card">
<div class="content">
<div class="header">Description</div>
<div class="description"><p>{{ backup.description }}</p></div>
<table class="ui celled table">
<tr>
<td><b>Computer:</b></td>
<td><a href="{% url 'computer' backup.computer.id %}">{{ backup.computer }}</a></td>
</tr>
<tr>
<td><b>Backup Method:</b></td>
<td>{{ backup.method }}</td>
</tr>
<tr>
<td><b>Backup Software:</b></td>
<td>{{ backup.software }}</td>
</tr>
<tr>
<td><b>Exec Time:</b></td>
<td>{{ backup.exec_time }}</td>
</tr>
<tr>
<td><b>Exec Day:</b></td>
<td>{{ backup.exec_day }}</td>
</tr>
</table>
</div>
</div>
{% if target_device_list %}
<div class="card">
<div class="content">
<div class="header">Target Devices</div>
{% for device in target_device_list %}
<table class="ui celled table">
<tr>
<td><b>Target Device:</b></td>
<td><a href="{% url 'computer' device.device.id %}">{{ device.device }}</a></td>
</tr>
<tr>
<td><b>Target Path:</b></td>
<td>{{ device.target_path }}</td>
</tr>
</table>
{% endfor %}
</div>
</div>
{% endif %}
{% if notifications %}
<div class="card">
<div class="content">
<div class="header">Notifications</div>
{% for notification in notifications %}
<table class="ui celled table">
<tr>
<td><b>Name:</b></td>
<td>{{ notification.notification }}</td>
</tr>
<tr>
<td><b>Description:</b></td>
<td>{{ notification.notification.description }}</td>
</tr>
<tr>
<td><b>Recipient:</b></td>
<td>{{ notification.notification.recipient }}</td>
</tr>
<tr>
<td><b>Type:</b></td>
<td>{{ notification.notification.notification_type }}</td>
</tr>
</table>
{% endfor %}
</div>
</div>
{% endif %}
</div>
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "inventory/base.html" %}
{% load render_table from django_tables2 %}
{% block section_title %}List of Backups{% endblock %}
{% block content %}
{% render_table backups %}
{% endblock %}

View File

@ -0,0 +1,28 @@
{% load static %}
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css">
<title>Network Inventory</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="ui container">
<a href="{% url 'customers' %}">Home</a> |
<a href="{% url 'all_computers' %}">All Computers</a> |
{% if user.is_authenticated %}
<a href="{% url 'logout' %}">Logout</a> |
{% else %}
<a href="{% url 'login' %}" >Login</a> |
{% endif %}
<h1>{% block section_title %}Device Inventory{% endblock %}</h1>
{% block content %}{% endblock %}
<footer>
{% block footer %}
<p class="copyright">Created by Andreas Zweili licensed under GPL v3.0</p>
{% endblock %}
</footer>
</div>
<script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.js"></script>
</body>
</html>

View File

@ -0,0 +1,171 @@
{% extends "inventory/base.html" %}
{% block section_title %}{{ computer }}{% endblock %}
{% block content %}
<div class="ui cards">
<div class="card">
<div class="content">
<div class="header">Description</div>
<div class="description"><p>{{ computer.description }}</p></div>
<table class="ui celled table">
<tr>
<td><b>OS:</b></td>
<td>{{ computer.os }}</td>
</tr>
<tr>
<td><b>Serial Number:</b></td>
<td><code>{{ computer.serialnumber }}</code></td>
</tr>
<tr>
<td><b>Category:</b></td>
<td>{{ computer.category }}</td>
</tr>
<tr>
<td><b>Owner:</b></td>
<td>{{ computer.owner }}</td>
</tr>
<tr>
<td><b>Customer:</b></td>
<td><a href="{% url 'customer' computer.customer.id %}">{{ computer.customer }}</a></td>
</tr>
<tr>
<td><b>Manufacturer:</b></td>
<td>{{ computer.manufacturer }}</td>
</tr>
<tr>
<td><b>Location:</b></td>
<td>{{ computer.location }}</td>
</tr>
{% if computer.user %}
<tr>
<td><b>User:</b></td>
<td><a href="{% url 'user' computer.user.id %}">{{ computer.user }}</a></td>
</tr>
{% endif %}
<tr>
<td><b>Installation Date:</b></td>
<td>{{ computer.installation_date }}</td>
</tr>
<tr>
<td><b>IPs:</b></td>
<td>
{% for net_id, ip in computer.ips.items %}
<a href="{% url 'net' net_id %}">{{ip}}</a><br>
{% endfor %}
</td>
</tr>
</table>
</div>
</div>
{% if software_list or backup_list %}
<div class="card">
<div class="content">
{% if software_list %}
<div class="header">Software</div>
<ul>
{% for software in software_list %}
<li>{{ software.software }}</li>
{% endfor %}
</ul>
{% endif %}
{% if licenses %}
<div class="header">Licenses</div>
<table class="ui celled table">
{% for license in licenses %}
<tr>
<td>{{ license.license.software }}</td>
<td><code>{{ license.license.key }}</code></td>
</tr>
{% endfor %}
</table>
{% endif %}
{% if backup_list %}
<div class="header">Backup</div>
<ul>
{% for backup in backup_list %}
<li><a href="{% url 'backup' backup.id %}">{{ backup }}</a></li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
{% endif %}
{% if cpu_list or ram_list or disks_list or raid_disk_pairs or computer.host %}
<div class="card">
<div class="content">
{% if cpu_list or ram_list or disks_list or computer.host %}
<div class="header">Hardware</div>
<table class="ui celled table">
{% if cpu_list %}
<tr>
<td><b>CPUs:</b></td>
<td>
{% for cpu in cpu_list %}
{{ cpu.amount }}x {{ cpu.cpu }}<br>
{% endfor %}
</td>
</tr>
{% endif %}
{% if ram_list %}
<tr>
<td><b>RAM Modules:</b></td>
<td>
{% for module in ram_list %}
{{ module.amount }}x {{ module.ram }}<br>
{% endfor %}
</td>
</tr>
{% endif %}
{% if disks_list %}
<tr>
<td><b>Disks:</b></td>
<td>
{% for disk in disks_list %}
{{ disk.amount }}x {{ disk.disk }}<br>
{% endfor %}
</td>
</tr>
{% endif %}
</table>
{% endif %}
{% if raid_disk_pairs %}
<div class="header">RAID</div>
{% for raid, disks in raid_disk_pairs.items %}
<table class="ui celled table">
<tr>
<td><b>Type:</b></td>
<td>{{ raid.raid_type }}</td>
</tr>
<tr>
<td><b>Usable Space</b></td>
<td>{{ raid.usable_space }}</td>
</tr>
{% if disks %}
{% for disk in disks %}
<tr>
<td><b>Disk Type</b></td>
<td>{{ disk.disk }}</td>
</tr>
<tr>
<td><b>Amount</b></td>
<td>{{ disk.disk_amount }}</td>
</tr>
{% endfor %}
{% endif %}
</table>
{% endfor %}
{% endif %}
{% if computer.host %}
<div class="header">Host</div>
<div class="description">
<a href="{% url 'computer' computer.host.id %}">{{ computer.host }}</a>
</div>
{% endif %}
</div>
</div>
{% endif %}
</div>
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "inventory/base.html" %}
{% load render_table from django_tables2 %}
{% block section_title %}List of Computers{% endblock %}
{% block content %}
{% render_table computers %}
{% endblock %}

View File

@ -0,0 +1,28 @@
{% extends "inventory/base.html" %}
{% block section_title %}{{ cronjob.name }}{% endblock %}
{% block content %}
<h3>Description</h3>
<p>
<b>Host:</b> <a href="{% url 'computer' cronjob.host.id %}">{{ cronjob.host }}</a>
</p>
<p>
<b>Command:</b><br/>
<code>{{ cronjob.command }}</code>
</p>
<table>
<tr>
<th>Minute</th>
<th>Hour</th>
<th>Day of Week</th>
<th>Day of Month</th>
<th>Month</th>
</tr>
<tr>
<td>{{ cronjob.minutes }}</td>
<td>{{ cronjob.hours }}</td>
<td>{{ cronjob.weekday }}</td>
<td>{{ cronjob.day }}</td>
<td>{{ cronjob.month }}</td>
</tr>
</table>
{% endblock %}

View File

@ -0,0 +1,28 @@
{% extends "inventory/base.html" %}
{% block section_title %}List of Cron Jobs{% endblock %}
{% block content %}
{% if cronjob_list %}
<table class="sortable">
<tr>
<th>Name</th>
<th>Hostname</th>
<th>Minute</th>
<th>Hour</th>
<th>Day of Week</th>
<th>Day of Month</th>
<th>Month</th>
</tr>
{% for cronjob in cronjob_list %}
<tr>
<td><a href="{% url 'cronjob' cronjob.id %}">{{ cronjob.name }}</a></td>
<td>{{ cronjob.host }}</td>
<td>{{ cronjob.minutes }}</td>
<td>{{ cronjob.hours }}</td>
<td>{{ cronjob.weekday }}</td>
<td>{{ cronjob.day }}</td>
<td>{{ cronjob.month }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "inventory/base.html" %}
{% block section_title %}{{ customer.name }}{% endblock %}
{% block content %}
<h3>Description</h3>
<p>{{ customer.description }}</p>
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "inventory/base.html" %}
{% load render_table from django_tables2 %}
{% block section_title %}List of Customers{% endblock %}
{% block content %}
{% render_table customers %}
{% endblock %}

View File

@ -0,0 +1,43 @@
{% extends "inventory/base.html" %}
{% block section_title %}{{ device.name }}{% endblock %}
{% block content %}
<div class="ui cards">
<div class="card">
<div class="content">
<div class="header">Description</div>
<div class="description"><p>{{ device.description }}</p></div>
<table class="ui celled table">
</tr>
<tr>
<th><b>Serial Number:</b></th>
<td><code>{{ device.serialnumber }}</code></td>
</tr>
<tr>
<th><b>Category:</b></th>
<td>{{ device.category }}</td>
</tr>
<tr>
<th><b>Owner:</b></th>
<td>{{ device.owner }}</td>
</tr>
<tr>
<th><b>Customer:</b></th>
<td><a href="{% url 'customer' device.customer.id %}">{{ device.customer }}</a></td>
</tr>
<tr>
<th><b>Manufacturer:</b></th>
<td>{{ device.manufacturer }}</td>
</tr>
<tr>
<th><b>Location:</b></th>
<td>{{ device.location }}</td>
</tr>
<tr>
<th><b>Installation Date:</b></th>
<td>{{ device.installation_date }}</td>
</tr>
</table>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "inventory/base.html" %}
{% load render_table from django_tables2 %}
{% block section_title %}List of General Devices{% endblock %}
{% block content %}
{% render_table devices %}
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "inventory/base.html" %}
{% load render_table from django_tables2 %}
{% block section_title %}Licenses{% endblock %}
{% block content %}
<h3>User Licenses</h3>
{% render_table user_licenses %}
<h3>Computer Licenses</h3>
{% render_table computer_licenses %}
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "inventory/base.html" %}
{% load render_table from django_tables2 %}
{% block section_title %}{{ net.name }}{% endblock %}
{% block content %}
{% if net.description %}
<p>{{ net.description }}</p>
{% endif %}
{% render_table table %}
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "inventory/base.html" %}
{% load render_table from django_tables2 %}
{% block section_title %}List of Nets{% endblock %}
{% block content %}
{% render_table nets %}
{% endblock %}

View File

@ -0,0 +1,106 @@
{% extends "inventory/base.html" %}
{% block section_title %}{{ user }}{% endblock %}
{% block content %}
<div class="ui cards">
<div class="card">
<div class="content">
<div class="header">Description</div>
<div class="description"><p>{{ user.description }}</p></div>
<table class="ui celled table">
<tr>
<td><b>Customer</b></td>
<td><a href="{% url 'customer' user.customer.id %}">{{ user.customer }}</a></td>
</tr>
<tr>
<td><b>AD Login</b></td>
<td>{{ user.ad_login }}</td>
</tr>
<tr>
<td><b>AD Password</b></td>
<td>{{ user.ad_pw }}</td>
</tr>
<tr>
<td><b>Email Address</b></td>
<td>{{ user.ad_login }}</td>
</tr>
<tr>
<td><b>Mail Password</b></td>
<td>{{ user.mail_pw }}</td>
</tr>
<tr>
<td><b>User is activ</b></td>
<td>{{ user.enabled }}</td>
</tr>
<tr>
<td><b>Comptuers</b></td>
<td>
{% for computer in computers %}
<a href="{% url 'computer' computer.id %}">{{ computer}}</a>
{% endfor %}
</td>
</tr>
</table>
</div>
</div>
{% if ad_groups or mail_groups or mail_alias %}
<div class="card">
<div class="content">
{% if mail_alias %}
<div class="header">Mail Alias</div>
<table class="ui celled table">
{% for alias in mail_alias %}
<tr>
<td>
{{ alias }}
</td>
</tr>
{% endfor %}
</table>
{% endif %}
{% if ad_groups %}
<div class="header">AD Groups</div>
<table class="ui celled table">
{% for group in ad_groups %}
<tr>
<td>{{ group.group }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
{% if mail_groups %}
<div class="header">Mail Groups</div>
<table class="ui celled table">
<th>Group Name</th>
<th>Address</th>
{% for group in mail_groups %}
<tr>
<td>{{ group.group }}</td>
<td>{{ group.group.mail_address }}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
{% endif %}
{% endif %}
{% if licenses %}
<div class="card">
<div class="content">
<div class="header">Licenses</div>
<table class="ui celled table">
{% for license in licenses %}
<tr>
<td>{{ license.license.software }}</td>
<td><code>{{ license.license.key }}</code></td>
</tr>
{% endfor %}
</table>
</div>
</div>
{% endif %}
</div>
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "inventory/base.html" %}
{% load render_table from django_tables2 %}
{% block section_title %}Users{% endblock %}
{% block content %}
{% render_table users %}
{% endblock %}

View File

@ -0,0 +1,24 @@
{% extends 'inventory/base.html' %}
{% block section_title %}Login{% endblock %}
{% block content %}
<form id="login" name="login" method="post">
{% csrf_token %}
<p>
<label for="id_username">Username:</label>
<div class="ui input">
<input type="text" name="username" autofocus required id="id_username">
</div>
</p>
<p>
<label for="id_password">Password:</label>
<div class="ui input">
<input type="password" name="password" required id="id_password">
</div>
</p>
<p>
<button name="button_login" type="submit" class="ui button">Login</button>
</form>
</p>
{% endblock %}

View File

@ -5,6 +5,6 @@ pytestmark = pytest.mark.django_db
def test_device_reverse_url():
device = mixer.blend('inventory.ConnectedDevice')
device = mixer.blend('devices.ConnectedDevice')
assert (device.get_absolute_url()
== "/device/" + str(device.id) + "/")

View File

@ -4,7 +4,7 @@ from django.test import Client
from mixer.backend.django import mixer
from core.tests import helper
from customer.models import Customer
from customers.models import Customer
pytestmark = pytest.mark.django_db
@ -19,7 +19,7 @@ def test_customer_device_table(create_admin_user):
customer = fixture['customer']
client = Client()
client.login(username="novartis-admin", password="password")
device = mixer.blend('inventory.Device', customer=mixer.SELECT)
device = mixer.blend('devices.Device', customer=mixer.SELECT)
response = client.get('/customer/' + str(customer.id) + '/devices/')
assert (response.status_code == 200
and helper.in_content(response, device))
@ -40,7 +40,7 @@ def test_customer_device_table_no_permission(create_admin_user):
customer = Customer.objects.create(name='Nestle')
client = Client()
client.login(username="novartis-admin", password="password")
mixer.blend('inventory.Device', customer=customer)
mixer.blend('devices.Device', customer=customer)
response = client.get('/customer/' + str(customer.id) + '/devices/')
assert response.status_code == 403
@ -50,8 +50,8 @@ def test_customer_device_table_multiple_devices(create_admin_user):
customer = fixture['customer']
client = Client()
client.login(username="novartis-admin", password="password")
device1 = mixer.blend('inventory.Device', customer=mixer.SELECT)
device2 = mixer.blend('inventory.Device', customer=mixer.SELECT)
device1 = mixer.blend('devices.Device', customer=mixer.SELECT)
device2 = mixer.blend('devices.Device', customer=mixer.SELECT)
response = client.get('/customer/' + str(customer.id) + '/devices/')
assert (response.status_code == 200
and helper.in_content(response, device1)

View File

@ -5,6 +5,6 @@ pytestmark = pytest.mark.django_db
def test_device_reverse_url():
device = mixer.blend('inventory.Device')
device = mixer.blend('devices.Device')
assert (device.get_absolute_url()
== "/device/" + str(device.id) + "/")

View File

@ -15,10 +15,10 @@ def test_device_detail_view_not_logged_in():
def test_device_detail_view(create_admin_user):
fixture = create_admin_user()
mixer.blend('inventory.DeviceCategory')
mixer.blend('customer.Owner')
mixer.blend('inventory.Location')
device = mixer.blend('inventory.Device',
mixer.blend('devices.DeviceCategory')
mixer.blend('customers.Owner')
mixer.blend('customers.Location')
device = mixer.blend('devices.Device',
customer=fixture['customer'],
owner=mixer.SELECT,
category=mixer.SELECT,
@ -47,8 +47,8 @@ def test_device_detail_view_not_found(create_admin_user):
def test_device_detail_view_no_permission(create_admin_user):
create_admin_user()
customer = mixer.blend('customer.Customer')
device = mixer.blend('inventory.Device', customer=customer)
customer = mixer.blend('customers.Customer')
device = mixer.blend('devices.Device', customer=customer)
client = Client()
client.login(username="novartis-admin", password="password")
response = client.get('/device/' + str(device.id) + '/')

10
devices/urls.py Normal file
View File

@ -0,0 +1,10 @@
from django.urls import path
from . import views
urlpatterns = [
path('customer/<int:pk>/devices/', views.devices_table_view,
name='devices'),
path('device/<int:pk>/', views.device_detail_view, name='device'),
]

View File

@ -1,3 +1,28 @@
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404
from django.shortcuts import render
# Create your views here.
from django_tables2 import RequestConfig
from customers.decorators import customer_view_permission
from .decorators import device_view_permission
from .models import Device
from .tables import DevicesTable
@login_required
@device_view_permission
def device_detail_view(request, pk):
device = get_object_or_404(Device, pk=pk)
return render(request, 'inventory/device_details.html',
{'device': device})
@login_required
@customer_view_permission
def devices_table_view(request, pk):
table = DevicesTable(Device.objects.filter(customer=pk))
RequestConfig(request).configure(table)
return render(request, 'inventory/device_list.html', {'devices': table})

View File

@ -1,8 +1,9 @@
from django.contrib import admin
import nested_admin
from devices.models import DeviceInNet
from .models import (
AdGroup,
Backup,
BackupMethod,
Computer,
@ -11,24 +12,14 @@ from .models import (
ComputerLicense,
ComputerRamRelation,
ComputerSoftwareRelation,
ConnectedDevice,
Cpu,
CpuArchitecture,
CpuManufacturer,
Device,
DeviceCategory,
DeviceInNet,
DeviceManufacturer,
Disk,
DiskType,
DisksInRaid,
IpStatus,
LicenseWithComputer,
LicenseWithUser,
Location,
MailAlias,
MailGroup,
Net,
Notification,
NotificationType,
NotificationFromBackup,
@ -41,9 +32,6 @@ from .models import (
SoftwareArchitecture,
SoftwareCategory,
TargetDevice,
User,
UserInAdGroup,
UserInMailGroup,
UserLicense,
Warranty,
WarrantyType
@ -82,22 +70,6 @@ class CpuManufacturerAdmin(admin.ModelAdmin):
return {}
class DeviceCategoryAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
Return empty perms dict thus hiding the model from admin index.
"""
return {}
class DeviceManufacturerAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
Return empty perms dict thus hiding the model from admin index.
"""
return {}
class IpStatusAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
@ -114,22 +86,6 @@ class LicenseWithComputerAdmin(admin.ModelAdmin):
return {}
class LicenseWithUserAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
Return empty perms dict thus hiding the model from admin index.
"""
return {}
class MailAliasAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
Return empty perms dict thus hiding the model from admin index.
"""
return {}
class NotificationTypeAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
@ -210,22 +166,6 @@ class RamTypeAdmin(admin.ModelAdmin):
return {}
class UserInAdGroupAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
Return empty perms dict thus hiding the model from admin index.
"""
return {}
class UserInMailGroupAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
Return empty perms dict thus hiding the model from admin index.
"""
return {}
class WarrantyTypeAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
@ -297,35 +237,6 @@ class ComputerAdmin(nested_admin.NestedModelAdmin):
DeviceInNetInline, LicenseWithComputerInLine)
class AdGroupInLine(admin.StackedInline):
model = UserInAdGroup
extra = 0
verbose_name_plural = 'AD Groups'
class LicenseWithUserInLine(admin.StackedInline):
model = LicenseWithUser
extra = 0
verbose_name_plural = 'Licenses'
class MailGroupInLine(admin.StackedInline):
model = UserInMailGroup
extra = 0
verbose_name_plural = 'Mail Groups'
class MailAliasInLine(admin.StackedInline):
model = MailAlias
extra = 0
verbose_name_plural = 'Mail Aliases'
class UserAdmin(admin.ModelAdmin):
list_display = ('name', 'customer', 'enabled')
inlines = (AdGroupInLine, MailGroupInLine, MailAliasInLine, LicenseWithUserInLine)
class TargetDeviceInLine(admin.StackedInline):
model = TargetDevice
extra = 0
@ -354,28 +265,16 @@ class ComputerLicenseAdmin(admin.ModelAdmin):
verbose_name_plural = 'Computer Licenses'
admin.site.register(AdGroup)
admin.site.register(Backup, BackupAdmin)
admin.site.register(BackupMethod, BackupMethodAdmin)
admin.site.register(Computer, ComputerAdmin)
admin.site.register(ComputerLicense, ComputerLicenseAdmin)
admin.site.register(ConnectedDevice)
admin.site.register(Cpu, CpuAdmin)
admin.site.register(CpuArchitecture, CpuArchitectureAdmin)
admin.site.register(CpuManufacturer, CpuManufacturerAdmin)
admin.site.register(Device)
admin.site.register(DeviceCategory, DeviceCategoryAdmin)
admin.site.register(DeviceInNet)
admin.site.register(DeviceManufacturer, DeviceManufacturerAdmin)
admin.site.register(Disk)
admin.site.register(DiskType, DiskTypeAdmin)
admin.site.register(IpStatus, IpStatusAdmin)
admin.site.register(LicenseWithComputer, LicenseWithComputerAdmin)
admin.site.register(LicenseWithUser, LicenseWithUserAdmin)
admin.site.register(Location)
admin.site.register(MailAlias, MailAliasAdmin)
admin.site.register(MailGroup)
admin.site.register(Net)
admin.site.register(Notification, NotificationAdmin)
admin.site.register(NotificationType, NotificationTypeAdmin)
admin.site.register(OperatingSystem, OperatingSystemAdmin)
@ -386,10 +285,6 @@ admin.site.register(Software)
admin.site.register(SoftwareArchitecture, SoftwareArchitectureAdmin)
admin.site.register(SoftwareCategory, SoftwareCategoryAdmin)
admin.site.register(TargetDevice, TargetDeviceAdmin)
admin.site.register(User, UserAdmin)
admin.site.register(UserInAdGroup, UserInAdGroupAdmin)
admin.site.register(UserInMailGroup, UserInMailGroupAdmin)
admin.site.register(UserLicense, UserLicenseAdmin)
admin.site.register(Warranty)
admin.site.register(WarrantyType, WarrantyTypeAdmin)

View File

@ -3,56 +3,13 @@ from django.shortcuts import get_object_or_404
from .models import Backup
from .models import Computer
from .models import Device
from .models import ConnectedDevice
from .models import Net
from .models import User
def computer_view_permission(old_fuction):
def new_function(request, pk, *args, **kwargs):
computer = get_object_or_404(Computer, pk=pk)
user = request.user
if user.has_perm('customer.view_customer', computer.customer):
return old_fuction(request, pk)
else:
return HttpResponseForbidden(
"You're not allowed to access this device."
)
return new_function
def device_view_permission(old_function):
def new_function(request, pk, *args, **kwargs):
device = get_object_or_404(Device, pk=pk)
user = request.user
if user.has_perm('customer.view_customer', device.customer):
return old_function(request, pk)
else:
return HttpResponseForbidden(
"You're not allowed to access this device."
)
return new_function
def connect_device_view_permission(old_function):
def new_function(request, pk, *args, **kwargs):
device = get_object_or_404(ConnectedDevice, pk=pk)
user = request.user
if user.has_perm('customer.view_customer', device.customer):
return old_function(request, pk)
else:
return HttpResponseForbidden(
"You're not allowed to access this device."
)
return new_function
def net_view_permission(old_fuction):
def new_function(request, pk, *args, **kwargs):
net = get_object_or_404(Net, pk=pk)
user = request.user
if user.has_perm('customer.view_customer', net.customer):
if user.has_perm('customers.view_customer', computer.customer):
return old_fuction(request, pk)
else:
return HttpResponseForbidden(
@ -65,20 +22,7 @@ def backup_view_permission(old_fuction):
def new_function(request, pk, *args, **kwargs):
backup = get_object_or_404(Backup, pk=pk)
user = request.user
if user.has_perm('customer.view_customer', backup.computer.customer):
return old_fuction(request, pk)
else:
return HttpResponseForbidden(
"You're not allowed to access this device."
)
return new_function
def user_view_permission(old_fuction):
def new_function(request, pk, *args, **kwargs):
inventory_user = get_object_or_404(User, pk=pk)
user = request.user
if user.has_perm('customer.view_customer', inventory_user.customer):
if user.has_perm('customers.view_customer', backup.computer.customer):
return old_fuction(request, pk)
else:
return HttpResponseForbidden(

View File

@ -17,28 +17,6 @@
fields:
name: ARM64
- model: inventory.DeviceManufacturer
fields:
name: Dell
- model: inventory.DeviceManufacturer
fields:
name: HP
- model: inventory.DeviceManufacturer
fields:
name: Axxiv
- model: inventory.DeviceManufacturer
fields:
name: Acer
- model: inventory.DeviceManufacturer
fields:
name: Asus
- model: inventory.DeviceManufacturer
fields:
name: Lenovo
- model: inventory.DeviceManufacturer
fields:
name: Samsung
- model: inventory.RamType
fields:
name: unkown
@ -62,19 +40,6 @@
fields:
name: SAS
- model: inventory.IpStatus
fields:
name: "Fixed in Device"
- model: inventory.IpStatus
fields:
name: Reserved
- model: inventory.IpStatus
fields:
name: "Fixed in Device + Reserved"
- model: inventory.IpStatus
fields:
name: Dynamic
- model: inventory.SoftwareArchitecture
fields:
name: "32 Bit"

View File

@ -6,8 +6,6 @@ from .cpu import CpuArchitecture, CpuManufacturer, Cpu
from .disk import DiskType, Disk
from .license import (License, ComputerLicense, UserLicense,
LicenseWithComputer, LicenseWithUser)
from .mailalias import MailAlias
from .net import Net, IpStatus
from .notification import Notification, NotificationType
from .os import OperatingSystem
from .raid import DisksInRaid, RaidType, Raid

View File

@ -1,6 +1,6 @@
from django.db import models
from .cpu import Cpu
from device.models import ConnectedDevice
from devices.models import ConnectedDevice
from .disk import Disk
from .os import OperatingSystem
from .ram import Ram

View File

@ -1,9 +1,8 @@
from django.db import models
from django.core.exceptions import ValidationError
from customer.models import Customer
from customers.models import Customer
from .computer import Computer
from .user import User
from users.models import User
from .software import Software

View File

@ -2,7 +2,7 @@ from django.db import models
from core.models import Category
from .devices import Device
from devices.models import Device
class WarrantyType(Category):

View File

@ -2,10 +2,6 @@ import django_tables2 as tables
from .models import Backup
from .models import ComputerLicense
from .models import Device
from .models import DeviceInNet
from .models import Net
from .models import User
from .models import UserLicense
@ -24,25 +20,6 @@ class ComputersTable(tables.Table):
template_name = 'django_tables2/semantic.html'
class DevicesTable(tables.Table):
id = tables.Column(visible=False)
name = tables.Column('Device', linkify=True)
class Meta:
template_name = 'django_tables2/semantic.html'
model = Device
class NetsTable(tables.Table):
id = tables.Column(visible=False)
name = tables.Column('Net', linkify=True)
customer = tables.Column('Customer', linkify=True)
class Meta:
template_name = 'django_tables2/semantic.html'
model = Net
class BackupsTable(tables.Table):
id = tables.Column(visible=False)
name = tables.Column('Backup', linkify=True)
@ -54,16 +31,6 @@ class BackupsTable(tables.Table):
model = Backup
class NetDetailTable(tables.Table):
device = tables.Column('Computer', linkify=True)
ip = tables.Column()
net = tables.Column(visible=False)
class Meta:
template_name = 'django_tables2/semantic.html'
model = DeviceInNet
class UserLicensesTable(tables.Table):
id = tables.Column(visible=False)
license_ptr = tables.Column(visible=False)
@ -86,15 +53,3 @@ class ComputerLicensesTable(tables.Table):
class Meta:
template_name = 'django_tables2/semantic.html'
model = ComputerLicense
class UsersTable(tables.Table):
id = tables.Column(visible=False)
name = tables.Column('User', linkify=True)
customer = tables.Column('Customer', linkify=True)
ad_groups = tables.ManyToManyColumn()
mail_groups = tables.ManyToManyColumn()
class Meta:
template_name = 'django_tables2/semantic.html'
model = User

View File

@ -7,7 +7,7 @@ pytestmark = pytest.mark.django_db
def test_license_two_licenses_per_user():
mixer.blend('inventory.User')
mixer.blend('users.User')
mixer.blend('inventory.UserLicense')
with pytest.raises(IntegrityError):
mixer.cycle(2).blend('inventory.LicenseWithUser',

View File

@ -3,7 +3,7 @@ from mixer.backend.django import mixer
from django.test import Client
from core.tests import helper
from customer.models import Customer
from customers.models import Customer
pytestmark = pytest.mark.django_db

View File

@ -73,7 +73,7 @@ def test_computer_detail_view_cpu_relation(create_admin_user):
def test_computer_detail_view_no_permission(create_admin_user):
create_admin_user()
customer = mixer.blend('customer.Customer')
customer = mixer.blend('customers.Customer')
computer = mixer.blend('inventory.Computer', customer=customer)
client = Client()
client.login(username="novartis-admin", password="password")

View File

@ -5,7 +5,7 @@ from django.test import Client
from core.tests import helper
from customer.models import Customer
from customers.models import Customer
pytestmark = pytest.mark.django_db

View File

@ -4,7 +4,7 @@ from mixer.backend.django import mixer
from django.test import Client
from core.tests import helper
from customer.models import Customer
from customers.models import Customer
pytestmark = pytest.mark.django_db

View File

@ -4,7 +4,7 @@ from django.test import Client
from mixer.backend.django import mixer
from core.tests import helper
from customer.models import Customer
from customers.models import Customer
pytestmark = pytest.mark.django_db
@ -53,8 +53,8 @@ def test_customer_license_table_no_permission(create_admin_user):
def test_customer_license_table_multiple_licenses(create_admin_user):
fixture = create_admin_user()
customer = fixture['customer']
user1 = mixer.blend('inventory.User')
user2 = mixer.blend('inventory.User')
user1 = mixer.blend('users.User')
user2 = mixer.blend('users.User')
client = Client()
client.login(username="novartis-admin", password="password")
license1 = mixer.blend('inventory.UserLicense', customer=customer,

View File

@ -6,22 +6,13 @@ urlpatterns = [
path('accounts/', include('django.contrib.auth.urls')),
path('customer/<int:pk>/computers/',
views.computers_table_view, name='computers'),
path('customer/<int:pk>/devices/', views.devices_table_view,
name='devices'),
path('customer/<int:pk>/nets/', views.nets_table_view,
name='nets'),
path('customer/<int:pk>/backups/', views.backups_table_view,
name='backups'),
path('computer/<int:pk>/', views.computer_detail_view,
name='computer'),
path('device/<int:pk>/', views.device_detail_view, name='device'),
path('net/<int:pk>/', views.net_detail_view, name='net'),
path('backup/<int:pk>/', views.backup_detail_view, name='backup'),
path('computers/all/', views.ComputersFilterView.as_view(),
name='all_computers'),
path('customer/<int:pk>/licenses/', views.licenses_table_view,
name='licenses'),
path('customer/<int:pk>/users/', views.users_table_view,
name='users'),
path('user/<int:pk>/', views.user_detail_view, name='user'),
]

View File

@ -8,14 +8,11 @@ from django_tables2 import RequestConfig
from django_tables2.views import SingleTableMixin
from guardian.shortcuts import get_objects_for_user
from customer.models import Customer
from customer.decorators import customer_view_permission
from customers.models import Customer
from customers.decorators import customer_view_permission
from .decorators import backup_view_permission
from .decorators import computer_view_permission
from .decorators import device_view_permission
from .decorators import net_view_permission
from .decorators import user_view_permission
from .filters import ComputerFilter
from .models import Backup
from .models import Computer
@ -24,36 +21,16 @@ from .models import ComputerDiskRelation
from .models import ComputerLicense
from .models import ComputerRamRelation
from .models import ComputerSoftwareRelation
from .models import Device
from .models import DeviceInNet
from .models import DisksInRaid
from .models import LicenseWithComputer
from .models import LicenseWithUser
from .models import MailAlias
from .models import Net
from .models import NotificationFromBackup
from .models import Raid
from .models import TargetDevice
from .models import User
from .models import UserInAdGroup
from .models import UserInMailGroup
from .models import UserLicense
from .tables import BackupsTable
from .tables import ComputerLicensesTable
from .tables import ComputersTable
from .tables import DevicesTable
from .tables import NetDetailTable
from .tables import NetsTable
from .tables import UserLicensesTable
from .tables import UsersTable
@login_required
@device_view_permission
def device_detail_view(request, pk):
device = get_object_or_404(Device, pk=pk)
return render(request, 'inventory/device_details.html',
{'device': device})
@login_required
@ -88,33 +65,6 @@ def computers_table_view(request, pk):
return render(request, 'inventory/computer_list.html', {'computers': table})
@login_required
@customer_view_permission
def devices_table_view(request, pk):
table = DevicesTable(Device.objects.filter(customer=pk))
RequestConfig(request).configure(table)
return render(request, 'inventory/device_list.html', {'devices': table})
@login_required
@customer_view_permission
def nets_table_view(request, pk):
table = NetsTable(Net.objects.filter(customer=pk))
RequestConfig(request).configure(table)
return render(request, 'inventory/net_list.html', {'nets': table})
@login_required
@net_view_permission
def net_detail_view(request, pk):
net = get_object_or_404(Net, pk=pk)
table = NetDetailTable(DeviceInNet.objects.filter(net=net))
RequestConfig(request).configure(table)
return render(request, 'inventory/net_details.html',
{'table': table,
'net': net})
@login_required
@customer_view_permission
def backups_table_view(request, pk):
@ -145,7 +95,7 @@ class ComputersFilterView(LoginRequiredMixin, SingleTableMixin, FilterView):
def get_queryset(self):
customers = get_objects_for_user(self.request.user,
'customer.view_customer',
'customers.view_customer',
klass=Customer)
results = Computer.objects.filter(customer__in=customers)
return results
@ -163,29 +113,3 @@ def licenses_table_view(request, pk):
'inventory/license_list.html',
{'user_licenses': user_licenses,
'computer_licenses': computer_licenses})
@login_required
@customer_view_permission
def users_table_view(request, pk):
table = UsersTable(User.objects.filter(customer=pk))
RequestConfig(request).configure(table)
return render(request, 'inventory/user_list.html', {'users': table})
@login_required
@user_view_permission
def user_detail_view(request, pk):
user = get_object_or_404(User, pk=pk)
ad_groups = UserInAdGroup.objects.filter(user=user)
mail_groups = UserInMailGroup.objects.filter(user=user)
mail_alias = MailAlias.objects.filter(user=user)
computers = Computer.objects.filter(user=user)
licenses = LicenseWithUser.objects.filter(user=user)
return render(request, 'inventory/user_details.html',
{'user': user,
'ad_groups': ad_groups,
'mail_groups': mail_groups,
'mail_alias': mail_alias,
'computers': computers,
'licenses': licenses})

0
nets/__init__.py Normal file
View File

19
nets/admin.py Normal file
View File

@ -0,0 +1,19 @@
from django.contrib import admin
from .models import (
IpStatus,
Net,
)
class IpStatusAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
Return empty perms dict thus hiding the model from admin index.
"""
return {}
admin.site.register(IpStatus, IpStatusAdmin)
admin.site.register(Net)

5
nets/apps.py Normal file
View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class NetsConfig(AppConfig):
name = 'nets'

17
nets/decorators.py Normal file
View File

@ -0,0 +1,17 @@
from django.http import HttpResponseForbidden
from django.shortcuts import get_object_or_404
from .models import Net
def net_view_permission(old_fuction):
def new_function(request, pk, *args, **kwargs):
net = get_object_or_404(Net, pk=pk)
user = request.user
if user.has_perm('customers.view_customer', net.customer):
return old_fuction(request, pk)
else:
return HttpResponseForbidden(
"You're not allowed to access this device."
)
return new_function

12
nets/fixtures/nets.yaml Normal file
View File

@ -0,0 +1,12 @@
- model: nets.IpStatus
fields:
name: "Fixed in Device"
- model: nets.IpStatus
fields:
name: Reserved
- model: nets.IpStatus
fields:
name: "Fixed in Device + Reserved"
- model: nets.IpStatus
fields:
name: Dynamic

View File

@ -1,5 +1,5 @@
from django.db import models
from customer.models import Customer
from customers.models import Customer
from core.models import Category

24
nets/tables.py Normal file
View File

@ -0,0 +1,24 @@
import django_tables2 as tables
from devices.models import DeviceInNet
from .models import Net
class NetsTable(tables.Table):
id = tables.Column(visible=False)
name = tables.Column('Net', linkify=True)
customer = tables.Column('Customer', linkify=True)
class Meta:
template_name = 'django_tables2/semantic.html'
model = Net
class NetDetailTable(tables.Table):
device = tables.Column('Computer', linkify=True)
ip = tables.Column()
net = tables.Column(visible=False)
class Meta:
template_name = 'django_tables2/semantic.html'
model = DeviceInNet

View File

@ -0,0 +1,9 @@
{% extends "inventory/base.html" %}
{% load render_table from django_tables2 %}
{% block section_title %}{{ net.name }}{% endblock %}
{% block content %}
{% if net.description %}
<p>{{ net.description }}</p>
{% endif %}
{% render_table table %}
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "inventory/base.html" %}
{% load render_table from django_tables2 %}
{% block section_title %}List of Nets{% endblock %}
{% block content %}
{% render_table nets %}
{% endblock %}

View File

@ -5,6 +5,6 @@ pytestmark = pytest.mark.django_db
def test_net_reverse_url():
net = mixer.blend('inventory.Net')
net = mixer.blend('nets.Net')
assert (net.get_absolute_url()
== "/net/" + str(net.id) + "/")

View File

@ -5,7 +5,7 @@ from django.test import Client
from core.tests import helper
from customer.models import Customer
from customers.models import Customer
pytestmark = pytest.mark.django_db
@ -19,7 +19,7 @@ def test_customer_net_table(create_admin_user):
create_admin_user()
client = Client()
client.login(username="novartis-admin", password="password")
net = mixer.blend('inventory.Net', customer=mixer.SELECT)
net = mixer.blend('nets.Net', customer=mixer.SELECT)
response = client.get('/customer/' + str(net.customer.id) + '/nets/')
assert (response.status_code == 200
and helper.in_content(response, net))
@ -39,6 +39,6 @@ def test_customer_net_table_no_permission(create_admin_user):
customer = Customer.objects.create(name='Nestle')
client = Client()
client.login(username="novartis-admin", password="password")
mixer.blend('inventory.Net', customer=customer)
mixer.blend('nets.Net', customer=customer)
response = client.get('/customer/' + str(customer.id) + '/nets/')
assert response.status_code == 403

View File

@ -3,7 +3,7 @@ from mixer.backend.django import mixer
from django.test import Client
from inventory.models import DeviceInNet
from devices.models import DeviceInNet
from core.tests import helper
@ -12,10 +12,10 @@ pytestmark = pytest.mark.django_db
def test_net_detail_view_no_permission(create_admin_user):
create_admin_user()
net = mixer.blend('inventory.Net')
customer = mixer.blend('customer.Customer')
net = mixer.blend('nets.Net')
customer = mixer.blend('customers.Customer')
device = mixer.blend('inventory.Computer', customer=customer)
mixer.blend('inventory.DeviceInNet',
mixer.blend('devices.DeviceInNet',
device=device,
net=net,
ip='10.7.89.101')
@ -27,7 +27,7 @@ def test_net_detail_view_no_permission(create_admin_user):
def test_net_detail_view(create_admin_user):
fixture = create_admin_user()
net = mixer.blend('inventory.Net', customer=mixer.SELECT)
net = mixer.blend('nets.Net', customer=mixer.SELECT)
device = mixer.blend('inventory.Computer', customer=fixture['customer'])
device_in_net = DeviceInNet.objects.create(device=device,
net=net, ip='10.7.89.101')
@ -41,7 +41,7 @@ def test_net_detail_view(create_admin_user):
def test_net_detail_view_not_found(create_admin_user):
create_admin_user()
mixer.blend('inventory.Net')
mixer.blend('nets.Net')
client = Client()
client.login(username="novartis-admin", password="password")
response = client.get('/net/100/')

9
nets/urls.py Normal file
View File

@ -0,0 +1,9 @@
from django.urls import path
from . import views
urlpatterns = [
path('customer/<int:pk>/nets/', views.nets_table_view,
name='nets'),
path('net/<int:pk>/', views.net_detail_view, name='net'),
]

32
nets/views.py Normal file
View File

@ -0,0 +1,32 @@
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404
from django.shortcuts import render
from django_tables2 import RequestConfig
from customers.decorators import customer_view_permission
from devices.models import DeviceInNet
from .decorators import net_view_permission
from .models import Net
from .tables import NetDetailTable
from .tables import NetsTable
@login_required
@customer_view_permission
def nets_table_view(request, pk):
table = NetsTable(Net.objects.filter(customer=pk))
RequestConfig(request).configure(table)
return render(request, 'inventory/net_list.html', {'nets': table})
@login_required
@net_view_permission
def net_detail_view(request, pk):
net = get_object_or_404(Net, pk=pk)
table = NetDetailTable(DeviceInNet.objects.filter(net=net))
RequestConfig(request).configure(table)
return render(request, 'inventory/net_details.html',
{'table': table,
'net': net})

View File

@ -36,6 +36,7 @@ INSTALLED_APPS = [
'guardian',
'inventory.apps.InventoryConfig',
'nested_admin',
'nets.apps.NetsConfig',
'users.apps.UsersConfig',
]

View File

@ -18,8 +18,11 @@ from django.contrib import admin
from django.urls import path
urlpatterns = [
url(r'', include('customers.urls')),
url(r'', include('devices.urls')),
url(r'', include('inventory.urls')),
url(r'', include('customer.urls')),
url(r'', include('nets.urls')),
url(r'', include('users.urls')),
path('admin/', admin.site.urls),
url(r'^_nested_admin/', include('nested_admin.urls')),
]

7
run.sh
View File

@ -5,12 +5,17 @@ if [ -f ./.second_run ]; then
python manage.py migrate
else
python manage.py makemigrations core
python manage.py makemigrations customer
python manage.py makemigrations customers
python manage.py makemigrations devices
python manage.py makemigrations inventory
python manage.py makemigrations nets
python manage.py makemigrations users
python manage.py makemigrations
python manage.py migrate
python manage.py loaddata core
python manage.py loaddata devices
python manage.py loaddata inventory
python manage.py loaddata nets
python manage.py shell -c "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', 'admin@example.com', 'password')"
touch .second_run
fi

View File

@ -1,3 +1,81 @@
from django.contrib import admin
# Register your models here.
from inventory.models import LicenseWithUser
from .models import (
AdGroup,
MailAlias,
MailGroup,
User,
UserInAdGroup,
UserInMailGroup,
)
class MailAliasAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
Return empty perms dict thus hiding the model from admin index.
"""
return {}
class UserInAdGroupAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
Return empty perms dict thus hiding the model from admin index.
"""
return {}
class UserInMailGroupAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
Return empty perms dict thus hiding the model from admin index.
"""
return {}
class LicenseWithUserAdmin(admin.ModelAdmin):
def get_model_perms(self, request):
"""
Return empty perms dict thus hiding the model from admin index.
"""
return {}
class LicenseWithUserInLine(admin.StackedInline):
model = LicenseWithUser
extra = 0
verbose_name_plural = 'Licenses'
class AdGroupInLine(admin.StackedInline):
model = UserInAdGroup
extra = 0
verbose_name_plural = 'AD Groups'
class MailGroupInLine(admin.StackedInline):
model = UserInMailGroup
extra = 0
verbose_name_plural = 'Mail Groups'
class MailAliasInLine(admin.StackedInline):
model = MailAlias
extra = 0
verbose_name_plural = 'Mail Aliases'
class UserAdmin(admin.ModelAdmin):
list_display = ('name', 'customer', 'enabled')
inlines = (AdGroupInLine, MailGroupInLine, MailAliasInLine, LicenseWithUserInLine)
admin.site.register(AdGroup)
admin.site.register(MailAlias, MailAliasAdmin)
admin.site.register(MailGroup)
admin.site.register(User, UserAdmin)
admin.site.register(UserInAdGroup, UserInAdGroupAdmin)
admin.site.register(UserInMailGroup, UserInMailGroupAdmin)

17
users/decorators.py Normal file
View File

@ -0,0 +1,17 @@
from django.http import HttpResponseForbidden
from django.shortcuts import get_object_or_404
from .models import User
def user_view_permission(old_fuction):
def new_function(request, pk, *args, **kwargs):
inventory_user = get_object_or_404(User, pk=pk)
user = request.user
if user.has_perm('customers.view_customer', inventory_user.customer):
return old_fuction(request, pk)
else:
return HttpResponseForbidden(
"You're not allowed to access this device."
)
return new_function

View File

@ -0,0 +1,3 @@
from .user import User, UserInAdGroup, UserInMailGroup
from .groups import AdGroup, Group, MailGroup
from .mailalias import MailAlias

View File

@ -1,5 +1,5 @@
from django.db import models
from customer.models import Customer
from customers.models import Customer
class Group(models.Model):

View File

@ -1,5 +1,5 @@
from django.db import models
from .user import User
from users.models import User
class MailAlias(models.Model):

View File

@ -1,5 +1,5 @@
from django.db import models
from customer.models import Customer
from customers.models import Customer
from .groups import AdGroup, MailGroup

15
users/tables.py Normal file
View File

@ -0,0 +1,15 @@
import django_tables2 as tables
from .models import User
class UsersTable(tables.Table):
id = tables.Column(visible=False)
name = tables.Column('User', linkify=True)
customer = tables.Column('Customer', linkify=True)
ad_groups = tables.ManyToManyColumn()
mail_groups = tables.ManyToManyColumn()
class Meta:
template_name = 'django_tables2/semantic.html'
model = User

View File

@ -0,0 +1,23 @@
{% extends "inventory/base.html" %}
{% load render_table from django_tables2 %}
{% block section_title %}List of Computers{% endblock %}
{% block content %}
<div class="ui form">
<form action="" method="get" class="ui form">
<div class="fields">
<div class="field">
{{ filter.form.name__contains.label_tag }}
{{ filter.form.name__contains }}
</div>
<div class="field">
{{ filter.form.owner.label_tag }}
{{ filter.form.owner }}
</div>
<div class="field">
<button type="submit" class="ui button">Submit</button>
</div>
</div>
</form>
</div>
{% render_table table %}
{% endblock %}

View File

@ -0,0 +1,82 @@
{% extends "inventory/base.html" %}
{% block section_title %}{{ backup.name }}{% endblock %}
{% block content %}
<div class="ui cards">
<div class="card">
<div class="content">
<div class="header">Description</div>
<div class="description"><p>{{ backup.description }}</p></div>
<table class="ui celled table">
<tr>
<td><b>Computer:</b></td>
<td><a href="{% url 'computer' backup.computer.id %}">{{ backup.computer }}</a></td>
</tr>
<tr>
<td><b>Backup Method:</b></td>
<td>{{ backup.method }}</td>
</tr>
<tr>
<td><b>Backup Software:</b></td>
<td>{{ backup.software }}</td>
</tr>
<tr>
<td><b>Exec Time:</b></td>
<td>{{ backup.exec_time }}</td>
</tr>
<tr>
<td><b>Exec Day:</b></td>
<td>{{ backup.exec_day }}</td>
</tr>
</table>
</div>
</div>
{% if target_device_list %}
<div class="card">
<div class="content">
<div class="header">Target Devices</div>
{% for device in target_device_list %}
<table class="ui celled table">
<tr>
<td><b>Target Device:</b></td>
<td><a href="{% url 'computer' device.device.id %}">{{ device.device }}</a></td>
</tr>
<tr>
<td><b>Target Path:</b></td>
<td>{{ device.target_path }}</td>
</tr>
</table>
{% endfor %}
</div>
</div>
{% endif %}
{% if notifications %}
<div class="card">
<div class="content">
<div class="header">Notifications</div>
{% for notification in notifications %}
<table class="ui celled table">
<tr>
<td><b>Name:</b></td>
<td>{{ notification.notification }}</td>
</tr>
<tr>
<td><b>Description:</b></td>
<td>{{ notification.notification.description }}</td>
</tr>
<tr>
<td><b>Recipient:</b></td>
<td>{{ notification.notification.recipient }}</td>
</tr>
<tr>
<td><b>Type:</b></td>
<td>{{ notification.notification.notification_type }}</td>
</tr>
</table>
{% endfor %}
</div>
</div>
{% endif %}
</div>
{% endblock %}

View File

@ -0,0 +1,6 @@
{% extends "inventory/base.html" %}
{% load render_table from django_tables2 %}
{% block section_title %}List of Backups{% endblock %}
{% block content %}
{% render_table backups %}
{% endblock %}

View File

@ -0,0 +1,28 @@
{% load static %}
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css">
<title>Network Inventory</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="ui container">
<a href="{% url 'customers' %}">Home</a> |
<a href="{% url 'all_computers' %}">All Computers</a> |
{% if user.is_authenticated %}
<a href="{% url 'logout' %}">Logout</a> |
{% else %}
<a href="{% url 'login' %}" >Login</a> |
{% endif %}
<h1>{% block section_title %}Device Inventory{% endblock %}</h1>
{% block content %}{% endblock %}
<footer>
{% block footer %}
<p class="copyright">Created by Andreas Zweili licensed under GPL v3.0</p>
{% endblock %}
</footer>
</div>
<script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.js"></script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More