django-restit 4.2.142__py3-none-any.whl → 4.2.144__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-restit
3
- Version: 4.2.142
3
+ Version: 4.2.144
4
4
  Summary: A Rest Framework for DJANGO
5
5
  License: MIT
6
6
  Author: Ian Starnes
@@ -96,6 +96,8 @@ inbox/utils/render.py,sha256=CU_F2qUBQE7mjb9Q6Dn9ro5CS_O_zEY-wDMHEClKkIA,4331
96
96
  inbox/utils/sending.py,sha256=BKelTZnbkdSLGpjOY6IRTrzj-Hnw2pPZ7RYQGwe-tqk,2179
97
97
  incident/README.md,sha256=4vbZTJj7uUmq8rogYngxqNYjFTlBOujfWUGheLoFKMc,1114
98
98
  incident/__init__.py,sha256=xgdt3z3z7ygjWv5HxhiWgBtB2W3IUJmmR88NSyUeHuo,3455
99
+ incident/extra/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
100
+ incident/extra/abuse.py,sha256=TaNs1mF7L2ijoAl5iyEX1BaUgaOwsCeeF2_zwj4RSF0,4301
99
101
  incident/migrations/0001_initial.py,sha256=KmJRau3a2QFRaUwUrFUgY2p7FQZCODv3F-Sl0ZArpu0,9720
100
102
  incident/migrations/0002_event_component_event_component_id.py,sha256=Qfu3ndJKh4v7953ULTUZlSa3mVI-lnFIq9VFN1Rbs7Q,595
101
103
  incident/migrations/0003_rule_action.py,sha256=LNqV52qOjxxe3L8qEdln-Hd2voFcpyjOZ_cEsasrv7s,425
@@ -113,15 +115,15 @@ incident/migrations/0014_event_group_alter_rulecheck_index.py,sha256=v3gm5k0LVoa
113
115
  incident/migrations/0015_rule_title_template_alter_incident_state.py,sha256=FPUDhFwqBC39EjeknRT7BPddEf6ExCjsXVb9LMqIn3U,687
114
116
  incident/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
115
117
  incident/models/__init__.py,sha256=NMphuhb0RTMf7Ov4QkNv7iv6_I8Wtr3xQ54yjX_a31M,209
116
- incident/models/event.py,sha256=LNKYdqOj_CO4aGvc2dNmy3K-S52Udi_gZ4-wintbs1s,7901
117
- incident/models/incident.py,sha256=_pzAyUC-RgwrCF-hOIOUDLhdG9koTqZK8pOltBZx48o,21143
118
+ incident/models/event.py,sha256=mk5IQgxtwkLKJEpwIHwO0c45X4CfwqqIN-aI5lJPVBg,7944
119
+ incident/models/incident.py,sha256=n5S-QzGvAOtJmlzbj3vPTY03avIknPjDMLUUq9FyTa0,21648
118
120
  incident/models/ossec.py,sha256=eUDRGawzuLWobKEVGKfdZisDnyjS_Hlxi0T_GCSLCCI,2252
119
121
  incident/models/rules.py,sha256=aRkJ0ZnTv87nAUC1sHVkPExfb3OJ8fgHQIhnCIpIbhQ,7001
120
122
  incident/models/ticket.py,sha256=S3kqGQpYLE6Y4M9IKu_60sgW-f592xNr8uufqHnvDoU,2302
121
123
  incident/parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
122
124
  incident/parsers/ossec.py,sha256=fouUsSnrdkEuqDzJ-MxmCP7ny5pCGFS3Tyf6lQSMBc4,11609
123
125
  incident/periodic.py,sha256=eX1rQK6v65A9ugofTvJPSmAWei6C-3EYgzCMuGZ03jM,381
124
- incident/rpc.py,sha256=6JVWTTAr4CN2tAjjIUcXug1z3RhU_ar5CDLzedkduA4,8187
126
+ incident/rpc.py,sha256=rCFVWhWjaRHBLvlpxs-TlnkCNLsP9n6V3tg4KpYNHfg,8747
125
127
  incident/templates/email/incident_change.html,sha256=tQYphypwLukkVdwH0TB2Szz2VEJ7GnsfRS3_ZJ-MYeE,13895
