assemblyline-ui 4.7.0.dev28__py3-none-any.whl → 4.7.0.dev31__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.
assemblyline_ui/VERSION CHANGED
@@ -1 +1 @@
1
- 4.7.0.dev28
1
+ 4.7.0.dev31
@@ -513,11 +513,11 @@ def saml_acs(**_):
513
513
  data["roles"] = load_roles(data["type"], user_roles)
514
514
 
515
515
  # Load in the user DN
516
- if dn := get_attribute(saml_user_data, "dn"):
516
+ if dn := get_attribute(saml_user_data, config.auth.saml.attributes.dn_attribute):
517
517
  data["dn"] = dn
518
518
 
519
519
  # Get the dynamic classification info
520
- if u_classification := get_attribute(saml_user_data, "classification"):
520
+ if u_classification := get_attribute(saml_user_data, config.auth.saml.attributes.classification_attribute):
521
521
  data["classification"] = get_dynamic_classification(u_classification, data)
522
522
 
523
523
  # Save the updated user
@@ -197,8 +197,9 @@ def who_am_i(**kwargs):
197
197
 
198
198
  # System configuration
199
199
  user_data['c12nDef'] = classification_definition
200
+ full_alias_access = user_data['is_admin'] or CLASSIFICATION.is_accessible(user_data['classification'], CLASSIFICATION.RESTRICTED)
200
201
  user_data['classification_aliases'] = {k: v for k, v in CLASSIFICATION_ALIASES.items().items()
201
- if k in user_data['classification'] or user_data['is_admin'] or CLASSIFICATION.is_accessible(user_data['classification'], CLASSIFICATION.RESTRICTED)}
202
+ if k in user_data['classification'] or full_alias_access}
202
203
 
203
204
  # create tag-to-source lookup mapping
204
205
  external_source_tags = {}
assemblyline_ui/error.py CHANGED
@@ -37,7 +37,7 @@ def handle_401(e):
37
37
  else:
38
38
  msg = str(e)
39
39
 
40
- ip = ip_address(session.get("ip", request.remote_addr))
40
+ ip = ip_address(request.headers.get("X-Forwarded-For", request.remote_addr))
41
41
  data = {}
42
42
 
43
43
  # Check which OAuth providers are available based on IP filters
@@ -90,11 +90,14 @@ def increase_daily_submission_quota(user) -> Optional[str]:
90
90
  daily_quota = config.ui.default_quotas.daily_submissions
91
91
 
92
92
  if daily_quota != 0:
93
- current_daily_quota = DAILY_QUOTA_TRACKER.increment_submission(quota_user)
94
- flask_session['remaining_quota_submission'] = max(daily_quota - current_daily_quota, 0)
95
- if current_daily_quota > daily_quota:
96
- LOGGER.info(f"User {quota_user} exceeded their daily submission quota of {daily_quota}.")
97
- return f"You've exceeded your daily maximum submission quota of {daily_quota}"
93
+ current_daily_quota = DAILY_QUOTA_TRACKER.get_submission(quota_user)
94
+ if current_daily_quota >= daily_quota:
95
+ LOGGER.info(f"User {quota_user} reached their daily submission quota of {daily_quota}.")
96
+
97
+ return f"You've reached your daily maximum submission quota of {daily_quota}"
98
+ else:
99
+ new_daily_quota = DAILY_QUOTA_TRACKER.increment_submission(quota_user)
100
+ flask_session["remaining_quota_submission"] = max(daily_quota - new_daily_quota, 0)
98
101
 
99
102
  return None
100
103
 
@@ -121,13 +124,11 @@ def check_async_submission_quota(user) -> Optional[str]:
121
124
  return daily_submission_quota_error
122
125
 
123
126
  if max_quota != 0 and not ASYNC_SUBMISSION_TRACKER.begin(quota_user, max_quota):
124
- LOGGER.info(f"User {quota_user} exceeded their async submission quota of {max_quota}.")
125
-
126
127
  # Decrease the daily quota as we have increase it in the increase_daily_submission_quota call
127
128
  # but the user is out of concurrent async submission quotas
128
129
  release_daily_submission_quota(user)
129
-
130
- return f"You've exceeded your maximum concurrent async submission quota of {max_quota}"
130
+ LOGGER.info(f"User {quota_user} exceeded their async submission quota of {max_quota}.")
131
+ return f"You've exceeded your maximum async concurrent submission quota of {max_quota}"
131
132
 
132
133
  return None
133
134
 
@@ -135,6 +136,8 @@ def check_async_submission_quota(user) -> Optional[str]:
135
136
  def check_submission_quota(user) -> Optional[str]:
