django-restit 4.2.179__py3-none-any.whl → 4.2.180__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/models/member.py +1 -1
- {django_restit-4.2.179.dist-info → django_restit-4.2.180.dist-info}/METADATA +1 -1
- {django_restit-4.2.179.dist-info → django_restit-4.2.180.dist-info}/RECORD +10 -10
- incident/models/event.py +113 -63
- rest/__init__.py +1 -1
- rest/decorators.py +1 -2
- wiki/renderers/__init__.py +9 -0
- wiki/renderers/mistune/media.py +4 -4
- {django_restit-4.2.179.dist-info → django_restit-4.2.180.dist-info}/LICENSE.md +0 -0
- {django_restit-4.2.179.dist-info → django_restit-4.2.180.dist-info}/WHEEL +0 -0
account/models/member.py
CHANGED
@@ -357,7 +357,7 @@ class Member(User, RestModel, MetaDataModel):
|
|
357
357
|
self.log("login_blocked", "password has expired", request, method="login", level=31)
|
358
358
|
if throw_exception:
|
359
359
|
raise PermissionDeniedException(
|
360
|
-
"password expired", 412,
|
360
|
+
f"{self.username} password expired", 412,
|
361
361
|
component="account.Member", component_id=self.id)
|
362
362
|
return False
|
363
363
|
return True
|
@@ -31,7 +31,7 @@ account/models/device.py,sha256=8D-Sbv9PZWAnX6UVpp1lNJ03P24fknNnN1VOhqY7RVg,6306
|
|
31
31
|
account/models/feeds.py,sha256=vI7fG4ASY1M0Zjke24RdnfDcuWeATl_yR_25jPmT64g,2011
|
32
32
|
account/models/group.py,sha256=Pmm6G5Qb9C-OQ70xUxp5M1_PAg1DtvUxb5WFFW-WmOY,22909
|
33
33
|
account/models/legacy.py,sha256=zYdtv4LC0ooxPVqWM-uToPwV-lYWQLorSE6p6yn1xDw,2720
|
34
|
-
account/models/member.py,sha256=
|
34
|
+
account/models/member.py,sha256=xkVpADfnKkUEIg8EDy7OU077c0e5ZGEQKYvcwhGzXd0,55393
|
35
35
|
account/models/membership.py,sha256=90EpAhOsGaqphDAkONP6j_qQ0OWSRaQsI8H7E7fgMkE,9249
|
36
36
|
account/models/notify.py,sha256=YKYEXT56i98b7-ydLt5UuEVOqW7lipQMi-KuiPhcSwY,15627
|
37
37
|
account/models/passkeys.py,sha256=lObapudvL--ABSTZTIELmYvHE3dPF0tO_KmuYk0ZJXc,1699
|
@@ -115,7 +115,7 @@ incident/migrations/0015_rule_title_template_alter_incident_state.py,sha256=FPUD
|
|
115
115
|
incident/migrations/0016_rule_notify_template.py,sha256=4WGdMxiELujLIy9bzHovHWbAORupodN1Ty3vsy3mLjg,425
|
116
116
|
incident/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
117
117
|
incident/models/__init__.py,sha256=NMphuhb0RTMf7Ov4QkNv7iv6_I8Wtr3xQ54yjX_a31M,209
|
118
|
-
incident/models/event.py,sha256=
|
118
|
+
incident/models/event.py,sha256=skhnH4q80XkxcXNo1JNTAF1SzSLUssB3_mjtFX_xxw0,8864
|
119
119
|
incident/models/incident.py,sha256=oxwLDJYGmk26zf7AD_e7nKcoJw3gXibjrX3DlByNAT8,22580
|
120
120
|
incident/models/ossec.py,sha256=g7cc2vYdYEB8zomohwqbo0ekyPt1v_qA67y35sBn2YY,2244
|
121
121
|
incident/models/rules.py,sha256=PPp8oJDW1gop9i_21lhP50qgt_TrdWErp2mYqZCMfd4,7065
|
@@ -380,7 +380,7 @@ pushit/utils.py,sha256=IeTCGa-164nmB1jIsK1lu1O1QzUhS3BKfuXHGjCW-ck,2121
|
|
380
380
|
rest/.gitignore,sha256=TbEvWRMnAiajCTOdhiNrd9eeCAaIjRp9PRjE_VkMM5g,118
|
381
381
|
rest/README.md,sha256=V3ETc-cJu8PZIbKr9xSe_pA4JEUpC8Dhw4bQeVCDJPw,5460
|
382
382
|
rest/RemoteEvents.py,sha256=nL46U7AuxIrlw2JunphR1tsXyqi-ep_gD9CYGpYbNgE,72
|
383
|
-
rest/__init__.py,sha256=
|
383
|
+
rest/__init__.py,sha256=01ohdi9tNjAEK-JvD5T6Orp2UIBd3QpmjM5PeLM8DU4,122
|
384
384
|
rest/arc4.py,sha256=y644IbF1ec--e4cUJ3KEYsewTCITK0gmlwa5mJruFC0,1967
|
385
385
|
rest/cache.py,sha256=1Qg0rkaCJCaVP0-l5hZg2CIblTdeBSlj_0fP6vlKUpU,83
|
386
386
|
rest/crypto/__init__.py,sha256=Tl0U11rgj1eBYqd6OXJ2_XSdNLumW_JkBZnaJqI6Ldw,72
|
@@ -388,7 +388,7 @@ rest/crypto/aes.py,sha256=NOVRBRSHCV-om68YpGySWWG-4kako3iEVjq8hxZWPUU,4372
|
|
388
388
|
rest/crypto/privpub.py,sha256=_FioylVcbMmDP80yPYjURmafEiDmEAMkskbc7WF10ac,4082
|
389
389
|
rest/crypto/util.py,sha256=agFN2OCPHC70tHNGWrMkkZX4Tt_Ty6imoKEMdTkZpKA,4514
|
390
390
|
rest/datem.py,sha256=qbkgDpTVbxpnS4hRm_GnyRo9Gk7nRJbH-tJqxm172mo,13152
|
391
|
-
rest/decorators.py,sha256=
|
391
|
+
rest/decorators.py,sha256=1lLbjxSHbGgJlFkDQ3QqOPaLpBRZK0dw2OMrLnAT9XQ,15382
|
392
392
|
rest/encryption.py,sha256=x6Kiez0tVqfxK26MSsRL3k8OS05ni1gEX2aj3I0S9V0,788
|
393
393
|
rest/errors.py,sha256=uKwG9OkLme36etabqK54DMjMQc1fgEoUIAUxXa7WFQw,612
|
394
394
|
rest/extra/__init__.py,sha256=YzmNsch5H5FFLkUK9mIAKyoRK_rJCA9HGb0kubp4h30,54
|
@@ -494,11 +494,11 @@ wiki/models/faq.py,sha256=nvcEFerllQKT61kIYlasvZzRKwpXyfmQpiqkpHP1V1o,1745
|
|
494
494
|
wiki/models/page.py,sha256=uIu-jVdf1Y9qXKbb5k15-8RLTltyTtoXobZJFcx8_0A,8836
|
495
495
|
wiki/models/revision.py,sha256=St5-vz8SGvogsDL6jTWqHLE23PS5mp9iA0DUt3hWTsU,729
|
496
496
|
wiki/periodic.py,sha256=t-UgXJIug-OLslJM_r03-5WrNKj39TxrvfuNFjVAhDs,334
|
497
|
-
wiki/renderers/__init__.py,sha256=
|
497
|
+
wiki/renderers/__init__.py,sha256=si9LdyUtGWbazsddEt7HY9Fl3iJYAeI_Hu9qf1J154I,682
|
498
498
|
wiki/renderers/mistune/__init__.py,sha256=baClLWELOwy5n8UUFi7qmoFBU6QaeegD-wRNZ7fIW_w,84
|
499
499
|
wiki/renderers/mistune/highlight.py,sha256=BosglMQUxc_KVbLapQ4gCt6rCc0rAF1vCtUR7R1Ad4c,1264
|
500
500
|
wiki/renderers/mistune/math.py,sha256=dgQpH9CIDiqyESphoK5XUVFxK5Yb5VhEIoLgjp3Vtcs,1901
|
501
|
-
wiki/renderers/mistune/media.py,sha256=
|
501
|
+
wiki/renderers/mistune/media.py,sha256=wV7VYfKxhlfhxPAmpL28COXvhRQ1eQulPgV6hBYACF8,2747
|
502
502
|
wiki/renderers/mistune/meta.py,sha256=1lry9m-4wiwsivWnqYHYjwmGv91BGUSB7niJuZ1Xx54,805
|
503
503
|
wiki/renderers/mistune/task_list.py,sha256=Ex0gUPX_d9jtbPbnEEktlqAJsM6wIt5Md2wsltX7LIY,1889
|
504
504
|
wiki/renderers/mistune/toc.py,sha256=TKGiuMVpKqzDGUx5bAjJYpZIzG6n3wTjtuBdBc-TM_8,2302
|
@@ -518,7 +518,7 @@ ws4redis/servers/uwsgi.py,sha256=VyhoCI1DnVFqBiJYHoxqn5Idlf6uJPHvfBKgkjs34mo,172
|
|
518
518
|
ws4redis/settings.py,sha256=KKq00EwoGnz1yLwCZr5Dfoq2izivmAdsNEEM4EhZwN4,1610
|
519
519
|
ws4redis/utf8validator.py,sha256=S0OlfjeGRP75aO6CzZsF4oTjRQAgR17OWE9rgZdMBZA,5122
|
520
520
|
ws4redis/websocket.py,sha256=R0TUyPsoVRD7Y_oU7w2I6NL4fPwiz5Vl94-fUkZgLHA,14848
|
521
|
-
django_restit-4.2.
|
522
|
-
django_restit-4.2.
|
523
|
-
django_restit-4.2.
|
524
|
-
django_restit-4.2.
|
521
|
+
django_restit-4.2.180.dist-info/LICENSE.md,sha256=VHN4hhEeVOoFjtG-5fVv4jesA4SWi0Z-KgOzzN6a1ps,1068
|
522
|
+
django_restit-4.2.180.dist-info/METADATA,sha256=PtXqvmNGrzGdzNKLZvdYKbY_oKYMWZQ54JtWVWk03z8,7714
|
523
|
+
django_restit-4.2.180.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
524
|
+
django_restit-4.2.180.dist-info/RECORD,,
|
incident/models/event.py
CHANGED
@@ -129,85 +129,135 @@ class Event(JSONMetaData, rm.RestModel):
|
|
129
129
|
value = value[:80] + "..."
|
130
130
|
self.description = value
|
131
131
|
|
132
|
-
|
132
|
+
|
133
|
+
def on_rest_created(self, request):
|
134
|
+
# Record metrics if enabled
|
135
|
+
if INCIDENT_EVENT_METRICS:
|
136
|
+
self._record_event_metrics()
|
137
|
+
|
138
|
+
self._update_properties(request)
|
139
|
+
# Process rules and create incident if needed
|
140
|
+
hit_rule = self.runRules()
|
141
|
+
incident = self._process_rules_and_create_incident(hit_rule)
|
142
|
+
|
143
|
+
if incident is None:
|
144
|
+
# No incident needed based on rules
|
145
|
+
return
|
146
|
+
|
147
|
+
# Update incident metadata
|
148
|
+
self.incident = incident
|
149
|
+
self.save()
|
150
|
+
|
151
|
+
# Record incident metrics if enabled
|
152
|
+
if INCIDENT_METRICS:
|
153
|
+
self._record_incident_metrics()
|
154
|
+
|
155
|
+
# Trigger any incident actions
|
156
|
+
try:
|
157
|
+
incident.triggerAction()
|
158
|
+
except Exception:
|
159
|
+
logger.exception()
|
160
|
+
|
161
|
+
def _update_properties(self, request):
|
162
|
+
# make sure hostname is set
|
133
163
|
if self.hostname is None:
|
134
164
|
self.hostname = settings.HOSTNAME
|
165
|
+
|
166
|
+
# Update properties
|
167
|
+
self.setProperty("level", self.level)
|
168
|
+
self.setProperty("category", self.category)
|
135
169
|
if not self.getProperty("hostname", None):
|
136
170
|
self.setProperty("hostname", self.hostname)
|
137
|
-
|
171
|
+
|
172
|
+
# lookup IP
|
138
173
|
if request and request.DATA.get("ip_lookup", field_type=bool):
|
139
174
|
self.reporter_ip = request.ip
|
140
175
|
self.lookupIP(request.ip)
|
141
176
|
|
142
|
-
def
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
177
|
+
def _record_event_metrics(self):
|
178
|
+
"""Record event metrics"""
|
179
|
+
if self.hostname:
|
180
|
+
metrics.metric(
|
181
|
+
f"incident_evt_{self.hostname}",
|
182
|
+
category="incident_events",
|
183
|
+
min_granularity="hourly"
|
184
|
+
)
|
185
|
+
metrics.metric(
|
186
|
+
"incident_evt",
|
187
|
+
min_granularity=INCIDENT_EVENT_GRANULARITY
|
188
|
+
)
|
149
189
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
190
|
+
def _record_incident_metrics(self):
|
191
|
+
"""Record incident metrics"""
|
192
|
+
if self.hostname:
|
193
|
+
metrics.metric(
|
194
|
+
f"incidents_{self.hostname}",
|
195
|
+
category="incidents",
|
196
|
+
min_granularity="hourly"
|
197
|
+
)
|
198
|
+
metrics.metric(
|
199
|
+
"incidents",
|
200
|
+
min_granularity=INCIDENT_EVENT_GRANULARITY
|
201
|
+
)
|
202
|
+
|
203
|
+
def _process_rules_and_create_incident(self, hit_rule):
|
204
|
+
"""Process rules and create incident if needed"""
|
158
205
|
if hit_rule is not None:
|
159
|
-
#
|
160
|
-
priority = hit_rule.priority
|
206
|
+
# Handle rule matches
|
161
207
|
if hit_rule.action == "ignore":
|
162
208
|
self.save()
|
163
|
-
return
|
209
|
+
return None
|
210
|
+
|
164
211
|
if hit_rule.bundle > 0:
|
165
|
-
|
212
|
+
return Incident.getBundled(rule=hit_rule, event=self)
|
166
213
|
|
167
214
|
elif self.level >= EVENT_TO_INCIDENT_LEVEL:
|
168
|
-
#
|
215
|
+
# Ignore high levels without rules
|
169
216
|
self.save()
|
170
|
-
|
171
|
-
return
|
217
|
+
return None
|
172
218
|
|
173
|
-
#
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
219
|
+
# Create new incident
|
220
|
+
return self._create_incident(hit_rule)
|
221
|
+
|
222
|
+
def _create_incident(self, hit_rule):
|
223
|
+
"""Create a new incident"""
|
224
|
+
incident = Incident(
|
225
|
+
rule=hit_rule,
|
226
|
+
priority=hit_rule.priority if hit_rule else 10,
|
227
|
+
reporter_ip=self.reporter_ip,
|
228
|
+
category=self.category,
|
229
|
+
group=self.group,
|
230
|
+
component=self.component,
|
231
|
+
component_id=self.component_id,
|
232
|
+
hostname=self.hostname
|
233
|
+
)
|
234
|
+
|
235
|
+
# Set incident group from rule if needed
|
236
|
+
if self.group is None and hit_rule is not None:
|
237
|
+
incident.group = hit_rule.group
|
238
|
+
|
239
|
+
# Set pending state if rule requires
|
240
|
+
if hit_rule is not None and hit_rule.action_after != 0:
|
241
|
+
incident.state = INCIDENT_STATE_PENDING
|
242
|
+
|
243
|
+
# Set description based on rules and category
|
244
|
+
self._set_incident_description(incident, hit_rule)
|
245
|
+
|
246
|
+
incident.save()
|
247
|
+
incident.updateMeta(self)
|
248
|
+
return incident
|
249
|
+
|
250
|
+
def _set_incident_description(self, incident, hit_rule):
|
251
|
+
"""Set the incident description"""
|
252
|
+
if hit_rule and hit_rule.title_template and "{" in hit_rule.title_template:
|
253
|
+
try:
|
254
|
+
incident.description = hit_rule.title_template.format(event=self)
|
255
|
+
except Exception:
|
256
|
+
logger.exception(hit_rule.title_template)
|
199
257
|
incident.description = self.description
|
258
|
+
elif self.category == "ossec":
|
259
|
+
incident.description = f"{self.hostname}: {self.description}"
|
200
260
|
incident.save()
|
201
|
-
incident.
|
202
|
-
|
203
|
-
|
204
|
-
if INCIDENT_METRICS:
|
205
|
-
# we want to track any incidents, including bundles
|
206
|
-
if self.hostname:
|
207
|
-
metrics.metric(f"incidents_{self.hostname}", category="incidents", min_granularity="hourly")
|
208
|
-
metrics.metric("incidents", min_granularity=INCIDENT_EVENT_GRANULARITY)
|
209
|
-
|
210
|
-
try:
|
211
|
-
incident.triggerAction()
|
212
|
-
except Exception:
|
213
|
-
logger.exception()
|
261
|
+
incident.updateAbuseInfo()
|
262
|
+
else:
|
263
|
+
incident.description = self.description
|
rest/__init__.py
CHANGED
rest/decorators.py
CHANGED
@@ -62,7 +62,7 @@ def rest_error_catcher(func, request, *args, **kwargs):
|
|
62
62
|
metrics.metric(f"rest_call_{slug_path}", category="rest_calls", min_granularity=REST_METRICS_GRANULARITY)
|
63
63
|
return func(request, *args, **kwargs)
|
64
64
|
except PermissionDeniedException as err:
|
65
|
-
return rv.restPermissionDenied(request, err.reason, err.code)
|
65
|
+
return rv.restPermissionDenied(request, err.reason, err.code, component=err.component, component_id=err.component_id)
|
66
66
|
except RestError as err:
|
67
67
|
rh.log_exception("REST ERROR", request.path, err.reason)
|
68
68
|
if settings.get("REST_ERROR_METRICS", True):
|
@@ -437,4 +437,3 @@ def periodic(minute=None, hour=None, day=None, month=None, weekday=None, tz=None
|
|
437
437
|
inner_func.is_periodic = True
|
438
438
|
return inner_func
|
439
439
|
return decorator
|
440
|
-
|
wiki/renderers/__init__.py
CHANGED
@@ -2,14 +2,23 @@ from .mistune.highlight import HighlightMixin
|
|
2
2
|
from .mistune.toc import TocMixin
|
3
3
|
from .mistune.media import MediaMixin
|
4
4
|
import mistune
|
5
|
+
import re
|
6
|
+
|
5
7
|
try:
|
6
8
|
HTMLRenderer = mistune.HTMLRenderer
|
7
9
|
except Exception:
|
8
10
|
HTMLRenderer = mistune.Renderer
|
9
11
|
|
10
12
|
|
13
|
+
def slugify(text):
|
14
|
+
return re.sub(r'\W+', '-', text.strip().lower()).strip('-')
|
15
|
+
|
11
16
|
class WikiRenderer(TocMixin, HighlightMixin, MediaMixin, HTMLRenderer):
|
12
17
|
def __init__(self, *args, **kwargs):
|
13
18
|
# self.enable_math()
|
14
19
|
self.reset_toc()
|
15
20
|
super(WikiRenderer, self).__init__(*args, **kwargs)
|
21
|
+
|
22
|
+
def heading(self, text, level):
|
23
|
+
slug = slugify(text)
|
24
|
+
return f'<h{level} id="{slug}">{text}</h{level}>\n'
|
wiki/renderers/mistune/media.py
CHANGED
@@ -48,10 +48,11 @@ class MediaMixin(object):
|
|
48
48
|
params = {"href":href}
|
49
49
|
if title:
|
50
50
|
params["title"] = title
|
51
|
-
|
52
|
-
|
53
|
-
if not href.startswith("http"):
|
51
|
+
|
52
|
+
if not href.startswith("http") and not href.startswith("#"):
|
54
53
|
params["data-action"] = "local_page"
|
54
|
+
elif label and href.startswith("http"):
|
55
|
+
params["download"] = label
|
55
56
|
flat_params = ' '.join("{}='{}'".format(key,val) for (key,val) in list(params.items()))
|
56
57
|
return """<a {}>{}</a>""".format(flat_params, (text or link))
|
57
58
|
|
@@ -87,4 +88,3 @@ class MediaMixin(object):
|
|
87
88
|
|
88
89
|
flat_params = ' '.join("{}='{}'".format(key,val) for (key,val) in list(params.items()))
|
89
90
|
return '<img {} />'.format(flat_params)
|
90
|
-
|
File without changes
|
File without changes
|