diff --git a/conftest.py b/conftest.py index 8a50790..128b9ae 100644 --- a/conftest.py +++ b/conftest.py @@ -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) diff --git a/inventory/templates/inventory/base.html b/core/templates/core/base.html similarity index 100% rename from inventory/templates/inventory/base.html rename to core/templates/core/base.html diff --git a/inventory/templates/registration/login.html b/core/templates/registration/login.html similarity index 100% rename from inventory/templates/registration/login.html rename to core/templates/registration/login.html diff --git a/customers/decorators.py b/customers/decorators.py index ad2add4..875b964 100644 --- a/customers/decorators.py +++ b/customers/decorators.py @@ -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( diff --git a/inventory/templates/inventory/all_computers.html b/customers/templates/inventory/all_computers.html similarity index 100% rename from inventory/templates/inventory/all_computers.html rename to customers/templates/inventory/all_computers.html diff --git a/inventory/templates/inventory/backup_details.html b/customers/templates/inventory/backup_details.html similarity index 100% rename from inventory/templates/inventory/backup_details.html rename to customers/templates/inventory/backup_details.html diff --git a/inventory/templates/inventory/backup_list.html b/customers/templates/inventory/backup_list.html similarity index 100% rename from inventory/templates/inventory/backup_list.html rename to customers/templates/inventory/backup_list.html diff --git a/customers/templates/inventory/base.html b/customers/templates/inventory/base.html new file mode 100644 index 0000000..2517d3f --- /dev/null +++ b/customers/templates/inventory/base.html @@ -0,0 +1,28 @@ +{% load static %} + + + + Network Inventory + + + + +
+ Home | + All Computers | + {% if user.is_authenticated %} + Logout | + {% else %} + Login | + {% endif %} +

{% block section_title %}Device Inventory{% endblock %}

+ {% block content %}{% endblock %} + +
+ + + diff --git a/inventory/templates/inventory/computer_details.html b/customers/templates/inventory/computer_details.html similarity index 100% rename from inventory/templates/inventory/computer_details.html rename to customers/templates/inventory/computer_details.html diff --git a/inventory/templates/inventory/computer_list.html b/customers/templates/inventory/computer_list.html similarity index 100% rename from inventory/templates/inventory/computer_list.html rename to customers/templates/inventory/computer_list.html diff --git a/inventory/templates/inventory/cronjob_details.html b/customers/templates/inventory/cronjob_details.html similarity index 100% rename from inventory/templates/inventory/cronjob_details.html rename to customers/templates/inventory/cronjob_details.html diff --git a/inventory/templates/inventory/cronjob_list.html b/customers/templates/inventory/cronjob_list.html similarity index 100% rename from inventory/templates/inventory/cronjob_list.html rename to customers/templates/inventory/cronjob_list.html diff --git a/inventory/templates/inventory/customer_details.html b/customers/templates/inventory/customer_details.html similarity index 100% rename from inventory/templates/inventory/customer_details.html rename to customers/templates/inventory/customer_details.html diff --git a/inventory/templates/inventory/customer_list.html b/customers/templates/inventory/customer_list.html similarity index 100% rename from inventory/templates/inventory/customer_list.html rename to customers/templates/inventory/customer_list.html diff --git a/inventory/templates/inventory/device_details.html b/customers/templates/inventory/device_details.html similarity index 100% rename from inventory/templates/inventory/device_details.html rename to customers/templates/inventory/device_details.html diff --git a/inventory/templates/inventory/device_list.html b/customers/templates/inventory/device_list.html similarity index 100% rename from inventory/templates/inventory/device_list.html rename to customers/templates/inventory/device_list.html diff --git a/inventory/templates/inventory/license_list.html b/customers/templates/inventory/license_list.html similarity index 100% rename from inventory/templates/inventory/license_list.html rename to customers/templates/inventory/license_list.html diff --git a/inventory/templates/inventory/net_details.html b/customers/templates/inventory/net_details.html similarity index 100% rename from inventory/templates/inventory/net_details.html rename to customers/templates/inventory/net_details.html diff --git a/inventory/templates/inventory/net_list.html b/customers/templates/inventory/net_list.html similarity index 100% rename from inventory/templates/inventory/net_list.html rename to customers/templates/inventory/net_list.html diff --git a/inventory/templates/inventory/user_details.html b/customers/templates/inventory/user_details.html similarity index 100% rename from inventory/templates/inventory/user_details.html rename to customers/templates/inventory/user_details.html diff --git a/inventory/templates/inventory/user_list.html b/customers/templates/inventory/user_list.html similarity index 100% rename from inventory/templates/inventory/user_list.html rename to customers/templates/inventory/user_list.html diff --git a/customers/templates/registration/login.html b/customers/templates/registration/login.html new file mode 100644 index 0000000..70b7127 --- /dev/null +++ b/customers/templates/registration/login.html @@ -0,0 +1,24 @@ +{% extends 'inventory/base.html' %} + +{% block section_title %}Login{% endblock %} + +{% block content %} +
+{% csrf_token %} +

+ +

+ +
+

+

+ +

+ +
+

+

+ +

+

+{% endblock %} diff --git a/customers/tests/test_customer.py b/customers/tests/test_customer.py index 1f415ce..b398606 100644 --- a/customers/tests/test_customer.py +++ b/customers/tests/test_customer.py @@ -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) + "/") diff --git a/customers/tests/test_customer_detail_view.py b/customers/tests/test_customer_detail_view.py index 68ea0e4..8fd8705 100644 --- a/customers/tests/test_customer_detail_view.py +++ b/customers/tests/test_customer_detail_view.py @@ -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 diff --git a/customers/tests/test_customer_list_view.py b/customers/tests/test_customer_list_view.py index e66b310..5243de4 100644 --- a/customers/tests/test_customer_list_view.py +++ b/customers/tests/test_customer_list_view.py @@ -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") diff --git a/customers/views.py b/customers/views.py index b067bec..24eff63 100644 --- a/customers/views.py +++ b/customers/views.py @@ -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}) diff --git a/devices/admin.py b/devices/admin.py index 8c38f3f..fcc8486 100644 --- a/devices/admin.py +++ b/devices/admin.py @@ -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) diff --git a/devices/apps.py b/devices/apps.py index 41481ef..d43cc4b 100644 --- a/devices/apps.py +++ b/devices/apps.py @@ -1,5 +1,5 @@ from django.apps import AppConfig -class DeviceConfig(AppConfig): - name = 'device' +class DevicesConfig(AppConfig): + name = 'devices' diff --git a/devices/decorators.py b/devices/decorators.py new file mode 100644 index 0000000..5d210d1 --- /dev/null +++ b/devices/decorators.py @@ -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 diff --git a/devices/fixtures/devices.yaml b/devices/fixtures/devices.yaml new file mode 100644 index 0000000..8f68d0c --- /dev/null +++ b/devices/fixtures/devices.yaml @@ -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 diff --git a/devices/models.py b/devices/models.py index 8322e3a..85fbb97 100644 --- a/devices/models.py +++ b/devices/models.py @@ -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): diff --git a/devices/tables.py b/devices/tables.py new file mode 100644 index 0000000..2cad213 --- /dev/null +++ b/devices/tables.py @@ -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 diff --git a/devices/templates/inventory/all_computers.html b/devices/templates/inventory/all_computers.html new file mode 100644 index 0000000..b960e29 --- /dev/null +++ b/devices/templates/inventory/all_computers.html @@ -0,0 +1,23 @@ +{% extends "inventory/base.html" %} +{% load render_table from django_tables2 %} +{% block section_title %}List of Computers{% endblock %} +{% block content %} +
+
+
+
+ {{ filter.form.name__contains.label_tag }} + {{ filter.form.name__contains }} +
+
+ {{ filter.form.owner.label_tag }} + {{ filter.form.owner }} +
+
+ +
+
+
+
+{% render_table table %} +{% endblock %} diff --git a/devices/templates/inventory/backup_details.html b/devices/templates/inventory/backup_details.html new file mode 100644 index 0000000..190f0c8 --- /dev/null +++ b/devices/templates/inventory/backup_details.html @@ -0,0 +1,82 @@ +{% extends "inventory/base.html" %} +{% block section_title %}{{ backup.name }}{% endblock %} +{% block content %} +
+
+
+
Description
+