136
137
  if config.ui.enforce_quota:
137
138
  quota_user = user['uname']
139
+
140
+ # get max concurrent submission quota
138
141
  max_quota = user.get('submission_quota')
139
142
  if max_quota is None:
140
143
  max_quota = config.ui.default_quotas.concurrent_submissions
@@ -143,13 +146,13 @@ def check_submission_quota(user) -> Optional[str]:
143
146
  if daily_submission_quota_error:
144
147
  return daily_submission_quota_error
145
148
 
149
+ # if a user do have a max_quota set and number of concurrent queues are <= max quota
146
150
  if max_quota != 0 and not SUBMISSION_TRACKER.begin(quota_user, max_quota):
147
- LOGGER.info(f"User {quota_user} exceeded their submission quota of {max_quota}.")
148
151
 
149
152
  # Decrease the daily quota as we have increase it in the increase_daily_submission_quota call
150
153
  # but the user is out of concurrent submission quotas
151
154
  release_daily_submission_quota(user)
152
-
155
+ LOGGER.info(f"User {quota_user} exceeded their concurrent submission quota of {max_quota}.")
153
156
  return f"You've exceeded your maximum concurrent submission quota of {max_quota}"
154
157
 
155
158
  return None
@@ -316,15 +319,18 @@ def get_default_user_settings(user: dict) -> dict:
316
319
  settings.update({"default_zip_password": DEFAULT_ZIP_PASSWORD, "download_encoding": DOWNLOAD_ENCODING})
317
320
  return UserSettings(settings).as_primitives()
318
321
 
322
+
319
323
  def get_user_api_keys_dict(uname):
320
324
  apikeys = get_user_api_keys(uname)
321
325
  apikeys_dict = dict((apikey['key_name'], apikey) for apikey in apikeys)
322
326
  return apikeys_dict
323
327
 
328
+
324
329
  def get_user_api_keys(uname):
325
330
  apikeys = STORAGE.apikey.stream_search(f"uname:{uname}", as_obj=False)
326
331
  return apikeys
327
332
 
333
+
328
334
  def load_user_settings(user):
329
335
  default_settings = get_default_user_settings(user)
330
336
  user_classfication = user.get('classification', Classification.UNRESTRICTED)
@@ -9,7 +9,7 @@ import ldap
9
9
  import ldap.filter
10
10
  from assemblyline.common.str_utils import safe_str
11
11
  from assemblyline.odm.models.user import load_roles
12
- from flask import request, session
12
+ from flask import request
13
13
 
14
14
  from assemblyline_ui.config import CLASSIFICATION, config
