Compare commits
No commits in common. "ai-dev" and "master" have entirely different histories.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,13 +1,8 @@
|
||||
from django.contrib import admin
|
||||
from .models import Application, Vulnerability
|
||||
from .models import Ticket
|
||||
|
||||
@admin.register(Application)
|
||||
class ApplicationAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'version', 'vendor')
|
||||
search_fields = ('name', 'vendor')
|
||||
|
||||
@admin.register(Vulnerability)
|
||||
class VulnerabilityAdmin(admin.ModelAdmin):
|
||||
list_display = ('cve_id', 'application', 'severity', 'status', 'discovered_at')
|
||||
list_filter = ('severity', 'status', 'application__name')
|
||||
search_fields = ('cve_id', 'description')
|
||||
@admin.register(Ticket)
|
||||
class TicketAdmin(admin.ModelAdmin):
|
||||
list_display = ('subject', 'status', 'priority', 'requester_email', 'created_at')
|
||||
list_filter = ('status', 'priority')
|
||||
search_fields = ('subject', 'requester_email', 'description')
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
from django import forms
|
||||
from .models import Ticket
|
||||
|
||||
class UploadFileForm(forms.Form):
|
||||
file = forms.FileField()
|
||||
|
||||
class VulnerabilitySearchForm(forms.Form):
|
||||
application_name = forms.CharField(max_length=100, label="Application Name")
|
||||
application_website = forms.URLField(label="Application Website", required=False)
|
||||
class TicketForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Ticket
|
||||
fields = ['subject', 'requester_email', 'priority', 'description']
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
# Generated by Django 5.2.7 on 2025-10-27 12:23
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Application',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255)),
|
||||
('version', models.CharField(max_length=100)),
|
||||
('vendor', models.CharField(max_length=255)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Vulnerability',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('cve_id', models.CharField(max_length=50, unique=True)),
|
||||
('description', models.TextField()),
|
||||
('severity', models.CharField(choices=[('Critical', 'Critical'), ('High', 'High'), ('Medium', 'Medium'), ('Low', 'Low')], max_length=10)),
|
||||
('status', models.CharField(choices=[('New', 'New'), ('Acknowledged', 'Acknowledged'), ('In-Progress', 'In-Progress'), ('Resolved', 'Resolved')], default='New', max_length=20)),
|
||||
('discovered_at', models.DateTimeField(auto_now_add=True)),
|
||||
('last_updated', models.DateTimeField(auto_now=True)),
|
||||
('application', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='vulnerabilities', to='core.application')),
|
||||
],
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Ticket',
|
||||
),
|
||||
]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,34 +1,25 @@
|
||||
from django.db import models
|
||||
|
||||
class Application(models.Model):
|
||||
name = models.CharField(max_length=255)
|
||||
version = models.CharField(max_length=100)
|
||||
vendor = models.CharField(max_length=255)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name} {self.version}"
|
||||
|
||||
class Vulnerability(models.Model):
|
||||
SEVERITY_CHOICES = [
|
||||
('Critical', 'Critical'),
|
||||
('High', 'High'),
|
||||
('Medium', 'Medium'),
|
||||
('Low', 'Low'),
|
||||
]
|
||||
class Ticket(models.Model):
|
||||
STATUS_CHOICES = [
|
||||
('New', 'New'),
|
||||
('Acknowledged', 'Acknowledged'),
|
||||
('In-Progress', 'In-Progress'),
|
||||
('Resolved', 'Resolved'),
|
||||
('open', 'Open'),
|
||||
('in_progress', 'In Progress'),
|
||||
('closed', 'Closed'),
|
||||
]
|
||||
|
||||
cve_id = models.CharField(max_length=50, unique=True)
|
||||
PRIORITY_CHOICES = [
|
||||
('low', 'Low'),
|
||||
('medium', 'Medium'),
|
||||
('high', 'High'),
|
||||
]
|
||||
|
||||
subject = models.CharField(max_length=255)
|
||||
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='open')
|
||||
priority = models.CharField(max_length=20, choices=PRIORITY_CHOICES, default='medium')
|
||||
requester_email = models.EmailField()
|
||||
description = models.TextField()
|
||||
severity = models.CharField(max_length=10, choices=SEVERITY_CHOICES)
|
||||
application = models.ForeignKey(Application, on_delete=models.CASCADE, related_name='vulnerabilities')
|
||||
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='New')
|
||||
discovered_at = models.DateTimeField(auto_now_add=True)
|
||||
last_updated = models.DateTimeField(auto_now=True)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.cve_id
|
||||
return self.subject
|
||||
@ -1,69 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}{{ project_name|default:"Vulnerability Scanner" }}{% endblock %}</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||
{% load static %}
|
||||
<link rel="stylesheet" href="{% static 'css/custom.css' %}">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="d-flex" id="wrapper">
|
||||
<!-- Sidebar -->
|
||||
<div class="bg-light border-right" id="sidebar-wrapper">
|
||||
<div class="sidebar-heading">
|
||||
<a class="text-decoration-none text-dark" href="/">
|
||||
<i class="bi bi-shield-shaded"></i> {{ project_name|default:"Vulnerability Scanner" }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="list-group list-group-flush">
|
||||
<a href="/" class="list-group-item list-group-item-action bg-light"><i class="bi bi-speedometer2 me-2"></i>Dashboard</a>
|
||||
<a href="#" class="list-group-item list-group-item-action bg-light"><i class="bi bi-file-earmark-arrow-up me-2"></i>Upload Inventory</a>
|
||||
<a href="#" class="list-group-item list-group-item-action bg-light"><i class="bi bi-bug me-2"></i>Vulnerabilities</a>
|
||||
<a href="#" class="list-group-item list-group-item-action bg-light"><i class="bi bi-gear me-2"></i>Settings</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /#sidebar-wrapper -->
|
||||
|
||||
<!-- Page Content -->
|
||||
<div id="page-content-wrapper">
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light border-bottom">
|
||||
<div class="container-fluid">
|
||||
<button class="btn btn-primary" id="menu-toggle"><i class="bi bi-list"></i></button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav ms-auto mt-2 mt-lg-0">
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="bi bi-person-circle"></i> Admin
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
|
||||
<li><a class="dropdown-item" href="#">Profile</a></li>
|
||||
<li><a class="dropdown-item" href="#">Logout</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="container-fluid p-4">
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
</div>
|
||||
<!-- /#page-content-wrapper -->
|
||||
</div>
|
||||
<!-- /#wrapper -->
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
document.getElementById("menu-toggle").addEventListener("click", function(e) {
|
||||
e.preventDefault();
|
||||
document.getElementById("wrapper").classList.toggle("toggled");
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,14 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}{{ article.title }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mt-5">
|
||||
<h1>{{ article.title }}</h1>
|
||||
<p class="text-muted">Published on {{ article.created_at|date:"F d, Y" }}</p>
|
||||
<hr>
|
||||
<div>
|
||||
{{ article.content|safe }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -1,122 +1,157 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
{% block title %}Dashboard - {{ project_name }}{% endblock %}
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{ project_name }}</title>
|
||||
{% if project_description %}
|
||||
<meta name="description" content="{{ project_description }}">
|
||||
<meta property="og:description" content="{{ project_description }}">
|
||||
<meta property="twitter:description" content="{{ project_description }}">
|
||||
{% endif %}
|
||||
{% if project_image_url %}
|
||||
<meta property="og:image" content="{{ project_image_url }}">
|
||||
<meta property="twitter:image" content="{{ project_image_url }}">
|
||||
{% endif %}
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--bg-color-start: #6a11cb;
|
||||
--bg-color-end: #2575fc;
|
||||
--text-color: #ffffff;
|
||||
--card-bg-color: rgba(255, 255, 255, 0.08);
|
||||
--card-border-color: rgba(255, 255, 255, 0.18);
|
||||
}
|
||||
|
||||
{% block content %}
|
||||
<div class="container-fluid">
|
||||
<h1 class="mt-4">Dashboard</h1>
|
||||
<p>Overview of application vulnerabilities.</p>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3 col-md-6 mb-4">
|
||||
<div class="card text-white bg-primary">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<div class="fs-4 fw-bold">{{ total_applications }}</div>
|
||||
<div>Total Applications</div>
|
||||
</div>
|
||||
<i class="bi bi-box-fill fs-1"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-md-6 mb-4">
|
||||
<div class="card text-white bg-warning">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<div class="fs-4 fw-bold">{{ total_vulnerabilities }}</div>
|
||||
<div>Total Vulnerabilities</div>
|
||||
</div>
|
||||
<i class="bi bi-bug-fill fs-1"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-md-6 mb-4">
|
||||
<div class="card text-white bg-danger">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<div class="fs-4 fw-bold">{{ critical_vulnerabilities }}</div>
|
||||
<div>Critical Vulnerabilities</div>
|
||||
</div>
|
||||
<i class="bi bi-exclamation-octagon-fill fs-1"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-md-6 mb-4">
|
||||
<div class="card text-white bg-info">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<div class="fs-4 fw-bold">{{ new_vulnerabilities }}</div>
|
||||
<div>New Vulnerabilities</div>
|
||||
</div>
|
||||
<i class="bi bi-patch-plus-fill fs-1"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: linear-gradient(130deg, var(--bg-color-start), var(--bg-color-end));
|
||||
color: var(--text-color);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<i class="bi bi-search me-2"></i>
|
||||
Vulnerability Search
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form action="{% url 'vulnerability_search' %}" method="get">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="application_name" placeholder="Enter application name...">
|
||||
<button class="btn btn-primary" type="submit">Search</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
body::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140' viewBox='0 0 140 140'><path d='M-20 20L160 20M20 -20L20 160' stroke-width='1' stroke='rgba(255,255,255,0.05)'/></svg>");
|
||||
animation: bg-pan 24s linear infinite;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<i class="bi bi-box-seam me-2"></i>
|
||||
Application Inventory
|
||||
</div>
|
||||
<a href="{% url 'upload_inventory' %}" class="btn btn-primary">Upload Inventory</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Version</th>
|
||||
<th>Vendor</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for app in applications %}
|
||||
<tr>
|
||||
<td>{{ app.name }}</td>
|
||||
<td>{{ app.version }}</td>
|
||||
<td>{{ app.vendor }}</td>
|
||||
<td>
|
||||
<button class="btn btn-sm btn-primary">Details</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="4" class="text-center">No applications found.</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@keyframes bg-pan {
|
||||
0% {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
100% {
|
||||
transform: translate3d(-140px, -140px, 0);
|
||||
}
|
||||
}
|
||||
|
||||
main {
|
||||
padding: clamp(2rem, 4vw, 3rem);
|
||||
width: min(640px, 92vw);
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--card-bg-color);
|
||||
border: 1px solid var(--card-border-color);
|
||||
border-radius: 20px;
|
||||
padding: clamp(2rem, 4vw, 3rem);
|
||||
backdrop-filter: blur(24px);
|
||||
-webkit-backdrop-filter: blur(24px);
|
||||
box-shadow: 0 20px 60px rgba(15, 23, 42, 0.35);
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0 0 1.2rem;
|
||||
font-weight: 700;
|
||||
font-size: clamp(2.2rem, 3vw + 1.3rem, 3rem);
|
||||
letter-spacing: -0.04em;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0.6rem 0;
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.7;
|
||||
opacity: 0.92;
|
||||
}
|
||||
|
||||
.loader {
|
||||
margin: 1.5rem auto;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border: 4px solid rgba(255, 255, 255, 0.25);
|
||||
border-top-color: #fff;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
}
|
||||
|
||||
code {
|
||||
background: rgba(15, 23, 42, 0.35);
|
||||
padding: 0.2rem 0.6rem;
|
||||
border-radius: 0.5rem;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 2.4rem;
|
||||
font-size: 0.86rem;
|
||||
opacity: 0.7;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main>
|
||||
<div class="card">
|
||||
<h1>Analyzing your requirements and generating your website…</h1>
|
||||
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
|
||||
<span class="sr-only">Loading…</span>
|
||||
</div>
|
||||
<p>Appwizzy AI is collecting your requirements and applying the first changes.</p>
|
||||
<p>This page will refresh automatically as the plan is implemented.</p>
|
||||
<p>
|
||||
Runtime: Django <code>{{ django_version }}</code> · Python <code>{{ python_version }}</code> —
|
||||
UTC <code>{{ current_time|date:"Y-m-d H:i:s" }}</code>
|
||||
</p>
|
||||
</div>
|
||||
<footer>
|
||||
Page updated: {{ current_time|date:"Y-m-d H:i:s" }} (UTC)
|
||||
</footer>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -1,13 +0,0 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mt-4">
|
||||
<h2>Upload Application Inventory</h2>
|
||||
<p>Upload a CSV file with the following columns: Name, Version, Vendor.</p>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit" class="btn btn-primary">Upload</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -1,25 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mt-4">
|
||||
<h2>Vulnerability Search</h2>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit" class="btn btn-primary">Search</button>
|
||||
</form>
|
||||
|
||||
{% if results %}
|
||||
<hr>
|
||||
<h3>Search Results</h3>
|
||||
<div class="list-group">
|
||||
{% for result in results %}
|
||||
<div class="list-group-item">
|
||||
<h5 class="mb-1">{{ result.cve_id }}</h5>
|
||||
<p class="mb-1">{{ result.description }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -1,9 +1,7 @@
|
||||
from django.urls import path
|
||||
|
||||
from .views import dashboard, upload_inventory, vulnerability_search
|
||||
from .views import home
|
||||
|
||||
urlpatterns = [
|
||||
path("", dashboard, name="dashboard"),
|
||||
path("upload/", upload_inventory, name="upload_inventory"),
|
||||
path("search/", vulnerability_search, name="vulnerability_search"),
|
||||
]
|
||||
path("", home, name="home"),
|
||||
]
|
||||
|
||||
@ -1,72 +1,37 @@
|
||||
from django.shortcuts import render, redirect
|
||||
from .models import Application, Vulnerability
|
||||
from .forms import UploadFileForm, VulnerabilitySearchForm
|
||||
import csv
|
||||
import io
|
||||
import requests
|
||||
import os
|
||||
import platform
|
||||
|
||||
def dashboard(request):
|
||||
# Placeholder data
|
||||
total_apps = Application.objects.count()
|
||||
total_vulns = Vulnerability.objects.count()
|
||||
critical_vulns = Vulnerability.objects.filter(severity='Critical').count()
|
||||
new_vulns = Vulnerability.objects.filter(status='New').count()
|
||||
applications = Application.objects.all()
|
||||
from django import get_version as django_version
|
||||
from django.shortcuts import render
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils import timezone
|
||||
from django.views.generic.edit import CreateView
|
||||
|
||||
from .forms import TicketForm
|
||||
from .models import Ticket
|
||||
|
||||
|
||||
def home(request):
|
||||
"""Render the landing screen with loader and environment details."""
|
||||
host_name = request.get_host().lower()
|
||||
agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic"
|
||||
now = timezone.now()
|
||||
|
||||
context = {
|
||||
'total_applications': total_apps,
|
||||
'total_vulnerabilities': total_vulns,
|
||||
'critical_vulnerabilities': critical_vulns,
|
||||
'new_vulnerabilities': new_vulns,
|
||||
'applications': applications,
|
||||
"project_name": "Vulnerability Scanner",
|
||||
"project_name": "New Style",
|
||||
"agent_brand": agent_brand,
|
||||
"django_version": django_version(),
|
||||
"python_version": platform.python_version(),
|
||||
"current_time": now,
|
||||
"host_name": host_name,
|
||||
"project_description": os.getenv("PROJECT_DESCRIPTION", ""),
|
||||
"project_image_url": os.getenv("PROJECT_IMAGE_URL", ""),
|
||||
}
|
||||
return render(request, "core/index.html", context)
|
||||
|
||||
def upload_inventory(request):
|
||||
if request.method == 'POST':
|
||||
form = UploadFileForm(request.POST, request.FILES)
|
||||
if form.is_valid():
|
||||
try:
|
||||
csv_file = request.FILES['file']
|
||||
decoded_file = io.TextIOWrapper(csv_file.file, encoding='utf-8', newline='', errors='ignore')
|
||||
reader = csv.reader(decoded_file)
|
||||
# Skip header row
|
||||
next(reader)
|
||||
for row in reader:
|
||||
if row and len(row) == 3:
|
||||
print(f"Processing row: {row}")
|
||||
Application.objects.create(
|
||||
name=row[0],
|
||||
version=row[1],
|
||||
vendor=row[2],
|
||||
)
|
||||
return redirect('dashboard')
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
form.add_error(None, f"An error occurred: {e}")
|
||||
else:
|
||||
form = UploadFileForm()
|
||||
return render(request, 'core/upload_inventory.html', {'form': form})
|
||||
|
||||
def vulnerability_search(request):
|
||||
form = VulnerabilitySearchForm()
|
||||
results = []
|
||||
if request.method == 'POST':
|
||||
form = VulnerabilitySearchForm(request.POST)
|
||||
if form.is_valid():
|
||||
application_name = form.cleaned_data['application_name']
|
||||
# Basic search using NVD API
|
||||
url = f"https://services.nvd.nist.gov/rest/json/cves/1.0?keyword={application_name}"
|
||||
try:
|
||||
response = requests.get(url)
|
||||
data = response.json()
|
||||
if 'result' in data:
|
||||
for cve_item in data['result']['CVE_Items']:
|
||||
cve_id = cve_item['cve']['CVE_data_meta']['ID']
|
||||
description = cve_item['cve']['description']['description_data'][0]['value']
|
||||
results.append({'cve_id': cve_id, 'description': description})
|
||||
except requests.exceptions.RequestException as e:
|
||||
form.add_error(None, f"Error fetching data from NVD: {e}")
|
||||
|
||||
return render(request, 'core/vulnerability_search.html', {'form': form, 'results': results})
|
||||
class TicketCreateView(CreateView):
|
||||
model = Ticket
|
||||
form_class = TicketForm
|
||||
template_name = "core/ticket_create.html"
|
||||
success_url = reverse_lazy("home")
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
Django==5.2.7
|
||||
mysqlclient==2.2.7
|
||||
python-dotenv==1.1.1
|
||||
requests
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
#sidebar-wrapper {
|
||||
min-height: 100vh;
|
||||
margin-left: -15rem;
|
||||
transition: margin .25s ease-out;
|
||||
}
|
||||
|
||||
#sidebar-wrapper .sidebar-heading {
|
||||
padding: 0.875rem 1.25rem;
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#sidebar-wrapper .list-group {
|
||||
width: 15rem;
|
||||
}
|
||||
|
||||
#page-content-wrapper {
|
||||
min-width: 100vw;
|
||||
}
|
||||
|
||||
#wrapper.toggled #sidebar-wrapper {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
#sidebar-wrapper {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
#page-content-wrapper {
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#wrapper.toggled #sidebar-wrapper {
|
||||
margin-left: -15rem;
|
||||
}
|
||||
}
|
||||
|
||||
.card-body .fs-1 {
|
||||
opacity: 0.7;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user