{{ backup.description }}

+ + + + + + + + + + + + + + + + + + + + + +
Computer:{{ backup.computer }}
Backup Method:{{ backup.method }}
Backup Software:{{ backup.software }}
Exec Time:{{ backup.exec_time }}
Exec Day:{{ backup.exec_day }}
+
+
+ + {% if target_device_list %} +
+
+
Target Devices
+ {% for device in target_device_list %} + + + + + + + + + +
Target Device:{{ device.device }}
Target Path:{{ device.target_path }}
+ {% endfor %} +
+
+ {% endif %} + {% if notifications %} +
+
+
Notifications
+ {% for notification in notifications %} + + + + + + + + + + + + + + + + + + +
Name:{{ notification.notification }}
Description:{{ notification.notification.description }}
Recipient:{{ notification.notification.recipient }}
Type:{{ notification.notification.notification_type }}
+ {% endfor %} +
+
+ {% endif %} +
+{% endblock %} diff --git a/devices/templates/inventory/backup_list.html b/devices/templates/inventory/backup_list.html new file mode 100644 index 0000000..e726cf0 --- /dev/null +++ b/devices/templates/inventory/backup_list.html @@ -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 %} diff --git a/devices/templates/inventory/base.html b/devices/templates/inventory/base.html new file mode 100644 index 0000000..2517d3f --- /dev/null +++ b/devices/templates/inventory/base.html @@ -0,0 +1,28 @@ +{% load static %} + + + + Network Inventory + + + + +
+ Home | + All Computers | + {% if user.is_authenticated %} + Logout | + {% else %} + Login | + {% endif %} +

{% block section_title %}Device Inventory{% endblock %}

+ {% block content %}{% endblock %} + +
+ + + diff --git a/devices/templates/inventory/computer_details.html b/devices/templates/inventory/computer_details.html new file mode 100644 index 0000000..4637005 --- /dev/null +++ b/devices/templates/inventory/computer_details.html @@ -0,0 +1,171 @@ +{% extends "inventory/base.html" %} +{% block section_title %}{{ computer }}{% endblock %} +{% block content %} +
+
+
+
Description
+

{{ computer.description }}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {% if computer.user %} + + + + + {% endif %} + + + + + + + + +
OS:{{ computer.os }}
Serial Number:{{ computer.serialnumber }}
Category:{{ computer.category }}
Owner:{{ computer.owner }}
Customer:{{ computer.customer }}
Manufacturer:{{ computer.manufacturer }}
Location:{{ computer.location }}
User:{{ computer.user }}
Installation Date:{{ computer.installation_date }}
IPs: + {% for net_id, ip in computer.ips.items %} + {{ip}}
+ {% endfor %} +
+
+
+ {% if software_list or backup_list %} +
+
+ {% if software_list %} +
Software
+
    + {% for software in software_list %} +
  • {{ software.software }}
  • + {% endfor %} +
+ {% endif %} + {% if licenses %} +
Licenses
+ + {% for license in licenses %} + + + + + {% endfor %} +
{{ license.license.software }}{{ license.license.key }}
+ {% endif %} + {% if backup_list %} +
Backup
+
    + {% for backup in backup_list %} +
  • {{ backup }}
  • + {% endfor %} +
+ {% endif %} +
+
+ {% endif %} + + {% if cpu_list or ram_list or disks_list or raid_disk_pairs or computer.host %} +
+
+ {% if cpu_list or ram_list or disks_list or computer.host %} +
Hardware
+ + {% if cpu_list %} + + + + + {% endif %} + {% if ram_list %} + + + + + {% endif %} + {% if disks_list %} + + + + + {% endif %} +
CPUs: + {% for cpu in cpu_list %} + {{ cpu.amount }}x {{ cpu.cpu }}
+ {% endfor %} +
RAM Modules: + {% for module in ram_list %} + {{ module.amount }}x {{ module.ram }}
+ {% endfor %} +
Disks: + {% for disk in disks_list %} + {{ disk.amount }}x {{ disk.disk }}
+ {% endfor %} +
+ {% endif %} + + {% if raid_disk_pairs %} +
RAID
+ {% for raid, disks in raid_disk_pairs.items %} + + + + + + + + + + {% if disks %} + {% for disk in disks %} + + + + + + + + + {% endfor %} + {% endif %} +
Type:{{ raid.raid_type }}
Usable Space{{ raid.usable_space }}
Disk Type{{ disk.disk }}
Amount{{ disk.disk_amount }}
+ {% endfor %} + {% endif %} + + {% if computer.host %} +
Host
+ + {% endif %} +
+
+ {% endif %} + +
+{% endblock %} diff --git a/devices/templates/inventory/computer_list.html b/devices/templates/inventory/computer_list.html new file mode 100644 index 0000000..804f024 --- /dev/null +++ b/devices/templates/inventory/computer_list.html @@ -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 %} diff --git a/devices/templates/inventory/cronjob_details.html b/devices/templates/inventory/cronjob_details.html new file mode 100644 index 0000000..b47b2e5 --- /dev/null +++ b/devices/templates/inventory/cronjob_details.html @@ -0,0 +1,28 @@ +{% extends "inventory/base.html" %} +{% block section_title %}{{ cronjob.name }}{% endblock %} +{% block content %} +

