django-restit 4.1.61__py3-none-any.whl → 4.1.62__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- account/rpc/group.py +1 -0
- {django_restit-4.1.61.dist-info → django_restit-4.1.62.dist-info}/METADATA +1 -1
- {django_restit-4.1.61.dist-info → django_restit-4.1.62.dist-info}/RECORD +13 -10
- incident/migrations/0010_incident_category_incident_component_id.py +23 -0
- incident/migrations/0011_ticket.py +38 -0
- incident/models/__init__.py +1 -0
- incident/models/event.py +4 -1
- incident/models/incident.py +26 -13
- incident/models/ticket.py +65 -0
- incident/rpc.py +6 -0
- rest/__init__.py +1 -1
- {django_restit-4.1.61.dist-info → django_restit-4.1.62.dist-info}/LICENSE.md +0 -0
- {django_restit-4.1.61.dist-info → django_restit-4.1.62.dist-info}/WHEEL +0 -0
account/rpc/group.py
CHANGED
@@ -33,7 +33,7 @@ account/periodic.py,sha256=imh9C-oQVhfw7GX3RRHYuC6DIreGbXrQM35A8C4UjOE,876
|
|
33
33
|
account/rpc/__init__.py,sha256=L_AqHC0WbgUgLoqvNz6pY0E34eqh7sRaX77I6TxhRZ4,152
|
34
34
|
account/rpc/auth.py,sha256=8CgXsbNZLeBcd5MHpdL29z9E8PYUcKX_zYpTPX_Pa-0,12516
|
35
35
|
account/rpc/device.py,sha256=fbbZFp3cUdhVXvD7gVFOqFWj4hKS3bjZKD_aF5fQxd8,2852
|
36
|
-
account/rpc/group.py,sha256=
|
36
|
+
account/rpc/group.py,sha256=dUIZGArPgnKafL7F44f7Qum5EAskWcjj64Haqlkbdb8,3448
|
37
37
|
account/rpc/member.py,sha256=oKdXSGhQ7AOPTwisZ5RvHhQ1SdZoXWlBQY0lIlDXJY0,1150
|
38
38
|
account/rpc/notify.py,sha256=Q2YWejP36egeF060Hih5uX4Psv_B8NWlLLPi7iDYlIw,3344
|
39
39
|
account/rpc/oauth.py,sha256=-BW38HjYwSQhOs31ubnBxO0yCKVpczEMoHq54NC9uOU,2610
|
@@ -89,16 +89,19 @@ incident/migrations/0006_delete_eventmetadata.py,sha256=buSEY_TmmXi9ShPFxB74Os2q
|
|
89
89
|
incident/migrations/0007_event_metadata.py,sha256=syxcM4gIcBwSjcpdU69CXq5dGS1Gu8OodZtPJFDpY5U,414
|
90
90
|
incident/migrations/0008_incident_action_sent_incident_hostname_and_more.py,sha256=N2D47E9k4PxOo-9C72gqYkb6K0GqVIO4PkvdnWlrSuA,903
|
91
91
|
incident/migrations/0009_incident_reporter_ip.py,sha256=JOrTGBPJw9g7cg--HH3zqnbsMowjNSgzxJTrKojcPJA,473
|
92
|
+
incident/migrations/0010_incident_category_incident_component_id.py,sha256=FGRHnWJOPeKl5ko17L7rkERrLeyGCWET7sFmZbTB-YQ,631
|
93
|
+
incident/migrations/0011_ticket.py,sha256=Ml5E_Qi4Z0MD89fetoOFOL3rPlVQdjaaDCcFBfOuwd4,2142
|
92
94
|
incident/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
93
|
-
incident/models/__init__.py,sha256=
|
94
|
-
incident/models/event.py,sha256=
|
95
|
-
incident/models/incident.py,sha256=
|
95
|
+
incident/models/__init__.py,sha256=NMphuhb0RTMf7Ov4QkNv7iv6_I8Wtr3xQ54yjX_a31M,209
|
96
|
+
incident/models/event.py,sha256=5cbtIQwY2DTBR9PkQX9jKIWtzbFb69BLMOUdWieMrVw,6772
|
97
|
+
incident/models/incident.py,sha256=xOtlGyc6TxOoCEtHU1bdSYFBnjfDGhzT2C0YFklfwmY,13059
|
96
98
|
incident/models/ossec.py,sha256=pWMqcuTRxPFTEF-OZQSMn7YpNEE9mfsI4GMhWWjJs5I,2187
|
97
99
|
incident/models/rules.py,sha256=67fbtEDfznxCYb-B89417lgYesN12PzmY25WBF_65a8,5300
|
100
|
+
incident/models/ticket.py,sha256=S3kqGQpYLE6Y4M9IKu_60sgW-f592xNr8uufqHnvDoU,2302
|
98
101
|
incident/parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
99
102
|
incident/parsers/ossec.py,sha256=4_7Tpr_XBK8HerGSbdrOrAOAtbRvRE7WZ2Xedo3kp8g,5724
|
100
103
|
incident/periodic.py,sha256=3YatKLLzoM9Q-3QXaIPtVIytLRCZt-7-IaD4tvKKGjg,723
|
101
|
-
incident/rpc.py,sha256=
|
104
|
+
incident/rpc.py,sha256=YkGXzE0AbrqRXlK9jZjE2VypT8mhcbVc49Yndr_c4BQ,5209
|
102
105
|
incident/templates/email/incident_change.html,sha256=O_5ocWTsnqmmOuQhAtXEiE4rWecnZnJjoKU4MwV6ILo,14178
|
103
106
|
incident/templates/email/incident_new.html,sha256=IPX3CqIrvdrZSn13_jlR6sEb0If8ftvUrUpkzC5G2Gc,15173
|
104
107
|
incident/templates/email/incident_plain.html,sha256=iTjdej6K9SO9Or5byX-0kc7c_BdSZWVgA301T03IyDk,14343
|
@@ -347,7 +350,7 @@ pushit/utils.py,sha256=IeTCGa-164nmB1jIsK1lu1O1QzUhS3BKfuXHGjCW-ck,2121
|
|
347
350
|
rest/.gitignore,sha256=TbEvWRMnAiajCTOdhiNrd9eeCAaIjRp9PRjE_VkMM5g,118
|
348
351
|
rest/README.md,sha256=V3ETc-cJu8PZIbKr9xSe_pA4JEUpC8Dhw4bQeVCDJPw,5460
|
349
352
|
rest/RemoteEvents.py,sha256=nL46U7AuxIrlw2JunphR1tsXyqi-ep_gD9CYGpYbNgE,72
|
350
|
-
rest/__init__.py,sha256=
|
353
|
+
rest/__init__.py,sha256=lB3bhQFmMA43cbx4GDWsoIIKZiruByPaff8EG57nMVM,121
|
351
354
|
rest/arc4.py,sha256=y644IbF1ec--e4cUJ3KEYsewTCITK0gmlwa5mJruFC0,1967
|
352
355
|
rest/cache.py,sha256=1Qg0rkaCJCaVP0-l5hZg2CIblTdeBSlj_0fP6vlKUpU,83
|
353
356
|
rest/crypto/__init__.py,sha256=Tl0U11rgj1eBYqd6OXJ2_XSdNLumW_JkBZnaJqI6Ldw,72
|
@@ -478,7 +481,7 @@ ws4redis/servers/uwsgi.py,sha256=VyhoCI1DnVFqBiJYHoxqn5Idlf6uJPHvfBKgkjs34mo,172
|
|
478
481
|
ws4redis/settings.py,sha256=K0yBiLUuY81iDM4Yr-k8hbvjn5VVHu5zQhmMK8Dtz0s,1536
|
479
482
|
ws4redis/utf8validator.py,sha256=S0OlfjeGRP75aO6CzZsF4oTjRQAgR17OWE9rgZdMBZA,5122
|
480
483
|
ws4redis/websocket.py,sha256=R0TUyPsoVRD7Y_oU7w2I6NL4fPwiz5Vl94-fUkZgLHA,14848
|
481
|
-
django_restit-4.1.
|
482
|
-
django_restit-4.1.
|
483
|
-
django_restit-4.1.
|
484
|
-
django_restit-4.1.
|
484
|
+
django_restit-4.1.62.dist-info/LICENSE.md,sha256=VHN4hhEeVOoFjtG-5fVv4jesA4SWi0Z-KgOzzN6a1ps,1068
|
485
|
+
django_restit-4.1.62.dist-info/METADATA,sha256=mdO3BNZQMo_z4xhhJdcVrlAaRCMaZ65wMh0uFwAEOv4,7573
|
486
|
+
django_restit-4.1.62.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
|
487
|
+
django_restit-4.1.62.dist-info/RECORD,,
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Generated by Django 4.1.4 on 2023-11-20 03:38
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
|
5
|
+
|
6
|
+
class Migration(migrations.Migration):
|
7
|
+
|
8
|
+
dependencies = [
|
9
|
+
('incident', '0009_incident_reporter_ip'),
|
10
|
+
]
|
11
|
+
|
12
|
+
operations = [
|
13
|
+
migrations.AddField(
|
14
|
+
model_name='incident',
|
15
|
+
name='category',
|
16
|
+
field=models.CharField(db_index=True, default=None, max_length=124, null=True),
|
17
|
+
),
|
18
|
+
migrations.AddField(
|
19
|
+
model_name='incident',
|
20
|
+
name='component_id',
|
21
|
+
field=models.IntegerField(blank=True, db_index=True, default=None, null=True),
|
22
|
+
),
|
23
|
+
]
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Generated by Django 4.1.4 on 2023-11-20 03:51
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
import django.db.models.deletion
|
5
|
+
import rest.models.base
|
6
|
+
import rest.models.metadata
|
7
|
+
|
8
|
+
|
9
|
+
class Migration(migrations.Migration):
|
10
|
+
|
11
|
+
dependencies = [
|
12
|
+
('account', '0016_authsession_buid'),
|
13
|
+
('incident', '0010_incident_category_incident_component_id'),
|
14
|
+
]
|
15
|
+
|
16
|
+
operations = [
|
17
|
+
migrations.CreateModel(
|
18
|
+
name='Ticket',
|
19
|
+
fields=[
|
20
|
+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
21
|
+
('created', models.DateTimeField(auto_now_add=True)),
|
22
|
+
('modified', models.DateTimeField(auto_now=True)),
|
23
|
+
('category', models.CharField(db_index=True, max_length=200)),
|
24
|
+
('priority', models.IntegerField(db_index=True, default=10)),
|
25
|
+
('title', models.CharField(max_length=200)),
|
26
|
+
('description', models.TextField()),
|
27
|
+
('status', models.CharField(db_index=True, default=None, max_length=32, null=True)),
|
28
|
+
('state', models.IntegerField(default=0)),
|
29
|
+
('component', models.CharField(db_index=True, default=None, max_length=200, null=True)),
|
30
|
+
('component_id', models.IntegerField(blank=True, db_index=True, default=None, null=True)),
|
31
|
+
('assigned_to', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tickets', to='account.member')),
|
32
|
+
('created_by', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='account.member')),
|
33
|
+
('group', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tickets', to='account.group')),
|
34
|
+
('incident', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tickets', to='incident.incident')),
|
35
|
+
],
|
36
|
+
bases=(models.Model, rest.models.base.RestModel, rest.models.metadata.MetaDataModel),
|
37
|
+
),
|
38
|
+
]
|
incident/models/__init__.py
CHANGED
incident/models/event.py
CHANGED
@@ -161,7 +161,10 @@ class Event(JSONMetaData, rm.RestModel):
|
|
161
161
|
incident = Incident(
|
162
162
|
rule=hit_rule, priority=priority,
|
163
163
|
reporter_ip=self.reporter_ip,
|
164
|
-
|
164
|
+
category=self.category,
|
165
|
+
component=self.component,
|
166
|
+
component_id=self.component_id,
|
167
|
+
hostname=self.hostname)
|
165
168
|
if hit_rule is not None:
|
166
169
|
incident.group = hit_rule.group
|
167
170
|
# TODO possibly make this smarter?
|
incident/models/incident.py
CHANGED
@@ -52,7 +52,12 @@ class Incident(models.Model, rm.RestModel, rm.MetaDataModel):
|
|
52
52
|
modified = models.DateTimeField(auto_now=True)
|
53
53
|
|
54
54
|
description = models.CharField(max_length=200)
|
55
|
+
|
56
|
+
category = models.CharField(max_length=124, null=True, default=None, db_index=True)
|
57
|
+
|
55
58
|
component = models.CharField(max_length=200, null=True, default=None, db_index=True)
|
59
|
+
component_id = models.IntegerField(null=True, blank=True, default=None, db_index=True)
|
60
|
+
|
56
61
|
hostname = models.CharField(max_length=200, null=True, default=None, db_index=True)
|
57
62
|
reporter_ip = models.CharField(max_length=16, blank=True, null=True, default=None, db_index=True)
|
58
63
|
|
@@ -68,7 +73,15 @@ class Incident(models.Model, rm.RestModel, rm.MetaDataModel):
|
|
68
73
|
@property
|
69
74
|
def first_event(self):
|
70
75
|
return self.events.first()
|
71
|
-
|
76
|
+
|
77
|
+
def shouldTriggerAction(self):
|
78
|
+
count = self.events.all().count()
|
79
|
+
aa = self.rule.action_after
|
80
|
+
if aa>= 0:
|
81
|
+
return aa == count-1
|
82
|
+
aa = abs(self.rule.action_after)
|
83
|
+
return (count % aa) == 0
|
84
|
+
|
72
85
|
def triggerAction(self, force=False):
|
73
86
|
if self.rule is None:
|
74
87
|
if self.action_sent is None:
|
@@ -82,7 +95,7 @@ class Incident(models.Model, rm.RestModel, rm.MetaDataModel):
|
|
82
95
|
# return
|
83
96
|
# only do query if not 0
|
84
97
|
logger.info("triggerAction", self.rule.action)
|
85
|
-
if force or self.
|
98
|
+
if force or self.shouldTriggerAction():
|
86
99
|
logger.info(f"triggering incident action: {self.rule.action}")
|
87
100
|
self.triggerAsyncNotify()
|
88
101
|
if self.rule.action is None or self.rule.action == "notify":
|
@@ -99,7 +112,9 @@ class Incident(models.Model, rm.RestModel, rm.MetaDataModel):
|
|
99
112
|
pk=self.pk,
|
100
113
|
created=time.mktime(self.created.timetuple()),
|
101
114
|
description=self.description,
|
115
|
+
category=self.category,
|
102
116
|
component=self.component,
|
117
|
+
component_id=self.component_id,
|
103
118
|
hostname=self.hostname)
|
104
119
|
if self.rule is not None:
|
105
120
|
msg["rule"] = self.rule.name
|
@@ -188,7 +203,7 @@ class Incident(models.Model, rm.RestModel, rm.MetaDataModel):
|
|
188
203
|
for k, v in self._changed__.items():
|
189
204
|
nv = self.getFieldValue(k)
|
190
205
|
notes.append(f"{k} changed from {v} to {nv}")
|
191
|
-
note = "\n".join(notes)
|
206
|
+
note = "\n<br>".join(notes)
|
192
207
|
|
193
208
|
h = IncidentHistory(
|
194
209
|
parent=self,
|
@@ -260,18 +275,16 @@ class Incident(models.Model, rm.RestModel, rm.MetaDataModel):
|
|
260
275
|
# calculate our bundle start time
|
261
276
|
when = datetime.now() - timedelta(minutes=rule.bundle)
|
262
277
|
q = objict(rule=rule, created__gte=when)
|
263
|
-
if rule.bundle_by
|
278
|
+
if rule.bundle_by in [2, 3, 5]:
|
279
|
+
if event.component_id:
|
280
|
+
q.component = event.component
|
281
|
+
q.component_id = event.component_id
|
282
|
+
if rule.bundle_by in [1, 3, 7]:
|
264
283
|
q.hostname = event.hostname
|
265
|
-
elif rule.bundle_by
|
266
|
-
q.component = event.category
|
267
|
-
elif rule.bundle_by == 3:
|
268
|
-
q.hostname = event.hostname
|
269
|
-
q.component = event.category
|
270
|
-
elif rule.bundle_by == 4:
|
271
|
-
q.reporter_ip = event.reporter_ip
|
272
|
-
elif rule.bundle_by == 5:
|
284
|
+
elif rule.bundle_by in [4, 5, 8]:
|
273
285
|
q.reporter_ip = event.reporter_ip
|
274
|
-
|
286
|
+
elif rule.bundle_by in [6, 7, 8]:
|
287
|
+
q.category = event.category
|
275
288
|
return Incident.objects.filter(**q).last()
|
276
289
|
|
277
290
|
@classmethod
|
@@ -0,0 +1,65 @@
|
|
1
|
+
from django.db import models
|
2
|
+
from django.conf import settings
|
3
|
+
|
4
|
+
from rest import models as rm
|
5
|
+
from rest import helpers as rh
|
6
|
+
|
7
|
+
|
8
|
+
class Ticket(models.Model, rm.RestModel, rm.MetaDataModel):
|
9
|
+
class RestMeta:
|
10
|
+
SEARCH_FIELDS = ["title", "description"]
|
11
|
+
CAN_DELETE = True
|
12
|
+
VIEW_PERMS = ["view_tickets"]
|
13
|
+
GRAPHS = {
|
14
|
+
"default": {
|
15
|
+
"extra": ["metadata"],
|
16
|
+
"graphs": {
|
17
|
+
"group": "basic",
|
18
|
+
"created_by": "basic",
|
19
|
+
"assigned_to": "basic",
|
20
|
+
"incident": "basic"
|
21
|
+
},
|
22
|
+
},
|
23
|
+
"detailed": {
|
24
|
+
"graphs": {
|
25
|
+
"group": "basic",
|
26
|
+
"created_by": "basic",
|
27
|
+
"assigned_to": "basic",
|
28
|
+
"incident": "basic",
|
29
|
+
"generic__component": "basic"
|
30
|
+
},
|
31
|
+
},
|
32
|
+
}
|
33
|
+
|
34
|
+
created = models.DateTimeField(auto_now_add=True)
|
35
|
+
modified = models.DateTimeField(auto_now=True)
|
36
|
+
|
37
|
+
group = models.ForeignKey(
|
38
|
+
"account.Group", on_delete=models.SET_NULL,
|
39
|
+
related_name="tickets",
|
40
|
+
null=True, default=None)
|
41
|
+
assigned_to = models.ForeignKey(
|
42
|
+
"account.Member", on_delete=models.SET_NULL,
|
43
|
+
related_name="tickets",
|
44
|
+
null=True, default=None)
|
45
|
+
created_by = models.ForeignKey(
|
46
|
+
"account.Member", on_delete=models.CASCADE,
|
47
|
+
related_name="+",
|
48
|
+
null=True, default=None)
|
49
|
+
|
50
|
+
# if category is null then this will run on all events?
|
51
|
+
category = models.CharField(max_length=200, db_index=True)
|
52
|
+
priority = models.IntegerField(default=10, db_index=True) # 1-10, 1 being the highest
|
53
|
+
|
54
|
+
title = models.CharField(max_length=200)
|
55
|
+
description = models.TextField()
|
56
|
+
|
57
|
+
status = models.CharField(max_length=32, default=None, null=True, db_index=True)
|
58
|
+
state = models.IntegerField(default=0) # how many incidents before firing action
|
59
|
+
|
60
|
+
incident = models.ForeignKey(
|
61
|
+
"incident.Incident", null=True, default=None,
|
62
|
+
related_name="tickets", on_delete=models.SET_NULL)
|
63
|
+
|
64
|
+
component = models.CharField(max_length=200, null=True, default=None, db_index=True)
|
65
|
+
component_id = models.IntegerField(null=True, blank=True, default=None, db_index=True)
|
incident/rpc.py
CHANGED
@@ -158,3 +158,9 @@ def rest_firewall_block(request):
|
|
158
158
|
return rv.restPermissionDenied(request)
|
159
159
|
Task.Publish("incident", f"firewall_{action}", dict(ip=ip), channel="tq_broadcast")
|
160
160
|
return rv.restStatus(request, True)
|
161
|
+
|
162
|
+
|
163
|
+
@rd.url('ticket')
|
164
|
+
@rd.url('ticket/<int:pk>')
|
165
|
+
def rest_on_ticket(request, pk=None):
|
166
|
+
return am.Ticket.on_rest_request(request, pk)
|
rest/__init__.py
CHANGED
File without changes
|
File without changes
|