126
128
  incident/templates/email/incident_msg.html,sha256=MZdKhTddUF2MpiH8Z3RTQEmW_ko1n3ajeZ11KLtiLlU,13780
127
129
  incident/templates/email/incident_new.html,sha256=W6nwFQROnyDfMlXub8s02ws4hGnJp16pfgp9xTm_aEc,15185
@@ -300,7 +302,7 @@ medialib/templates/medialib/testpicker.html,sha256=I7KnrAu9e4kQhuEEN-51HGzcuJ06E
300
302
  medialib/tests.py,sha256=z1THDMo-R9HWMvCCOgX6aH6-2W2uWqrtbJ_k-zfpgyc,6045
301
303
  medialib/tq.py,sha256=ZDRBZ9qEsqNAsk48cciLyX7DIziqD2uPEawtQny1Ja8,544
302
304
  medialib/urls.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
303
- medialib/utils.py,sha256=StQY7k9dOCksdTsYqUb3aGpwwrcYg07z7vskBQqCPnw,3774
305
+ medialib/utils.py,sha256=nHB1g9PuahzVVF8MqDLaxZY8u53Ggtve8nZJKyaIEUA,3810
304
306
  medialib/views.py,sha256=h_Fm3FOX04VV2G-J141wEHxT36d46HVdzPJg_u8r2vI,4321
305
307
  medialib/youtube/__init__.py,sha256=fmu9XPaDpadkb2OuroQsKiWpUPo7c5y8o83HmLLMIHA,4303
306
308
  medialib/youtube/apiclient/__init__.py,sha256=iGdQFKwzm0VxArl8X183-_ZBhIsETZlbXxhBAUz3MfI,601
@@ -377,7 +379,7 @@ pushit/utils.py,sha256=IeTCGa-164nmB1jIsK1lu1O1QzUhS3BKfuXHGjCW-ck,2121
377
379
  rest/.gitignore,sha256=TbEvWRMnAiajCTOdhiNrd9eeCAaIjRp9PRjE_VkMM5g,118
378
380
  rest/README.md,sha256=V3ETc-cJu8PZIbKr9xSe_pA4JEUpC8Dhw4bQeVCDJPw,5460
379
381
  rest/RemoteEvents.py,sha256=nL46U7AuxIrlw2JunphR1tsXyqi-ep_gD9CYGpYbNgE,72
380
- rest/__init__.py,sha256=hlX0ysuPQS5x3bCShSkKyAOossCGUQyGZ4ReDK1NeLM,122
382
+ rest/__init__.py,sha256=WbQDlSqAn04sJ1Ns67DJScCD43s2A5xHagr1HISnV7I,122
381
383
  rest/arc4.py,sha256=y644IbF1ec--e4cUJ3KEYsewTCITK0gmlwa5mJruFC0,1967
382
384
  rest/cache.py,sha256=1Qg0rkaCJCaVP0-l5hZg2CIblTdeBSlj_0fP6vlKUpU,83
383
385
  rest/crypto/__init__.py,sha256=Tl0U11rgj1eBYqd6OXJ2_XSdNLumW_JkBZnaJqI6Ldw,72
@@ -416,7 +418,7 @@ rest/models/metadata.py,sha256=1nQ7CYo9bJHoaXE_hVNaj1-Y7yqhHlf2ZlaD1IfTzic,12904
416
418
  rest/net.py,sha256=LcB2QV6VNRtsSdmiQvYZgwQUDwOPMn_VBdRiZ6OpI-I,2974
417
419
  rest/regexes.yaml,sha256=VoGb4E-P_K9f82Yzcpltgzekpt9usRtwu9PYlo46nUw,149463
418
420
  rest/requestex.py,sha256=N56056vV3zWkAP-QrYsCu7SdpPzE5kLuPoxGIuZAKt0,16127