Description

+

+ Host: {{ cronjob.host }} +

+

+ Command:
+ {{ cronjob.command }} +

+ + + + + + + + + + + + + + + +
MinuteHourDay of WeekDay of MonthMonth
{{ cronjob.minutes }}{{ cronjob.hours }}{{ cronjob.weekday }}{{ cronjob.day }}{{ cronjob.month }}
+{% endblock %} diff --git a/devices/templates/inventory/cronjob_list.html b/devices/templates/inventory/cronjob_list.html new file mode 100644 index 0000000..8252345 --- /dev/null +++ b/devices/templates/inventory/cronjob_list.html @@ -0,0 +1,28 @@ +{% extends "inventory/base.html" %} +{% block section_title %}List of Cron Jobs{% endblock %} +{% block content %} +{% if cronjob_list %} + + + + + + + + + + + {% for cronjob in cronjob_list %} + + + + + + + + + + {% endfor %} +
NameHostnameMinuteHourDay of WeekDay of MonthMonth
{{ cronjob.name }}{{ cronjob.host }}{{ cronjob.minutes }}{{ cronjob.hours }}{{ cronjob.weekday }}{{ cronjob.day }}{{ cronjob.month }}
+ {% endif %} +{% endblock %} diff --git a/devices/templates/inventory/customer_details.html b/devices/templates/inventory/customer_details.html new file mode 100644 index 0000000..1720642 --- /dev/null +++ b/devices/templates/inventory/customer_details.html @@ -0,0 +1,6 @@ +{% extends "inventory/base.html" %} +{% block section_title %}{{ customer.name }}{% endblock %} +{% block content %} +

Description

+

{{ customer.description }}

+{% endblock %} diff --git a/devices/templates/inventory/customer_list.html b/devices/templates/inventory/customer_list.html new file mode 100644 index 0000000..f678cde --- /dev/null +++ b/devices/templates/inventory/customer_list.html @@ -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 %} diff --git a/devices/templates/inventory/device_details.html b/devices/templates/inventory/device_details.html new file mode 100644 index 0000000..6ac2c41 --- /dev/null +++ b/devices/templates/inventory/device_details.html @@ -0,0 +1,43 @@ +{% extends "inventory/base.html" %} +{% block section_title %}{{ device.name }}{% endblock %} +{% block content %} +
+
+
+
Description
+

{{ device.description }}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Serial Number:{{ device.serialnumber }}
Category:{{ device.category }}
Owner:{{ device.owner }}
Customer:{{ device.customer }}
Manufacturer:{{ device.manufacturer }}
Location:{{ device.location }}
Installation Date:{{ device.installation_date }}
+
+
+
+{% endblock %} diff --git a/devices/templates/inventory/device_list.html b/devices/templates/inventory/device_list.html new file mode 100644 index 0000000..24a0b36 --- /dev/null +++ b/devices/templates/inventory/device_list.html @@ -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 %} diff --git a/devices/templates/inventory/license_list.html b/devices/templates/inventory/license_list.html new file mode 100644 index 0000000..eaf19ea --- /dev/null +++ b/devices/templates/inventory/license_list.html @@ -0,0 +1,9 @@ +{% extends "inventory/base.html" %} +{% load render_table from django_tables2 %} +{% block section_title %}Licenses{% endblock %} +{% block content %} +

User Licenses

+{% render_table user_licenses %} +

Computer Licenses

+{% render_table computer_licenses %} +{% endblock %} diff --git a/devices/templates/inventory/net_details.html b/devices/templates/inventory/net_details.html new file mode 100644 index 0000000..70db8c7 --- /dev/null +++ b/devices/templates/inventory/net_details.html @@ -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 %} +

{{ net.description }}

+{% endif %} +{% render_table table %} +{% endblock %} diff --git a/devices/templates/inventory/net_list.html b/devices/templates/inventory/net_list.html new file mode 100644 index 0000000..e270c58 --- /dev/null +++ b/devices/templates/inventory/net_list.html @@ -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 %} diff --git a/devices/templates/inventory/user_details.html b/devices/templates/inventory/user_details.html new file mode 100644 index 0000000..7c280cc --- /dev/null +++ b/devices/templates/inventory/user_details.html @@ -0,0 +1,106 @@ +{% extends "inventory/base.html" %} +{% block section_title %}{{ user }}{% endblock %} +{% block content %} +
+
+
+
Description
+

{{ user.description }}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Customer{{ user.customer }}
AD Login{{ user.ad_login }}
AD Password{{ user.ad_pw }}
Email Address{{ user.ad_login }}
Mail Password{{ user.mail_pw }}
User is activ{{ user.enabled }}
Comptuers + {% for computer in computers %} + {{ computer}} + {% endfor %} +
+
+
+ + {% if ad_groups or mail_groups or mail_alias %} +
+
+ {% if mail_alias %} +
Mail Alias
+ + {% for alias in mail_alias %} + + + + {% endfor %} +
+ {{ alias }} +
+ {% endif %} + + {% if ad_groups %} +
AD Groups
+ + {% for group in ad_groups %} + + + + {% endfor %} +
{{ group.group }}
+ {% endif %} + + {% if mail_groups %} +
Mail Groups
+ + + + {% for group in mail_groups %} + + + + + {% endfor %} +
Group NameAddress
{{ group.group }}{{ group.group.mail_address }}
+
+
+ {% endif %} + {% endif %} + + {% if licenses %} +
+
+
Licenses
+ + {% for license in licenses %} + + + + + {% endfor %} +
{{ license.license.software }}{{ license.license.key }}
+
+
+ {% endif %} +
+{% endblock %} diff --git a/devices/templates/inventory/user_list.html b/devices/templates/inventory/user_list.html new file mode 100644 index 0000000..65fc37c --- /dev/null +++ b/devices/templates/inventory/user_list.html @@ -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 %} diff --git a/devices/templates/registration/login.html b/devices/templates/registration/login.html new file mode 100644 index 0000000..70b7127 --- /dev/null +++ b/devices/templates/registration/login.html @@ -0,0 +1,24 @@ +{% extends 'inventory/base.html' %} + +{% block section_title %}Login{% endblock %} + +{% block content %} +
+{% csrf_token %} +