15
15
  from assemblyline_ui.helper.user import (
@@ -176,7 +176,7 @@ def validate_ldapuser(username, password, storage):
176
176
  ldap_obj = BasicLDAPWrapper(config.auth.ldap)
177
177
 
178
178
  # Check if IP is allowed to use LDAP auth
179
- ip = ip_address(session.get("ip", request.remote_addr))
179
+ ip = ip_address(request.headers.get("X-Forwarded-For", request.remote_addr))
180
180
  if config.auth.ldap.ip_filter and not any(ip in ip_network(cidr) for cidr in config.auth.ldap.ip_filter):
181
181
  raise AuthenticationException(f"Access from IP {ip} is not allowed for LDAP login")
182
182
 
@@ -5,7 +5,7 @@ import elasticapm
5
5
  import jwt
6
6
  import requests
7
7
  from assemblyline.odm.models.user import load_roles_form_acls
8
- from flask import request, session
8
+ from flask import request
9
9
 
10
10
  from assemblyline_ui.config import CACHE, STORAGE, config, get_token_store
11
11
  from assemblyline_ui.helper.oauth import get_profile_identifiers
@@ -61,7 +61,7 @@ def validate_oauth_token(oauth_token, oauth_provider, return_user=False):
61
61
  raise AuthenticationException(f"oAuth provider '{oauth_provider}' does not have a jwks_uri configured.")
62
62
 
63
63
  # Check if user is allowed to use this OAuth provider from its IP
64
- ip = ip_address(session.get("ip", request.remote_addr))
64
+ ip = ip_address(request.headers.get("X-Forwarded-For", request.remote_addr))
65
65
  if oauth_provider_config.ip_filter and not any(ip in ip_network(cidr) for cidr in oauth_provider_config.ip_filter):
66
66
  raise AuthenticationException(f"Access from IP {ip} is not allowed for oAuth provider: {oauth_provider}")
67
67
 
@@ -2,7 +2,7 @@ from ipaddress import ip_address, ip_network
2
2
  from typing import Any, Optional
3
3
 
4
4
  from assemblyline.odm.models.user import ROLES, TYPES
5
- from flask import request, session
5
+ from flask import request
6
6
 
7
7
  from assemblyline_ui.config import config, get_token_store
8
8
  from assemblyline_ui.http_exceptions import AuthenticationException
@@ -14,7 +14,7 @@ def validate_saml_user(username: str, saml_token_id: str):
14
14
  raise AuthenticationException("SAML login is disabled")
15
15
 
16
16
  # Check if user is allowed to use SAML auth from its IP
17
- ip = ip_address(session.get("ip", request.remote_addr))
17
+ ip = ip_address(request.headers.get("X-Forwarded-For", request.remote_addr))
18
18
  if config.auth.saml.ip_filter and not any(ip in ip_network(cidr) for cidr in config.auth.saml.ip_filter):
19
19
  raise AuthenticationException(f"Access from IP {ip} is not allowed for SAML login")
20
20
 
@@ -2,7 +2,7 @@ from ipaddress import ip_address, ip_network
2
2
 
3
3
  import elasticapm
4
4
  from assemblyline.common.security import verify_password
5
- from flask import request, session
5
+ from flask import request
6
6
 
7
7
  from assemblyline_ui.config import config
8
8
  from assemblyline_ui.http_exceptions import AuthenticationException
@@ -14,7 +14,7 @@ def validate_userpass(username, password, storage):
14
14
  # You can overload this to pass username/password to an LDAP server for exemple
15
15
  if config.auth.internal.enabled and username and password:
16
16
  # Check if user is allowed to use internal auth from its IP
17
- ip = ip_address(session.get("ip", request.remote_addr))
17
+ ip = ip_address(request.headers.get("X-Forwarded-For", request.remote_addr))
18
18
  if config.auth.internal.ip_filter and not any(ip in ip_network(cidr) for cidr in config.auth.internal.ip_filter):
19
19
  raise AuthenticationException(f"Access from IP {ip} is not allowed for username/password login")
20
20
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: assemblyline-ui
3
- Version: 4.7.0.dev28
3
+ Version: 4.7.0.dev31
4
4
  Summary: Assemblyline 4 - API and Socket IO server
5
5
  Home-page: https://github.com/CybercentreCanada/assemblyline-ui/
6
6
  Author: CCCS Assemblyline development team
@@ -1,8 +1,8 @@
1
- assemblyline_ui/VERSION,sha256=jfq1PXUsoabJh-h4btgHCYilGIJBvL5ntE1l0aayUQc,12
1
+ assemblyline_ui/VERSION,sha256=7O8Pk4citoXgxUOZlbtxeL-RH4VRdO9u98i9s5MCt4Q,12
2
2
  assemblyline_ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  assemblyline_ui/app.py,sha256=ok96rpL0-Hb5amqa7ojhuB0boQceZG7E32NX6LZm-f4,7849
4
4
  assemblyline_ui/config.py,sha256=4M5wpG_OwJPjZAjRWIUMMyF4KG30oJidNDnFM-IVJCw,8927
5
- assemblyline_ui/error.py,sha256=7tZt46dJXAuFhHSsmQPcQ1Dc7de56p1l8JG0BbDOFr8,6009
5
+ assemblyline_ui/error.py,sha256=9XUR2DMCd-Q5NWr88LKWpr1wu2180hehJf9rY1wnyBA,6030
6
6
  assemblyline_ui/gunicorn_config.py,sha256=db1Afugkwut9mxMigRq-L1_pRgUpRiDX4KySXY4_elg,1041
7
7
  assemblyline_ui/gunicorn_config_socketio.py,sha256=WWAWzrZOw1OXEiV_nNMKf-wH6A0Ckio2juCYWu-QfAE,115
8
8
  assemblyline_ui/healthz.py,sha256=IFr2ofSddFX8pvoixMmZHSlk364oKD_vURl_GRT6J2s,777
@@ -17,7 +17,7 @@ assemblyline_ui/api/v4/alert.py,sha256=XsOATBo5TZb5lhS1h34Pna-RLAZIUpk2WK_0sJ-we
17
17
  assemblyline_ui/api/v4/apikey.py,sha256=Ots7aPK9bi5ZzAePHPezQYwvv8Q7ygQAgOHpAZ1zTqo,11794
18
18
  assemblyline_ui/api/v4/archive.py,sha256=B_aFiur04RE_oIWw-Z0r4Au9PiRb2fJZAryCQeg3YkI,25781
19
19
  assemblyline_ui/api/v4/assistant.py,sha256=tNuamWxQZ1BbtuO9YT4DOVZHtzKD178KiqAWhDg5F5A,2766
20
- assemblyline_ui/api/v4/authentication.py,sha256=-rX_ugio-ARNiSn-t0W0kduuiyENY_h8brnWpKrIS3E,41494
20
+ assemblyline_ui/api/v4/authentication.py,sha256=GN457_uLJGGBir2jA_6BIRWcoj79qOLhkmFCzH7wud0,41566
21
21
  assemblyline_ui/api/v4/badlist.py,sha256=lTqRLs8F745U0biPdC4AHimj0VUiCLcNFEae7UnjIwg,31507
22
22
  assemblyline_ui/api/v4/bundle.py,sha256=UcLUpErpiAk5LSYeC0zHDw_WpQiPcM8uhH7NwmWi4hw,5521
23
23
  assemblyline_ui/api/v4/error.py,sha256=RdpnDqM-tiFdG-Qni3-_8kn7VPlB0UW1VafUF2EHw8Q,2586
@@ -41,7 +41,7 @@ assemblyline_ui/api/v4/submission.py,sha256=WxMY00ePNdOMFXyu9j38sxpe0vT26u-Z_biM
41
41
  assemblyline_ui/api/v4/submit.py,sha256=5nfuX6Ud3FMdDGIOgBAdcb6kpMbINk750Ph5yp90O8c,18372
42
42
  assemblyline_ui/api/v4/system.py,sha256=4JhLhpmPfKzbXiHsBoJxSZP-ibu-lnmk4FrtaLExaRM,24861
43
43
  assemblyline_ui/api/v4/ui.py,sha256=J3OoLEETlFgeq7DbSlubTPebMQJOUx6UwRIt8mCBYbQ,11508
44
- assemblyline_ui/api/v4/user.py,sha256=m_xvc59imrxbRBwnNkZeH2vZbcW5smDgLIcIRVobaP0,47848
44
+ assemblyline_ui/api/v4/user.py,sha256=94yE9rq2XnWgf1N8AEHPbMWiP23yCgzFvZ1nm0Ka7f0,47890
45
45
  assemblyline_ui/api/v4/webauthn.py,sha256=ouVWMMd0aMnNV5iaKbWY1AnsUE5_BKAtaUg9j77Rvow,4875
46
46
  assemblyline_ui/api/v4/workflow.py,sha256=Uz50960KyvFDm39NKYNSq5OXT0CA0u_FO5xPP61aYiQ,10579
47
47
  assemblyline_ui/helper/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -52,7 +52,7 @@ assemblyline_ui/helper/search.py,sha256=ri3IpUEnNyzrYYIx0Eb-2lQG-42QhG1YFUDAtpMB
52
52
  assemblyline_ui/helper/service.py,sha256=NSNK25rVUpsF7ElfzWZl4Ro7VQItmEB_JbBfnhSxmwo,5176
53
53
  assemblyline_ui/helper/signature.py,sha256=PUiQk56QoY5Ye2Pg3jRNgOT2i2ZqTWkk_0dv-Bfy9vI,899
54
54
  assemblyline_ui/helper/submission.py,sha256=fZ-XuH1TkiyzPOJMUAYmcIHHXbGWANDknbeWsHQc-Ms,32632
55
- assemblyline_ui/helper/user.py,sha256=dK3JElrulX1T3yuAx9-JdaaP4BYY8ulrYA58Rm2vhZM,17212
55
+ assemblyline_ui/helper/user.py,sha256=d5umOq5GcvsIUuxjeW4_2xbzjEwoAdcSyHswpE5rCO4,17462
56
56
  assemblyline_ui/helper/ai/__init__.py,sha256=m2Nb3UgSiXNz3l6rUX17BlKwT1YLjAHn7W87SWP8e9o,1052
57
57
  assemblyline_ui/helper/ai/base.py,sha256=0aAecNUh6jxuqlNoZzZDbnPMuqZUzh5hCKt1hpdFvLg,8801
58
58
  assemblyline_ui/helper/ai/cohere.py,sha256=Er2s2m5oD0svOyV2WnELuwZLY4FtJwTZFazr5T_Yir8,7021
@@ -60,11 +60,11 @@ assemblyline_ui/helper/ai/openai.py,sha256=37MNSMiJha9SVCDGIqYGF2Y-pYjhulhvzHPuA
60
60
  assemblyline_ui/security/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
61
  assemblyline_ui/security/apikey_auth.py,sha256=-KX7Ps1XYTP7Bgv6Dn290IEMJ7UBxHFJihILMpdf9zs,2214
62
62
  assemblyline_ui/security/authenticator.py,sha256=Lra3F9HJ2PU-A9lRY5_purqkUXZ3QRbKf8mDc6Zdq4o,7911
63
- assemblyline_ui/security/ldap_auth.py,sha256=43MWtxj_EyMNEySPgIerEyyL8b8Hb2V4qhOrfF3Kn08,10085
64
- assemblyline_ui/security/oauth_auth.py,sha256=QrIFvjIGGJy-XUdluGkEPrEktzCokt3mx-nieCp3Ucg,4689
65
- assemblyline_ui/security/saml_auth.py,sha256=cjvddqnELQv8eZfmiZPPHbXPpbK0HD8ZwQTeEi55zyA,2229
63
+ assemblyline_ui/security/ldap_auth.py,sha256=xEDPA3wD_HKNqdMYenBijM_ZvP8G-CUHyGoWYiBSeP4,10097
64
+ assemblyline_ui/security/oauth_auth.py,sha256=SrPHUX6A_J9rrQsZaZDdkHQ1nn9WvbYmsjEp4gPcIaU,4701
65
+ assemblyline_ui/security/saml_auth.py,sha256=w5GAhGDJzW2VzjPhBLM6v2dfprcqSoG8TTG06msEfa8,2241
66
66
  assemblyline_ui/security/second_factor_auth.py,sha256=l3SjJ5vn3bYxkPTtKWLewbZUSWtm1REqllzZvvsh9BU,2953
67
- assemblyline_ui/security/userpass_auth.py,sha256=KLIg-VulLqeJEYyj0FlD-rLAn-SX-2A38UUqbRNSNlw,1192
67
+ assemblyline_ui/security/userpass_auth.py,sha256=vy2cwxGtz-pQ-kMMUch2sji4D-t4jreEZDv-pFamTKg,1204
68
68
  assemblyline_ui/security/utils.py,sha256=CE6H9sM8S26vrzPATuCfwZv0TA7kBs3IRajaeX1aU3Q,5920
69
69
  assemblyline_ui/sio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
70
  assemblyline_ui/sio/alert.py,sha256=aTtrkZW21igbP6UcFgo1_fXdF8RpCBlMiKsNdpwItZw,2170
@@ -74,8 +74,8 @@ assemblyline_ui/sio/live_submission.py,sha256=mS0oGO5rEA8PLa8kjBcodOG-Q0CG4SpYAo
74
74
  assemblyline_ui/sio/retrohunt.py,sha256=vlH_x6Rb4pm3GM1sNLH1C42-NVR3VoAsEfkAu3L30fY,2146
75
75
  assemblyline_ui/sio/status.py,sha256=_Bxf1KLPOJEUIk4J9_j9fzvQWUXqSIT9xnJKhT1hhuc,1980
76
76
  assemblyline_ui/sio/submission.py,sha256=IYJuGz73HK9HtYfqc-gWW8tc1lt5VZ62Qn64AaGGtm8,2222
77
- assemblyline_ui-4.7.0.dev28.dist-info/licenses/LICENCE.md,sha256=NSkYo9EH8h5oOkzg4VhjAHF4339MqPP2cQ8msTPgl-c,1396
78
- assemblyline_ui-4.7.0.dev28.dist-info/METADATA,sha256=3USQJyIt0ilZKPdl9SvyiCYFW47ysnx8Vqj6NvMcttQ,8174
79
- assemblyline_ui-4.7.0.dev28.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
80
- assemblyline_ui-4.7.0.dev28.dist-info/top_level.txt,sha256=WLa7-PKLJTbMUbKKU3q3kg5_uAV67hss5kC71PAbIeg,16
81
- assemblyline_ui-4.7.0.dev28.dist-info/RECORD,,
77
+ assemblyline_ui-4.7.0.dev31.dist-info/licenses/LICENCE.md,sha256=NSkYo9EH8h5oOkzg4VhjAHF4339MqPP2cQ8msTPgl-c,1396
78
+ assemblyline_ui-4.7.0.dev31.dist-info/METADATA,sha256=wq2fGO6OWiyvUq1a_lke4Keu3BCDQQSXljlaI7F-MTw,8174
79
+ assemblyline_ui-4.7.0.dev31.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
80
+ assemblyline_ui-4.7.0.dev31.dist-info/top_level.txt,sha256=WLa7-PKLJTbMUbKKU3q3kg5_uAV67hss5kC71PAbIeg,16
81
+ assemblyline_ui-4.7.0.dev31.dist-info/RECORD,,