419
- rest/rpc.py,sha256=fcOI84p8sK9MJBDRgjBwtPtylOTOZNUUhFmFtSSndB8,2919
421
+ rest/rpc.py,sha256=CNQ2RtAPOYxZtpZxjh0sVzBmIGBYMP7n3CDEDwMENF0,2966
420
422
  rest/search.py,sha256=QVjk2b5tZLgf1zM2MHvJTyRjwUbY5ZD7HXSTmSPXtvU,8362
421
423
  rest/serializers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
422
424
  rest/serializers/collection.py,sha256=V9O4qxw26VX9dSYdbsN0-RNnXEi347Ln8eFLZ003LhA,4646
@@ -503,9 +505,9 @@ wiki/tq.py,sha256=wvuBZ3OMV_D2o4kpJhVLIOwpEUfwlglqLJQvpncAwtk,313
503
505
  ws4redis/README.md,sha256=QvwdsauPKxx4qQqnJ991xeU8DgFQCj3CeQt-nCE4s-w,3624
504
506
  ws4redis/__init__.py,sha256=teNfv83A_ke1CBt9BB7NsnWCcFBhnUFPsPESjF554_k,46
505
507
  ws4redis/client.py,sha256=HTntgqlMzZU9MhBz3fn3fXDpzfaTDZx_9tIb5SU91hY,7077
506
- ws4redis/connection.py,sha256=rlzdmgyjmuqETxjNf3uZU3tfoBeQQTzD4ZFru_u3JAs,13738
508
+ ws4redis/connection.py,sha256=HeRrQUxNYMJ-2SSSYB2XBHScKRbQRMCuQueDSUDJXXQ,13740
507
509
  ws4redis/exceptions.py,sha256=EGLoRTdqJVwz900pwhciqPuSjBBd08hhLgFu6umHrI4,636
508
- ws4redis/redis.py,sha256=fTNKrXPelowZrgji1XaijUoeQepV1ab1_Y3_tHsysww,6511
510
+ ws4redis/redis.py,sha256=jHfwpUG0Nru_zSyD-xwJhX67gASqVtTFiAc3RwgTcJs,6542
509
511
  ws4redis/servers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
510
512
  ws4redis/servers/base.py,sha256=3nYZF5jSsQxNLbnLtKLFJ82xJs_Mc7N1H2kEOx8wT6o,3747
511
513
  ws4redis/servers/django.py,sha256=cKOE4U0cE8I3_rDaLgv-KuDb376RASdOzUn7MlDA4As,5900
@@ -513,7 +515,7 @@ ws4redis/servers/uwsgi.py,sha256=VyhoCI1DnVFqBiJYHoxqn5Idlf6uJPHvfBKgkjs34mo,172
513
515
  ws4redis/settings.py,sha256=KKq00EwoGnz1yLwCZr5Dfoq2izivmAdsNEEM4EhZwN4,1610
514
516
  ws4redis/utf8validator.py,sha256=S0OlfjeGRP75aO6CzZsF4oTjRQAgR17OWE9rgZdMBZA,5122
515
517
  ws4redis/websocket.py,sha256=R0TUyPsoVRD7Y_oU7w2I6NL4fPwiz5Vl94-fUkZgLHA,14848