+ +

+ +
+

+

+ +

+ +
+

+

+ +

+

+{% endblock %} diff --git a/inventory/tests/test_models/test_connected_device.py b/devices/tests/test_connected_device.py similarity index 79% rename from inventory/tests/test_models/test_connected_device.py rename to devices/tests/test_connected_device.py index e361ca3..49b3354 100644 --- a/inventory/tests/test_models/test_connected_device.py +++ b/devices/tests/test_connected_device.py @@ -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) + "/") diff --git a/devices/tests/test_customer_device_table_view.py b/devices/tests/test_customer_device_table_view.py index 9a8a245..d9633a4 100644 --- a/devices/tests/test_customer_device_table_view.py +++ b/devices/tests/test_customer_device_table_view.py @@ -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) diff --git a/inventory/tests/test_models/test_device.py b/devices/tests/test_device.py similarity index 82% rename from inventory/tests/test_models/test_device.py rename to devices/tests/test_device.py index f10a9b8..8e660de 100644 --- a/inventory/tests/test_models/test_device.py +++ b/devices/tests/test_device.py @@ -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) + "/") diff --git a/devices/tests/test_device_detail_view.py b/devices/tests/test_device_detail_view.py index 5215413..615728f 100644 --- a/devices/tests/test_device_detail_view.py +++ b/devices/tests/test_device_detail_view.py @@ -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) + '/') diff --git a/devices/urls.py b/devices/urls.py new file mode 100644 index 0000000..f3ff95b --- /dev/null +++ b/devices/urls.py @@ -0,0 +1,10 @@ +from django.urls import path + +from . import views + + +urlpatterns = [ + path('customer//devices/', views.devices_table_view, + name='devices'), + path('device//', views.device_detail_view, name='device'), +] diff --git a/devices/views.py b/devices/views.py index 91ea44a..11ad91f 100644 --- a/devices/views.py +++ b/devices/views.py @@ -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}) diff --git a/inventory/admin.py b/inventory/admin.py index d16e07d..f4e8023 100644 --- a/inventory/admin.py +++ b/inventory/admin.py @@ -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) - diff --git a/inventory/decorators.py b/inventory/decorators.py index 03f7be6..2a137eb 100644 --- a/inventory/decorators.py +++ b/inventory/decorators.py @@ -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( diff --git a/inventory/fixtures/inventory.yaml b/inventory/fixtures/inventory.yaml index c9f5306..f1ae9d9 100644 --- a/inventory/fixtures/inventory.yaml +++ b/inventory/fixtures/inventory.yaml @@ -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" diff --git a/inventory/models/__init__.py b/inventory/models/__init__.py index 2dc165d..c02007e 100644 --- a/inventory/models/__init__.py +++ b/inventory/models/__init__.py @@ -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 diff --git a/inventory/models/computer.py b/inventory/models/computer.py index c1a0f90..1bd8d10 100644 --- a/inventory/models/computer.py +++ b/inventory/models/computer.py @@ -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 diff --git a/inventory/models/license.py b/inventory/models/license.py index 0ae0da0..f60396d 100644 --- a/inventory/models/license.py +++ b/inventory/models/license.py @@ -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 diff --git a/inventory/models/warranty.py b/inventory/models/warranty.py index ecc5f04..c56f287 100644 --- a/inventory/models/warranty.py +++ b/inventory/models/warranty.py @@ -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): diff --git a/inventory/tables.py b/inventory/tables.py index 8e1d24f..dc5f2ed 100644 --- a/inventory/tables.py +++ b/inventory/tables.py @@ -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 diff --git a/inventory/tests/test_models/test_license.py b/inventory/tests/test_models/test_license.py index 4fdfa35..51ccf4c 100644 --- a/inventory/tests/test_models/test_license.py +++ b/inventory/tests/test_models/test_license.py @@ -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', diff --git a/inventory/tests/test_views/test_backup_detail_view.py b/inventory/tests/test_views/test_backup_detail_view.py index 55d1ee2..f75259b 100644 --- a/inventory/tests/test_views/test_backup_detail_view.py +++ b/inventory/tests/test_views/test_backup_detail_view.py @@ -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 diff --git a/inventory/tests/test_views/test_computer_detail_view.py b/inventory/tests/test_views/test_computer_detail_view.py index 81baa03..dfbba9c 100644 --- a/inventory/tests/test_views/test_computer_detail_view.py +++ b/inventory/tests/test_views/test_computer_detail_view.py @@ -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") diff --git a/inventory/tests/test_views/test_customer_backup_table_view.py b/inventory/tests/test_views/test_customer_backup_table_view.py index 192490d..998ff8d 100644 --- a/inventory/tests/test_views/test_customer_backup_table_view.py +++ b/inventory/tests/test_views/test_customer_backup_table_view.py @@ -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 diff --git a/inventory/tests/test_views/test_customer_computer_table_view.py b/inventory/tests/test_views/test_customer_computer_table_view.py index aec9938..b663d7c 100644 --- a/inventory/tests/test_views/test_customer_computer_table_view.py +++ b/inventory/tests/test_views/test_customer_computer_table_view.py @@ -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 diff --git a/inventory/tests/test_views/test_customer_license_table_view.py b/inventory/tests/test_views/test_customer_license_table_view.py index 91da230..2336253 100644 --- a/inventory/tests/test_views/test_customer_license_table_view.py +++ b/inventory/tests/test_views/test_customer_license_table_view.py @@ -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, diff --git a/inventory/urls.py b/inventory/urls.py index c27fc09..cc84805 100644 --- a/inventory/urls.py +++ b/inventory/urls.py @@ -6,22 +6,13 @@ urlpatterns = [ path('accounts/', include('django.contrib.auth.urls')), path('customer//computers/', views.computers_table_view, name='computers'), - path('customer//devices/', views.devices_table_view, - name='devices'), - path('customer//nets/', views.nets_table_view, - name='nets'), path('customer//backups/', views.backups_table_view, name='backups'), path('computer//', views.computer_detail_view, name='computer'), - path('device//', views.device_detail_view, name='device'), - path('net//', views.net_detail_view, name='net'), path('backup//', views.backup_detail_view, name='backup'), path('computers/all/', views.ComputersFilterView.as_view(), name='all_computers'), path('customer//licenses/', views.licenses_table_view, name='licenses'), - path('customer//users/', views.users_table_view, - name='users'), - path('user//', views.user_detail_view, name='user'), ] diff --git a/inventory/views.py b/inventory/views.py index 9cd4d49..edcfad5 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -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}) diff --git a/nets/__init__.py b/nets/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nets/admin.py b/nets/admin.py new file mode 100644 index 0000000..13cac16 --- /dev/null +++ b/nets/admin.py @@ -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) diff --git a/nets/apps.py b/nets/apps.py new file mode 100644 index 0000000..cb734db --- /dev/null +++ b/nets/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class NetsConfig(AppConfig): + name = 'nets' diff --git a/nets/decorators.py b/nets/decorators.py new file mode 100644 index 0000000..651f1aa --- /dev/null +++ b/nets/decorators.py @@ -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 diff --git a/nets/fixtures/nets.yaml b/nets/fixtures/nets.yaml new file mode 100644 index 0000000..a98f3f4 --- /dev/null +++ b/nets/fixtures/nets.yaml @@ -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 diff --git a/inventory/models/net.py b/nets/models.py similarity index 94% rename from inventory/models/net.py rename to nets/models.py index cb4666c..9622cdf 100644 --- a/inventory/models/net.py +++ b/nets/models.py @@ -1,5 +1,5 @@ from django.db import models -from customer.models import Customer +from customers.models import Customer from core.models import Category diff --git a/nets/tables.py b/nets/tables.py new file mode 100644 index 0000000..3119cb4 --- /dev/null +++ b/nets/tables.py @@ -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 diff --git a/nets/templates/nets/net_details.html b/nets/templates/nets/net_details.html new file mode 100644 index 0000000..70db8c7 --- /dev/null +++ b/nets/templates/nets/net_details.html @@ -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 %} +

