Skip to content

Commit 24f04e4

Browse files
committed
wip
Signed-off-by: Keshav Priyadarshi <git@keshav.space>
1 parent 74172c4 commit 24f04e4

File tree

8 files changed

+510
-3
lines changed

8 files changed

+510
-3
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ sqlite:
121121
@$(MAKE) migrate
122122

123123
run:
124-
${MANAGE} runserver 8001 --insecure
124+
DJANGO_RUNSERVER_HIDE_WARNING=true ${MANAGE} runserver 8001 --insecure
125125

126126
test:
127127
@echo "-> Run the test suite"

vulnerabilities/models.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2515,7 +2515,7 @@ class AdvisoryToDoV2(models.Model):
25152515
help_text="Advisory/ies where this TODO is applicable.",
25162516
)
25172517

2518-
issue_type = models.CharField(
2518+
issue_type = models.CharField(
25192519
max_length=50,
25202520
choices=ISSUE_TYPE_CHOICES,
25212521
db_index=True,
@@ -2552,6 +2552,8 @@ class AdvisoryToDoV2(models.Model):
25522552
class Meta:
25532553
unique_together = ("related_advisories_id", "issue_type")
25542554

2555+
#todo add index!
2556+
25552557

25562558
class AdvisorySeverity(models.Model):
25572559
url = models.URLField(
@@ -2981,6 +2983,8 @@ class AdvisoryV2(models.Model):
29812983
choices=AdvisoryStatusType.choices, default=AdvisoryStatusType.PUBLISHED
29822984
)
29832985

2986+
# Note: Fields and relations below are not part of original upstream advisory.
2987+
29842988
exploitability = models.DecimalField(
29852989
null=True,
29862990
blank=True,
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
{% extends "base.html" %}
2+
{% load utils %}
3+
4+
{% block title %}
5+
Curation Dashboard
6+
{% endblock %}
7+
8+
{% block extrahead %}
9+
10+
<style>
11+
pre {
12+
/* background-color: #282a36; */
13+
/* color: #f8f8f2; */
14+
padding: 1rem;
15+
border-radius: 4px;
16+
overflow-x: auto;
17+
height: 750px;
18+
position: relative;
19+
}
20+
21+
.column {
22+
word-break: break-word;
23+
}
24+
25+
.copy-btn {
26+
position: absolute;
27+
top: 1.0rem;
28+
right: 1.5rem;
29+
z-index: 1;
30+
opacity: 0.5;
31+
transition: opacity 0.2s ease;
32+
}
33+
</style>
34+
35+
{% endblock %}
36+
37+
{% block content %}
38+
39+
<div class="columns">
40+
41+
<!-- LEFT: Advisory Viewer -->
42+
<div class="column is-5">
43+
<div class="box is-flex-direction-column">
44+
45+
{% for adv in advisories %}
46+
<div class="advisory-item" data-index="{{ forloop.counter0 }}" style="display: none;">
47+
<div class="box">
48+
<div class="level mb-2">
49+
50+
<div class="level-left">
51+
<h2 class="subtitle">Run Error</h2>
52+
</div>
53+
54+
<div class="level-right">
55+
<div class="has-text-right">
56+
<div class="buttons is-flex is-flex-direction-column">
57+
<p class="mr-4">
58+
<strong id="counterText">{{ forloop.counter }} / {{ advisories|length }}</strong>
59+
</p>
60+
61+
<button id="prevBtn" class="button is-small mb-1" onclick="prevAdvisory()">
62+
<span class="icon">
63+
<i class="fa fa-arrow-up"></i>
64+
</span>
65+
</button>
66+
67+
<button id="nextBtn" class="button is-small" onclick="nextAdvisory()">
68+
<span class="icon">
69+
<i class="fa fa-arrow-down"></i>
70+
</span>
71+
</button>
72+
73+
</div>
74+
75+
</div>
76+
</div>
77+
78+
</div>
79+
<div class="log-wrapper" style="position: relative;">
80+
<button class="button is-medium is-light copy-btn" id="copy-btn-{{ forloop.counter0 }}"
81+
onclick="copyCode('adv-{{ forloop.counter0 }}', 'copy-btn-{{ forloop.counter0 }}')">
82+
<span class="icon is-medium">
83+
<i class="fa fa-copy"></i>
84+
</span>
85+
</button>
86+
<pre><code id='adv-{{ forloop.counter0 }}' class="language-python">{{ adv }}</code></pre>
87+
</div>
88+
</div>
89+
90+
</div>
91+
{% endfor %}
92+
93+
94+
95+
</div>
96+
</div>
97+
98+
99+
<!-- RIGHT: Editor -->
100+
<div class="column is-7">
101+
<div class="box">
102+
103+
<h2 class="title is-6">Editor</h2>
104+
105+
<form method="post">
106+
{% csrf_token %}
107+
108+
<div class="field">
109+
<label class="label">Datasource ID</label>
110+
<div class="control">
111+
<input class="input" type="text" name="datasource_id">
112+
</div>
113+
</div>
114+
115+
<div class="field">
116+
<label class="label">AVID</label>
117+
<div class="control">
118+
<input class="input" type="text" name="avid">
119+
</div>
120+
</div>
121+
122+
<div class="field">
123+
<label class="label">URL</label>
124+
<div class="control">
125+
<input class="input" type="text" name="url">
126+
</div>
127+
</div>
128+
129+
<div class="field">
130+
<label class="label">Summary</label>
131+
<div class="control">
132+
<textarea class="textarea" name="summary"></textarea>
133+
</div>
134+
</div>
135+
136+
<hr>
137+
138+
<div class="buttons">
139+
<button class="button is-primary" type="submit">Save</button>
140+
<button class="button is-success" type="button">Finish</button>
141+
</div>
142+
143+
</form>
144+
145+
</div>
146+
</div>
147+
148+
</div>
149+
150+
{% endblock %}
151+
152+
153+
{% block scripts %}
154+
<script>
155+
let currentIndex = 0;
156+
const items = document.querySelectorAll(".advisory-item");
157+
158+
function show(index) {
159+
if (index < 0 || index >= items.length) return;
160+
161+
items.forEach(el => el.style.display = "none");
162+
items[index].style.display = "block";
163+
164+
currentIndex = index;
165+
166+
// update counter + buttons inside current item
167+
const current = items[index];
168+
169+
const counter = current.querySelector("#counterText");
170+
if (counter) {
171+
counter.textContent = (index + 1) + " / " + items.length;
172+
}
173+
174+
const prevBtn = current.querySelector("#prevBtn");
175+
const nextBtn = current.querySelector("#nextBtn");
176+
177+
if (prevBtn) prevBtn.disabled = index === 0;
178+
if (nextBtn) nextBtn.disabled = index === items.length - 1;
179+
}
180+
181+
function nextAdvisory() {
182+
show(currentIndex + 1);
183+
}
184+
185+
function prevAdvisory() {
186+
show(currentIndex - 1);
187+
}
188+
189+
document.addEventListener("DOMContentLoaded", () => {
190+
show(0);
191+
});
192+
193+
194+
function copyCode(target, button) {
195+
code = document.getElementById(target).textContent;
196+
navigator.clipboard.writeText(code)
197+
.then(() => {
198+
const btn = document.getElementById(button);
199+
btn.classList.add("is-success");
200+
btn.innerHTML = '<span class="icon is-small"><i class="fa fa-check"></i></span>';
201+
setTimeout(() => {
202+
btn.classList.remove("is-success");
203+
btn.innerHTML = '<span class="icon is-small"><i class="fa fa-copy"></i></span>';
204+
}, 1500);
205+
})
206+
.catch(err => alert(err));
207+
208+
}
209+
</script>
210+
{% endblock %}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
{% extends "base.html" %}
2+
{% load utils %}
3+
4+
{% block title %}
5+
Advisory To-Dos
6+
{% endblock %}
7+
8+
{% block extrahead %}
9+
<style>
10+
thead th {
11+
border-bottom: none !important;
12+
}
13+
14+
tbody tr:hover {
15+
background-color: #e0e0e0 !important;
16+
cursor: pointer;
17+
}
18+
19+
tbody tr:nth-child(even):hover {
20+
background-color: #d3d3d3 !important;
21+
}
22+
23+
.column {
24+
word-break: break-word;
25+
}
26+
</style>
27+
{% endblock %}
28+
29+
30+
{% block content %}
31+
<div class="columns">
32+
<div class="column">
33+
</div>
34+
35+
<div class="column is-four-fifths">
36+
<div class="content is-normal">
37+
<h1>Advisory To-Dos</h1>
38+
<hr />
39+
</div>
40+
<form method="get" class="box px-6 mx-0" action="">
41+
<div class="field has-addons">
42+
<div class="control is-expanded">
43+
{{ form.search }}
44+
</div>
45+
<div class="control">
46+
<button type="submit" class="button is-info"><i class="fa fa-search mx-1"></i></button>
47+
</div>
48+
</div>
49+
</form>
50+
51+
<div class="box">
52+
<!-- <div class="column has-text-right">
53+
<p class="has-text-weight-semibold">
54+
{{ active_pipeline_count|default:0 }} active pipeline{{ active_pipeline_count|default:0|pluralize }},
55+
{{ disabled_pipeline_count|default:0 }} disabled pipeline{{ disabled_pipeline_count|default:0|pluralize }}
56+
</p>
57+
</div> -->
58+
<table class="table is-striped is-hoverable is-fullwidth">
59+
<thead>
60+
<tr>
61+
<th colspan="6">
62+
<div class="box is-small">
63+
<div class="columns is-mobile is-vcentered">
64+
<div class="column is-one-quarter">Pipeline ID</div>
65+
<div class="column is-one-eighth">Active</div>
66+
<div class="column is-one-eighth">Interval</div>
67+
<div class="column is-one-eighth">Status</div>
68+
<div class="column is-one-fifth">Last Run End Time</div>
69+
<div class="column is-one-fifth">Next Run Start</div>
70+
</div>
71+
</div>
72+
</th>
73+
</tr>
74+
</thead>
75+
<tbody>
76+
{% for schedule in schedule_list %}
77+
<tr>
78+
<td colspan="6">
79+
<a href="{% url 'todo-detail' pk=schedule.id %}" class="has-text-info">
80+
<div class="columns px-1 is-mobile is-vcentered">
81+
82+
<div class="column is-one-quarter">
83+
{{ schedule.issue_type }}
84+
</div>
85+
<div class="column is-one-eighth has-text-grey">{{ schedule.issue_type|yesno:"Yes,No" }}</div>
86+
<div class="column is-one-eighth has-text-grey">
87+
{{ schedule.issue_type }}
88+
<!-- {% if schedule.is_run_once %}
89+
Once
90+
{% else %}
91+
{{ schedule.run_interval }} hour{{ schedule.run_interval|pluralize }}
92+
{% endif %} -->
93+
</div>
94+
<div class="column is-one-eighth">
95+
<span class="is-flex is-align-items-center">
96+
<!-- {% include "includes/job_status.html" with status=schedule.status %} -->
97+
</span>
98+
</div>
99+
<div class="column is-one-fifth has-text-grey">
100+
{{ schedule.issue_type }}
101+
<!-- {% if schedule.latest_run_end_date %}
102+
{{ schedule.latest_run_end_date|date:"Y-m-d h:i a T" }}
103+
{% else %}
104+
N/A
105+
{% endif %} -->
106+
</div>
107+
<div class="column is-one-fifth has-text-grey">
108+
{{ schedule.issue_type }}
109+
<!-- {% if schedule.next_run_date %}
110+
{{ schedule.next_run_date|date:"Y-m-d" }}
111+
{% else %}
112+
N/A
113+
{% endif %} -->
114+
</div>
115+
</div>
116+
</a>
117+
</td>
118+
</tr>
119+
{% empty %}
120+
<tr>
121+
<td colspan="6" class="has-text-centered">No pipeline found.</td>
122+
</tr>
123+
{% endfor %}
124+
</tbody>
125+
126+
</table>
127+
</div>
128+
{% if is_paginated %}
129+
<nav class="pagination is-centered px-5" role="navigation" aria-label="pagination">
130+
{% if page_obj.has_previous %}
131+
<a class="pagination-previous" href="?{% querystring request page=page_obj.previous_page_number %}">Previous</a>
132+
{% endif %}
133+
134+
{% if page_obj.has_next %}
135+
<a class="pagination-next" href="?{% querystring request page=page_obj.next_page_number %}">Next page</a>
136+
{% endif %}
137+
<ul class="pagination-list">
138+
<li><a class="pagination-link" aria-label="Goto page 1" href="?{% querystring request page=1 %}">1</a></li>
139+
<li><span class="pagination-ellipsis">&hellip;</span></li>
140+
<li><a class="pagination-link" aria-label="Goto page {{ page_obj.number }}"
141+
href="?{% querystring request page=page_obj.paginator.num_pages %}">{{ page_obj.paginator.num_pages }}</a></li>
142+
</ul>
143+
</nav>
144+
{% endif %}
145+
</div>
146+
<div class="column"></div>
147+
</div>
148+
{% endblock %}

0 commit comments

Comments
 (0)