516
- django_restit-4.2.142.dist-info/LICENSE.md,sha256=VHN4hhEeVOoFjtG-5fVv4jesA4SWi0Z-KgOzzN6a1ps,1068
517
- django_restit-4.2.142.dist-info/METADATA,sha256=ExBXdVbSrP8zJp7cm9D0SYaS6kTRjQXDmNdwHuzGviw,7663
518
- django_restit-4.2.142.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
519
- django_restit-4.2.142.dist-info/RECORD,,
518
+ django_restit-4.2.144.dist-info/LICENSE.md,sha256=VHN4hhEeVOoFjtG-5fVv4jesA4SWi0Z-KgOzzN6a1ps,1068
519
+ django_restit-4.2.144.dist-info/METADATA,sha256=P1p28suzqWk267UAN1dJ0FhlQZe6c3DALCwbPdqC2DQ,7663
520
+ django_restit-4.2.144.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
521
+ django_restit-4.2.144.dist-info/RECORD,,
File without changes
@@ -0,0 +1,125 @@
1
+ import requests
2
+ import ipaddress
3
+ from objict import objict
4
+ from rest import settings
5
+ from datetime import datetime
6
+ from enum import Enum
7
+
8
+ API_KEY = settings.get("ABUSEIPDB_KEY", "")
9
+
10
+ DEFAULT_HEADERS = {
11
+ 'Accept': 'application/json',
12
+ 'Key': API_KEY
13
+ }
14
+
15
+
16
+ class AbuseCategory(Enum):
17
+ DNS_COMPROMISE = (1, "Altering DNS records resulting in improper redirection.")
18
+ DNS_POISONING = (2, "Falsifying domain server cache (cache poisoning).")
19
+ FRAUD_ORDERS = (3, "Fraudulent orders.")
20
+ DDOS_ATTACK = (4, "Participating in distributed denial-of-service (usually part of botnet).")
21
+ FTP_BRUTE_FORCE = (5, "FTP Brute-Force")
22
+ PING_OF_DEATH = (6, "Oversized IP packet.")
23
+ PHISHING = (7, "Phishing websites and/or email.")
24
+ FRAUD_VOIP = (8, "Fraud VoIP")
25
+ OPEN_PROXY = (9, "Open proxy, open relay, or Tor exit node.")
26
+ WEB_SPAM = (10, "Comment/forum spam, HTTP referer spam, or other CMS spam.")
27
+ EMAIL_SPAM = (11, "Spam email content, infected attachments, and phishing emails.")
28
+ BLOG_SPAM = (12, "CMS blog comment spam.")
29
+ VPN_IP = (13, "Conjunctive category.")
30
+ PORT_SCAN = (14, "Scanning for open ports and vulnerable services.")
31
+ HACKING = (15, "Hacking")
32
+ SQL_INJECTION = (16, "Attempts at SQL injection.")
33
+ SPOOFING = (17, "Email sender spoofing.")
34
+ BRUTE_FORCE = (18, "Credential brute-force attacks on webpage logins and services.")
35
+ BAD_WEB_BOT = (19, "Webpage scraping and crawlers that do not honor robots.txt.")
36
+ EXPLOITED_HOST = (20, "Host is likely infected with malware and being used for other attacks.")
37
+ WEB_APP_ATTACK = (21, "Attempts to probe for or exploit installed web applications.")
38
+ SSH = (22, "Secure Shell (SSH) abuse.")
39
+ IOT_TARGETED = (23, "Abuse targeted at an 'Internet of Things' type device.")
40
+
41
+ def __init__(self, code, description):
42
+ self.code = code
43
+ self.description = description
44
+
45
+ def __str__(self):
46
+ return f"{self.name} ({self.code}): {self.description}"
47
+
48
+
49
+ def lookup(ip, max_days=0):
50
+ """
51
+ {
52
+ "data": {
53
+ "ipAddress": "118.25.6.39",
54
+ "isPublic": true,
55
+ "ipVersion": 4,
56
+ "isWhitelisted": false,
57
+ "abuseConfidenceScore": 100,
58
+ "countryCode": "CN",
59
+ "countryName": "China",
60
+ "usageType": "Data Center/Web Hosting/Transit",
61
+ "isp": "Tencent Cloud Computing (Beijing) Co. Ltd",
62
+ "domain": "tencent.com",
63
+ "hostnames": [],
64
+ "isTor": false,
65
+ "totalReports": 1,
66
+ "numDistinctUsers": 1,
67
+ "lastReportedAt": "2018-12-20T20:55:14+00:00",
68
+ "reports": [
69
+ {
70
+ "reportedAt": "2018-12-20T20:55:14+00:00",
71
+ "comment": "Dec 20 20:55:14 srv206 sshd[13937]: Invalid user oracle from 118.25.6.39",
72
+ "categories": [
73
+ 18,
74
+ 22
75
+ ],
76
+ "reporterId": 1,
77
+ "reporterCountryCode": "US",
78
+ "reporterCountryName": "United States"
79
+ }
80
+ ]
81
+ }
82
+ }
83
+ """
84
+ if not API_KEY:
85
+ return objict(errors=[{"detail": "Missing API KEY", "status": 401}])
86
+ url = 'https://api.abuseipdb.com/api/v2/check'
87
+ params = dict(ipAddress=ip)
88
+ if max_days:
89
+ params["maxAgeInDays"] = max_days
90
+ response = requests.request(
91
+ method='GET', url=url, headers=DEFAULT_HEADERS,
92
+ params=params)
93
+ return objict.fromJSON(response.text)
94
+
95
+
96
+ def reportAbuse(ip, comment, categories):
97
+ """
98
+ {
99
+ "data": {
100
+ "ipAddress": "127.0.0.1",
101
+ "abuseConfidenceScore": 52
102
+ }
103
+ }
104
+ """
105
+ if not API_KEY:
106
+ return objict(errors=[{"detail": "Missing API KEY", "status": 401}])
107
+ url = 'https://api.abuseipdb.com/api/v2/report'
108
+ now_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
109
+ params = dict(ip=ip, comment=comment, timestamp=now_str, categories=categories)
110
+ response = requests.request(
111
+ method='POST', url=url,
112
+ headers=DEFAULT_HEADERS, params=params)
113
+ return objict.fromJSON(response.text)
114
+
115
+
116
+ def isPrivate(ip, ignore_errors=False):
117
+ if not ignore_errors:
118
+ ip_obj = ipaddress.ip_address(ip)
119
+ return ip_obj.is_private
120
+ try:
121
+ ip_obj = ipaddress.ip_address(ip)
122
+ return ip_obj.is_private
123
+ except Exception:
124
+ pass
125
+ return None
incident/models/event.py CHANGED
@@ -193,6 +193,7 @@ class Event(JSONMetaData, rm.RestModel):
193
193
  incident.description = self.description