{{ net.description }}

+{% endif %} +{% render_table table %} +{% endblock %} diff --git a/nets/templates/nets/net_list.html b/nets/templates/nets/net_list.html new file mode 100644 index 0000000..e270c58 --- /dev/null +++ b/nets/templates/nets/net_list.html @@ -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 %} diff --git a/inventory/tests/test_models/test_net.py b/nets/tests/test_models/test_net.py similarity index 83% rename from inventory/tests/test_models/test_net.py rename to nets/tests/test_models/test_net.py index 85a08d7..9418f0a 100644 --- a/inventory/tests/test_models/test_net.py +++ b/nets/tests/test_models/test_net.py @@ -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) + "/") diff --git a/inventory/tests/test_views/test_customer_net_table_view.py b/nets/tests/test_views/test_customer_net_table_view.py similarity index 89% rename from inventory/tests/test_views/test_customer_net_table_view.py rename to nets/tests/test_views/test_customer_net_table_view.py index dbb6d0b..3795b58 100644 --- a/inventory/tests/test_views/test_customer_net_table_view.py +++ b/nets/tests/test_views/test_customer_net_table_view.py @@ -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 diff --git a/inventory/tests/test_views/test_net_detail_view.py b/nets/tests/test_views/test_net_detail_view.py similarity index 84% rename from inventory/tests/test_views/test_net_detail_view.py rename to nets/tests/test_views/test_net_detail_view.py index 9d623c9..21a7ff6 100644 --- a/inventory/tests/test_views/test_net_detail_view.py +++ b/nets/tests/test_views/test_net_detail_view.py @@ -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/') diff --git a/nets/urls.py b/nets/urls.py new file mode 100644 index 0000000..03ce4e9 --- /dev/null +++ b/nets/urls.py @@ -0,0 +1,9 @@ +from django.urls import path + +from . import views + +urlpatterns = [ + path('customer//nets/', views.nets_table_view, + name='nets'), + path('net//', views.net_detail_view, name='net'), + ] diff --git a/nets/views.py b/nets/views.py new file mode 100644 index 0000000..44cc420 --- /dev/null +++ b/nets/views.py @@ -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}) diff --git a/network_inventory/settings/base.py b/network_inventory/settings/base.py index 0f5345a..70fd69f 100644 --- a/network_inventory/settings/base.py +++ b/network_inventory/settings/base.py @@ -36,6 +36,7 @@ INSTALLED_APPS = [ 'guardian', 'inventory.apps.InventoryConfig', 'nested_admin', + 'nets.apps.NetsConfig', 'users.apps.UsersConfig', ] diff --git a/network_inventory/urls.py b/network_inventory/urls.py index 0e73dd2..59a31b3 100644 --- a/network_inventory/urls.py +++ b/network_inventory/urls.py @@ -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')), ] diff --git a/run.sh b/run.sh index 09f5ced..34e4a3b 100755 --- a/run.sh +++ b/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 diff --git a/users/admin.py b/users/admin.py index 8c38f3f..c77bf81 100644 --- a/users/admin.py +++ b/users/admin.py @@ -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) diff --git a/users/decorators.py b/users/decorators.py new file mode 100644 index 0000000..65622f1 --- /dev/null +++ b/users/decorators.py @@ -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 diff --git a/users/models/__init__.py b/users/models/__init__.py index e69de29..c908c26 100644 --- a/users/models/__init__.py +++ b/users/models/__init__.py @@ -0,0 +1,3 @@ +from .user import User, UserInAdGroup, UserInMailGroup +from .groups import AdGroup, Group, MailGroup +from .mailalias import MailAlias diff --git a/users/models/groups.py b/users/models/groups.py index 004e511..068e6f6 100644 --- a/users/models/groups.py +++ b/users/models/groups.py @@ -1,5 +1,5 @@ from django.db import models -from customer.models import Customer +from customers.models import Customer class Group(models.Model): diff --git a/inventory/models/mailalias.py b/users/models/mailalias.py similarity index 90% rename from inventory/models/mailalias.py rename to users/models/mailalias.py index 3241a57..a7f2d6b 100644 --- a/inventory/models/mailalias.py +++ b/users/models/mailalias.py @@ -1,5 +1,5 @@ from django.db import models -from .user import User +from users.models import User class MailAlias(models.Model): diff --git a/users/models/user.py b/users/models/user.py index c7f5cdc..07d8aa3 100644 --- a/users/models/user.py +++ b/users/models/user.py @@ -1,5 +1,5 @@ from django.db import models -from customer.models import Customer +from customers.models import Customer from .groups import AdGroup, MailGroup diff --git a/users/tables.py b/users/tables.py new file mode 100644 index 0000000..c42b3c9 --- /dev/null +++ b/users/tables.py @@ -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 diff --git a/users/templates/inventory/all_computers.html b/users/templates/inventory/all_computers.html new file mode 100644 index 0000000..b960e29 --- /dev/null +++ b/users/templates/inventory/all_computers.html @@ -0,0 +1,23 @@ +{% extends "inventory/base.html" %} +{% load render_table from django_tables2 %} +{% block section_title %}List of Computers{% endblock %} +{% block content %} +
+
+
+
+ {{ filter.form.name__contains.label_tag }} + {{ filter.form.name__contains }} +
+
+ {{ filter.form.owner.label_tag }} + {{ filter.form.owner }} +
+
+ +
+
+
+
+{% render_table table %} +{% endblock %} diff --git a/users/templates/inventory/backup_details.html b/users/templates/inventory/backup_details.html new file mode 100644 index 0000000..190f0c8 --- /dev/null +++ b/users/templates/inventory/backup_details.html @@ -0,0 +1,82 @@ +{% extends "inventory/base.html" %} +{% block section_title %}{{ backup.name }}{% endblock %} +{% block content %} +
+
+
+
Description
+

