mirror of
https://github.com/Nebucatnetzer/network_inventory.git
synced 2024-06-29 04:31:03 +02:00
split the project into more apps
This commit is contained in:
parent
a45790ee99
commit
e3d1d73db9
|
@ -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)
|
||||
|
|
|
@ -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(
|
||||
|
|
28
customers/templates/inventory/base.html
Normal file
28
customers/templates/inventory/base.html
Normal 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>
|
24
customers/templates/registration/login.html
Normal file
24
customers/templates/registration/login.html
Normal 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 %}
|
|
@ -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) + "/")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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})
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
31
devices/decorators.py
Normal 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
|
21
devices/fixtures/devices.yaml
Normal file
21
devices/fixtures/devices.yaml
Normal 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
|
|
@ -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
12
devices/tables.py
Normal 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
|
23
devices/templates/inventory/all_computers.html
Normal file
23
devices/templates/inventory/all_computers.html
Normal 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 %}
|
82
devices/templates/inventory/backup_details.html
Normal file
82
devices/templates/inventory/backup_details.html
Normal 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 %}
|
6
devices/templates/inventory/backup_list.html
Normal file
6
devices/templates/inventory/backup_list.html
Normal 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 %}
|
28
devices/templates/inventory/base.html
Normal file
28
devices/templates/inventory/base.html
Normal 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>
|
171
devices/templates/inventory/computer_details.html
Normal file
171
devices/templates/inventory/computer_details.html
Normal 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 %}
|
6
devices/templates/inventory/computer_list.html
Normal file
6
devices/templates/inventory/computer_list.html
Normal 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 %}
|
28
devices/templates/inventory/cronjob_details.html
Normal file
28
devices/templates/inventory/cronjob_details.html
Normal 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 %}
|
28
devices/templates/inventory/cronjob_list.html
Normal file
28
devices/templates/inventory/cronjob_list.html
Normal 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 %}
|
6
devices/templates/inventory/customer_details.html
Normal file
6
devices/templates/inventory/customer_details.html
Normal 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 %}
|
6
devices/templates/inventory/customer_list.html
Normal file
6
devices/templates/inventory/customer_list.html
Normal 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 %}
|
43
devices/templates/inventory/device_details.html
Normal file
43
devices/templates/inventory/device_details.html
Normal 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 %}
|
6
devices/templates/inventory/device_list.html
Normal file
6
devices/templates/inventory/device_list.html
Normal 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 %}
|
9
devices/templates/inventory/license_list.html
Normal file
9
devices/templates/inventory/license_list.html
Normal 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 %}
|
9
devices/templates/inventory/net_details.html
Normal file
9
devices/templates/inventory/net_details.html
Normal 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 %}
|
6
devices/templates/inventory/net_list.html
Normal file
6
devices/templates/inventory/net_list.html
Normal 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 %}
|
106
devices/templates/inventory/user_details.html
Normal file
106
devices/templates/inventory/user_details.html
Normal 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 %}
|
6
devices/templates/inventory/user_list.html
Normal file
6
devices/templates/inventory/user_list.html
Normal 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 %}
|
24
devices/templates/registration/login.html
Normal file
24
devices/templates/registration/login.html
Normal 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 %}
|
|
@ -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) + "/")
|
|
@ -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)
|
||||
|
|
|
@ -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) + "/")
|
|
@ -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
10
devices/urls.py
Normal 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'),
|
||||
]
|
|
@ -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})
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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'),
|
||||
]
|
||||
|
|
|
@ -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
0
nets/__init__.py
Normal file
19
nets/admin.py
Normal file
19
nets/admin.py
Normal 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
5
nets/apps.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class NetsConfig(AppConfig):
|
||||
name = 'nets'
|
17
nets/decorators.py
Normal file
17
nets/decorators.py
Normal 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
12
nets/fixtures/nets.yaml
Normal 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
|
|
@ -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
24
nets/tables.py
Normal 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
|
9
nets/templates/nets/net_details.html
Normal file
9
nets/templates/nets/net_details.html
Normal 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 %}
|
6
nets/templates/nets/net_list.html
Normal file
6
nets/templates/nets/net_list.html
Normal 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 %}
|
|
@ -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) + "/")
|
|
@ -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
|
|
@ -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
9
nets/urls.py
Normal 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
32
nets/views.py
Normal 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})
|
|
@ -36,6 +36,7 @@ INSTALLED_APPS = [
|
|||
'guardian',
|
||||
'inventory.apps.InventoryConfig',
|
||||
'nested_admin',
|
||||
'nets.apps.NetsConfig',
|
||||
'users.apps.UsersConfig',
|
||||
]
|
||||
|
||||
|
|
|
@ -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
7
run.sh
|
@ -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
|
||||
|
|
|
@ -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
17
users/decorators.py
Normal 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
|
|
@ -0,0 +1,3 @@
|
|||
from .user import User, UserInAdGroup, UserInMailGroup
|
||||
from .groups import AdGroup, Group, MailGroup
|
||||
from .mailalias import MailAlias
|
|
@ -1,5 +1,5 @@
|
|||
from django.db import models
|
||||
from customer.models import Customer
|
||||
from customers.models import Customer
|
||||
|
||||
|
||||
class Group(models.Model):
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from django.db import models
|
||||
from .user import User
|
||||
from users.models import User
|
||||
|
||||
|
||||
class MailAlias(models.Model):
|
|
@ -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
15
users/tables.py
Normal 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
|
23
users/templates/inventory/all_computers.html
Normal file
23
users/templates/inventory/all_computers.html
Normal 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 %}
|
82
users/templates/inventory/backup_details.html
Normal file
82
users/templates/inventory/backup_details.html
Normal 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 %}
|
6
users/templates/inventory/backup_list.html
Normal file
6
users/templates/inventory/backup_list.html
Normal 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 %}
|
28
users/templates/inventory/base.html
Normal file
28
users/templates/inventory/base.html
Normal 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
Loading…
Reference in New Issue
Block a user