194
194
  elif self.category == "ossec":
195
195
  incident.description = f"{self.hostname}: {self.description}"
196
+ incident.updateAbuseInfo()
196
197
  else:
197
198
  incident.description = self.description
198
199
  incident.save()
@@ -10,6 +10,7 @@ from datetime import datetime, timedelta
10
10
  from rest import log
11
11
  from ws4redis import client as ws4redis
12
12
  import time
13
+ from incident.extra import abuse
13
14
 
14
15
  logger = log.getLogger("incident", filename="incident.log")
15
16
 
@@ -483,6 +484,19 @@ class Incident(models.Model, rm.RestModel, rm.MetaDataModel):
483
484
  email_only=True,
484
485
  from_email=INCIDENT_EMAIL_FROM)
485
486
 
487
+ def updateAbuseInfo(self, ip=None):
488
+ # for now we just check if this ip is in the abuse ip db
489
+ if ip is None:
490
+ ip = self.reporter_ip
491
+ is_priv = abuse.isPrivate(ip, ignore_errors=True)
492
+ if is_priv is not None:
493
+ self.setProperty("is_private_ip", is_priv)
494
+ if is_priv:
495
+ return
496
+ info = abuse.lookup(ip, 0)
497
+ if "errors" not in info:
498
+ self.setProperty("abuse_info", info)
499
+
486
500
  @classmethod
487
501
  def getBundled(cls, rule, event):
488
502
  # calculate our bundle start time
incident/rpc.py CHANGED
@@ -3,6 +3,7 @@ from rest import views as rv
3
3
  from rest import helpers as rh
4
4
  from rest import settings
5
5
  from . import models as am
6
+ from .extra import abuse
6
7
  from .parsers import ossec
7
8
  from taskqueue.models import Task
8
9
  import incident