{{ backup.description }}

+ + + + + + + + + + + + + + + + + + + + + +
Computer:{{ backup.computer }}
Backup Method:{{ backup.method }}
Backup Software:{{ backup.software }}
Exec Time:{{ backup.exec_time }}
Exec Day:{{ backup.exec_day }}
+
+
+ + {% if target_device_list %} +
+
+
Target Devices
+ {% for device in target_device_list %} + + + + + + + + + +
Target Device:{{ device.device }}
Target Path:{{ device.target_path }}
+ {% endfor %} +
+
+ {% endif %} + {% if notifications %} +
+
+
Notifications
+ {% for notification in notifications %} + + + + + + + + + + + + + + + + + + +
Name:{{ notification.notification }}
Description:{{ notification.notification.description }}
Recipient:{{ notification.notification.recipient }}
Type:{{ notification.notification.notification_type }}
+ {% endfor %} +
+
+ {% endif %} +
+{% endblock %} diff --git a/users/templates/inventory/backup_list.html b/users/templates/inventory/backup_list.html new file mode 100644 index 0000000..e726cf0 --- /dev/null +++ b/users/templates/inventory/backup_list.html @@ -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 %} diff --git a/users/templates/inventory/base.html b/users/templates/inventory/base.html new file mode 100644 index 0000000..2517d3f --- /dev/null +++ b/users/templates/inventory/base.html @@ -0,0 +1,28 @@ +{% load static %} + + + + Network Inventory + + + + +
+ Home | + All Computers | + {% if user.is_authenticated %} + Logout | + {% else %} + Login | + {% endif %} +

{% block section_title %}Device Inventory{% endblock %}

+ {% block content %}{% endblock %} +
+ {% block footer %} + + {% endblock %} +
+
+ + + diff --git a/users/templates/inventory/computer_details.html b/users/templates/inventory/computer_details.html new file mode 100644 index 0000000..4637005 --- /dev/null +++ b/users/templates/inventory/computer_details.html @@ -0,0 +1,171 @@ +{% extends "inventory/base.html" %} +{% block section_title %}{{ computer }}{% endblock %} +{% block content %} +
+
+
+
Description
+

{{ computer.description }}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {% if computer.user %} + + + + + {% endif %} + + + + + + + + +
OS:{{ computer.os }}
Serial Number:{{ computer.serialnumber }}
Category:{{ computer.category }}
Owner:{{ computer.owner }}
Customer:{{ computer.customer }}
Manufacturer:{{ computer.manufacturer }}
Location:{{ computer.location }}
User:{{ computer.user }}
Installation Date:{{ computer.installation_date }}
IPs: + {% for net_id, ip in computer.ips.items %} + {{ip}}
+ {% endfor %} +
+
+
+ {% if software_list or backup_list %} +
+
+ {% if software_list %} +
Software
+
    + {% for software in software_list %} +
  • {{ software.software }}
  • + {% endfor %} +
+ {% endif %} + {% if licenses %} +
Licenses
+ + {% for license in licenses %} + + + + + {% endfor %} +
{{ license.license.software }}{{ license.license.key }}
+ {% endif %} + {% if backup_list %} +
Backup
+
    + {% for backup in backup_list %} +
  • {{ backup }}
  • + {% endfor %} +
+ {% endif %} +
+
+ {% endif %} + + {% if cpu_list or ram_list or disks_list or raid_disk_pairs or computer.host %} +
+
+ {% if cpu_list or ram_list or disks_list or computer.host %} +
Hardware
+ + {% if cpu_list %} + + + + + {% endif %} + {% if ram_list %} + + + + + {% endif %} + {% if disks_list %} + + + + + {% endif %} +
CPUs: + {% for cpu in cpu_list %} + {{ cpu.amount }}x {{ cpu.cpu }}
+ {% endfor %} +
RAM Modules: + {% for module in ram_list %} + {{ module.amount }}x {{ module.ram }}
+ {% endfor %} +
Disks: + {% for disk in disks_list %} + {{ disk.amount }}x {{ disk.disk }}
+ {% endfor %} +
+ {% endif %} + + {% if raid_disk_pairs %} +
RAID
+ {% for raid, disks in raid_disk_pairs.items %} + + + + + + + + + + {% if disks %} + {% for disk in disks %} + + + + + + + + + {% endfor %} + {% endif %} +
Type:{{ raid.raid_type }}
Usable Space{{ raid.usable_space }}
Disk Type{{ disk.disk }}
Amount{{ disk.disk_amount }}
+ {% endfor %} + {% endif %} + + {% if computer.host %} +
Host
+ + {% endif %} +
+
+ {% endif %} + +
+{% endblock %} diff --git a/users/templates/inventory/computer_list.html b/users/templates/inventory/computer_list.html new file mode 100644 index 0000000..804f024 --- /dev/null +++ b/users/templates/inventory/computer_list.html @@ -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 %} diff --git a/users/templates/inventory/cronjob_details.html b/users/templates/inventory/cronjob_details.html new file mode 100644 index 0000000..b47b2e5 --- /dev/null +++ b/users/templates/inventory/cronjob_details.html @@ -0,0 +1,28 @@ +{% extends "inventory/base.html" %} +{% block section_title %}{{ cronjob.name }}{% endblock %} +{% block content %} +

Description

+

+ Host: {{ cronjob.host }} +

+

+ Command:
+ {{ cronjob.command }} +

+ + + + + + + + + + + + + + + +
MinuteHourDay of WeekDay of MonthMonth
{{ cronjob.minutes }}{{ cronjob.hours }}{{ cronjob.weekday }}{{ cronjob.day }}{{ cronjob.month }}
+{% endblock %} diff --git a/users/templates/inventory/cronjob_list.html b/users/templates/inventory/cronjob_list.html new file mode 100644 index 0000000..8252345 --- /dev/null +++ b/users/templates/inventory/cronjob_list.html @@ -0,0 +1,28 @@ +{% extends "inventory/base.html" %} +{% block section_title %}List of Cron Jobs{% endblock %} +{% block content %} +{% if cronjob_list %} + + + + + + + + + + + {% for cronjob in cronjob_list %} + + + + + + + + + + {% endfor %} +
NameHostnameMinuteHourDay of WeekDay of MonthMonth
{{ cronjob.name }}{{ cronjob.host }}{{ cronjob.minutes }}{{ cronjob.hours }}{{ cronjob.weekday }}{{ cronjob.day }}{{ cronjob.month }}
+ {% endif %} +{% endblock %} diff --git a/users/templates/inventory/customer_details.html b/users/templates/inventory/customer_details.html new file mode 100644 index 0000000..1720642 --- /dev/null +++ b/users/templates/inventory/customer_details.html @@ -0,0 +1,6 @@ +{% extends "inventory/base.html" %} +{% block section_title %}{{ customer.name }}{% endblock %} +{% block content %} +

Description

+

{{ customer.description }}

+{% endblock %} diff --git a/users/templates/inventory/customer_list.html b/users/templates/inventory/customer_list.html new file mode 100644 index 0000000..f678cde --- /dev/null +++ b/users/templates/inventory/customer_list.html @@ -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 %} diff --git a/users/templates/inventory/device_details.html b/users/templates/inventory/device_details.html new file mode 100644 index 0000000..6ac2c41 --- /dev/null +++ b/users/templates/inventory/device_details.html @@ -0,0 +1,43 @@ +{% extends "inventory/base.html" %} +{% block section_title %}{{ device.name }}{% endblock %} +{% block content %} +
+
+
+
Description
+

{{ device.description }}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Serial Number:{{ device.serialnumber }}
Category:{{ device.category }}
Owner:{{ device.owner }}
Customer:{{ device.customer }}
Manufacturer:{{ device.manufacturer }}
Location:{{ device.location }}
Installation Date:{{ device.installation_date }}
+
+
+
+{% endblock %} diff --git a/users/templates/inventory/device_list.html b/users/templates/inventory/device_list.html new file mode 100644 index 0000000..24a0b36 --- /dev/null +++ b/users/templates/inventory/device_list.html @@ -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 %} diff --git a/users/templates/inventory/license_list.html b/users/templates/inventory/license_list.html new file mode 100644 index 0000000..eaf19ea --- /dev/null +++ b/users/templates/inventory/license_list.html @@ -0,0 +1,9 @@ +{% extends "inventory/base.html" %} +{% load render_table from django_tables2 %} +{% block section_title %}Licenses{% endblock %} +{% block content %} +

User Licenses

+{% render_table user_licenses %} +

Computer Licenses

+{% render_table computer_licenses %} +{% endblock %} diff --git a/users/templates/inventory/net_details.html b/users/templates/inventory/net_details.html new file mode 100644 index 0000000..70db8c7 --- /dev/null +++ b/users/templates/inventory/net_details.html @@ -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 %} +

{{ net.description }}

+{% endif %} +{% render_table table %} +{% endblock %} diff --git a/users/templates/inventory/net_list.html b/users/templates/inventory/net_list.html new file mode 100644 index 0000000..e270c58 --- /dev/null +++ b/users/templates/inventory/net_list.html @@ -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 %} diff --git a/users/templates/inventory/user_details.html b/users/templates/inventory/user_details.html new file mode 100644 index 0000000..7c280cc --- /dev/null +++ b/users/templates/inventory/user_details.html @@ -0,0 +1,106 @@ +{% extends "inventory/base.html" %} +{% block section_title %}{{ user }}{% endblock %} +{% block content %} +
+
+
+
Description
+

{{ user.description }}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Customer{{ user.customer }}
AD Login{{ user.ad_login }}
AD Password{{ user.ad_pw }}
Email Address{{ user.ad_login }}
Mail Password{{ user.mail_pw }}
User is activ{{ user.enabled }}
Comptuers + {% for computer in computers %} + {{ computer}} + {% endfor %} +
+
+
+ + {% if ad_groups or mail_groups or mail_alias %} +
+
+ {% if mail_alias %} +
Mail Alias
+ + {% for alias in mail_alias %} + + + + {% endfor %} +
+ {{ alias }} +
+ {% endif %} + + {% if ad_groups %} +
AD Groups
+ + {% for group in ad_groups %} + + + + {% endfor %} +
{{ group.group }}
+ {% endif %} + + {% if mail_groups %} +
Mail Groups
+ + + + {% for group in mail_groups %} + + + + + {% endfor %} +
Group NameAddress
{{ group.group }}{{ group.group.mail_address }}
+
+
+ {% endif %} + {% endif %} + + {% if licenses %} +
+
+
Licenses
+ + {% for license in licenses %} + + + + + {% endfor %} +
{{ license.license.software }}{{ license.license.key }}
+
+
+ {% endif %} +
+{% endblock %} diff --git a/users/templates/inventory/user_list.html b/users/templates/inventory/user_list.html new file mode 100644 index 0000000..65fc37c --- /dev/null +++ b/users/templates/inventory/user_list.html @@ -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 %} diff --git a/users/templates/registration/login.html b/users/templates/registration/login.html new file mode 100644 index 0000000..70b7127 --- /dev/null +++ b/users/templates/registration/login.html @@ -0,0 +1,24 @@ +{% extends 'inventory/base.html' %} + +{% block section_title %}Login{% endblock %} + +{% block content %} +
+{% csrf_token %} +

+ +

+ +
+

+

+ +

+ +
+

+

+ +

+