@@ -234,3 +235,20 @@ def rest_firewall_block(request):
234
235
  @rd.url('ticket/<int:pk>')
235
236
  def rest_on_ticket(request, pk=None):
236
237
  return am.Ticket.on_rest_request(request, pk)
238
+
239
+
240
+ @rd.urlGET('abuse/lookup')
241
+ @rd.requires_params(["ip"])
242
+ def rest_on_abuse_ip_lookup(request):
243
+ resp = abuse.lookup(request.DATA.get("ip"), request.DATA.get("max_age", 0))
244
+ return rv.restReturn(request, resp)
245
+
246
+
247
+ @rd.urlPOST('abuse/report')
248
+ @rd.requires_params(["ip", "comment", "categories"])
249
+ def rest_on_report_abuse(request):
250
+ resp = abuse.reportAbuse(
251
+ ip=request.DATA.get("ip"),
252
+ comment=request.DATA.get("comment"),
253
+ categories=request.DATA.get("categories"))
254
+ return rv.restReturn(request, resp)
medialib/utils.py CHANGED
@@ -7,8 +7,8 @@ import hashlib
7
7
 
8
8
  EXT_MAP = {
9
9
  "V":['mpg', 'mpeg', 'mpe', 'mp4', 'm4v', 'mov', 'qt', '3gp', 'ogv', 'webm', 'flv', 'asf', 'asx', 'wmv', 'mpv', 'mkv', 'avi', 'dat', 'swf'],
10
- "I":['jpg', 'jpg', 'jpeg', 'gif', 'png', 'bmp', 'tif', 'tiff'],
11
- "T":['txt', 'html'],
10
+ "I":['jpg', 'jpg', 'jpeg', 'gif', 'png', 'bmp', 'tif', 'tiff', 'webp', 'ico'],
11
+ "T":['txt', 'html', 'csv', 'md'],
12
12
  }
13
13
 
14
14
  KIND_MAP = {
@@ -27,7 +27,7 @@ def guessBase64Kind(data):
27
27
  # look at first 16 bytes for ext
28
28
  sample = fromBase64ToBytes(data[:16]).lower() # data[:16]
29
29
  # sample = self.base64_data[:16].decode('base64').lower()
30
- for ext in ["png", "jpg", "jpeg", "jfif", "bmp", "gif", "tif"]:
30
+ for ext in ["png", "jpg", "jpeg", "jfif", "bmp", "gif", "tif", "webp"]:
31
31
  if toBytes(ext) in sample:
32
32
  if ext == "jfif":
33
33
  ext = "jpg"
rest/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  from .uberdict import UberDict # noqa: F401
2
2
  from .settings_helper import settings # noqa: F401
3
3
 
4
- __version__ = "4.2.142"
4
+ __version__ = "4.2.144"
rest/rpc.py CHANGED
@@ -81,6 +81,7 @@ def on_get_system_info(request):
81
81
  out = hostinfo.getHostInfo(
82
82
  include_versions=request.DATA.get("versions") and SOFTWARE_VERSIONS,
83
83
  include_blocked=request.DATA.get("blocked"))
84
+ out["redist_pool"] = redis.getPoolStatus()
84
85
  return views.restGet(request, out)
85
86
 
86
87
 
ws4redis/connection.py CHANGED
@@ -286,7 +286,7 @@ class WebsocketConnection():
286
286
  if bool(self.last_msg):
287
287
  self.on_ws_msg(self.last_msg)
288
288
  except Exception:
289
- logger.exception()
289
+ # logger.exception()
290
290
  logger.error("unable to recv on ws... flushing")
291
291
  self.websocket.flush()
292
292
 
ws4redis/redis.py CHANGED
@@ -168,6 +168,7 @@ class RedisStore():
168
168
  if self.pubsub and self.pubsub.subscribed:
169
169
  self.pubsub.unsubscribe()
170
170
  self.pubsub.reset()
171
+ self.connection = None
171
172
 
172
173
  def __enter__(self):
173
174
  return self