+{% endblock %} diff --git a/inventory/tests/test_views/test_customer_user_table_view.py b/users/tests/test_customer_user_table_view.py similarity index 79% rename from inventory/tests/test_views/test_customer_user_table_view.py rename to users/tests/test_customer_user_table_view.py index 3e2669d..92c69b8 100644 --- a/inventory/tests/test_views/test_customer_user_table_view.py +++ b/users/tests/test_customer_user_table_view.py @@ -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,11 +19,11 @@ def test_customer_user_table(create_admin_user): customer = fixture['customer'] client = Client() client.login(username="novartis-admin", password="password") - user = mixer.blend('inventory.User', customer=mixer.SELECT) - ad_group = mixer.blend('inventory.AdGroup') - mail_group = mixer.blend('inventory.MailGroup') - mixer.blend('inventory.UserInAdGroup', user=user, group=ad_group) - mixer.blend('inventory.UserInMailGroup', user=user, group=mail_group) + user = mixer.blend('users.User', customer=mixer.SELECT) + ad_group = mixer.blend('users.AdGroup') + mail_group = mixer.blend('users.MailGroup') + mixer.blend('users.UserInAdGroup', user=user, group=ad_group) + mixer.blend('users.UserInMailGroup', user=user, group=mail_group) response = client.get('/customer/' + str(customer.id) + '/users/') assert (response.status_code == 200 and helper.in_content(response, user.name) @@ -47,7 +47,7 @@ def test_customer_user_table_no_permission(create_admin_user): customer = Customer.objects.create(name='Nestle') client = Client() client.login(username="novartis-admin", password="password") - mixer.blend('inventory.User', customer=customer) + mixer.blend('users.User', customer=customer) response = client.get('/customer/' + str(customer.id) + '/users/') assert response.status_code == 403 @@ -57,8 +57,8 @@ def test_customer_user_table_multiple_users(create_admin_user): customer = fixture['customer'] client = Client() client.login(username="novartis-admin", password="password") - user1 = mixer.blend('inventory.User', customer=mixer.SELECT) - user2 = mixer.blend('inventory.User', customer=mixer.SELECT) + user1 = mixer.blend('users.User', customer=mixer.SELECT) + user2 = mixer.blend('users.User', customer=mixer.SELECT) response = client.get('/customer/' + str(customer.id) + '/users/') assert (response.status_code == 200 and helper.in_content(response, user1.name) diff --git a/inventory/tests/test_models/test_user.py b/users/tests/test_user.py similarity index 83% rename from inventory/tests/test_models/test_user.py rename to users/tests/test_user.py index f12ac82..c52db11 100644 --- a/inventory/tests/test_models/test_user.py +++ b/users/tests/test_user.py @@ -5,6 +5,6 @@ pytestmark = pytest.mark.django_db def test_user_reverse_url(): - user = mixer.blend('inventory.User') + user = mixer.blend('users.User') assert (user.get_absolute_url() == "/user/" + str(user.id) + "/") diff --git a/inventory/tests/test_views/test_user_detail_view.py b/users/tests/test_user_detail_view.py similarity index 79% rename from inventory/tests/test_views/test_user_detail_view.py rename to users/tests/test_user_detail_view.py index 1aac2c8..e8ddeca 100644 --- a/inventory/tests/test_views/test_user_detail_view.py +++ b/users/tests/test_user_detail_view.py @@ -15,7 +15,7 @@ def test_user_detail_view_not_logged_in(): def test_user_detail_view(create_admin_user): create_admin_user() - user = mixer.blend('inventory.User', customer=mixer.SELECT) + user = mixer.blend('users.User', customer=mixer.SELECT) client = Client() client.login(username="novartis-admin", password="password") response = client.get('/user/' + str(user.id) + '/') @@ -33,9 +33,9 @@ def test_user_detail_view_not_found(create_admin_user): def test_user_detail_view_ad_group(create_admin_user): create_admin_user() - user = mixer.blend('inventory.User', customer=mixer.SELECT) - group = mixer.blend('inventory.AdGroup') - mixer.blend('inventory.UserInAdGroup', user=user, group=group) + user = mixer.blend('users.User', customer=mixer.SELECT) + group = mixer.blend('users.AdGroup') + mixer.blend('users.UserInAdGroup', user=user, group=group) client = Client() client.login(username="novartis-admin", password="password") response = client.get('/user/' + str(user.id) + '/') @@ -45,9 +45,9 @@ def test_user_detail_view_ad_group(create_admin_user): def test_user_detail_view_mail_group(create_admin_user): create_admin_user() - user = mixer.blend('inventory.User', customer=mixer.SELECT) - group = mixer.blend('inventory.MailGroup') - mixer.blend('inventory.UserInMailGroup', user=user, group=group) + user = mixer.blend('users.User', customer=mixer.SELECT) + group = mixer.blend('users.MailGroup') + mixer.blend('users.UserInMailGroup', user=user, group=group) client = Client() client.login(username="novartis-admin", password="password") response = client.get('/user/' + str(user.id) + '/') @@ -57,8 +57,8 @@ def test_user_detail_view_mail_group(create_admin_user): def test_user_detail_view_mail_alias(create_admin_user): create_admin_user() - user = mixer.blend('inventory.User', customer=mixer.SELECT) - mixer.blend('inventory.MailAlias', user=user) + user = mixer.blend('users.User', customer=mixer.SELECT) + mixer.blend('users.MailAlias', user=user) client = Client() client.login(username="novartis-admin", password="password") response = client.get('/user/' + str(user.id) + '/') @@ -68,7 +68,7 @@ def test_user_detail_view_mail_alias(create_admin_user): def test_user_detail_view_license(create_admin_user): create_admin_user() - user = mixer.blend('inventory.User', customer=mixer.SELECT) + user = mixer.blend('users.User', customer=mixer.SELECT) mixer.blend('inventory.UserLicense', software=mixer.SELECT) mixer.blend('inventory.LicenseWithUser', user=user) client = Client() @@ -80,7 +80,7 @@ def test_user_detail_view_license(create_admin_user): def test_user_detail_view_computer(create_admin_user): create_admin_user() - user = mixer.blend('inventory.User', customer=mixer.SELECT) + user = mixer.blend('users.User', customer=mixer.SELECT) computer = mixer.blend('inventory.Computer', user=user) client = Client() client.login(username="novartis-admin", password="password") @@ -91,8 +91,8 @@ def test_user_detail_view_computer(create_admin_user): def test_user_detail_view_no_permission(create_admin_user): create_admin_user() - customer = mixer.blend('customer.Customer') - user = mixer.blend('inventory.User', customer=customer) + customer = mixer.blend('customers.Customer') + user = mixer.blend('users.User', customer=customer) client = Client() client.login(username="novartis-admin", password="password") response = client.get('/user/' + str(user.id) + '/') diff --git a/users/urls.py b/users/urls.py new file mode 100644 index 0000000..579cbc0 --- /dev/null +++ b/users/urls.py @@ -0,0 +1,9 @@ +from django.urls import path + +from . import views + +urlpatterns = [ + path('customer//users/', views.users_table_view, + name='users'), + path('user//', views.user_detail_view, name='user'), + ] diff --git a/users/views.py b/users/views.py index 91ea44a..da25b21 100644 --- a/users/views.py +++ b/users/views.py @@ -1,3 +1,41 @@ +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 inventory.models import Computer, LicenseWithUser + +from .decorators import user_view_permission +from .models import MailAlias +from .models import User +from .models import UserInAdGroup +from .models import UserInMailGroup +from .tables import UsersTable + + +@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})