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 +1 -1
- assemblyline_ui/api/v4/authentication.py +2 -2
- assemblyline_ui/api/v4/user.py +2 -1
- assemblyline_ui/error.py +1 -1
- assemblyline_ui/helper/user.py +17 -11
- assemblyline_ui/security/ldap_auth.py +2 -2
- assemblyline_ui/security/oauth_auth.py +2 -2
- assemblyline_ui/security/saml_auth.py +2 -2
- assemblyline_ui/security/userpass_auth.py +2 -2
- {assemblyline_ui-4.7.0.dev28.dist-info → assemblyline_ui-4.7.0.dev31.dist-info}/METADATA +1 -1
- {assemblyline_ui-4.7.0.dev28.dist-info → assemblyline_ui-4.7.0.dev31.dist-info}/RECORD +14 -14
- {assemblyline_ui-4.7.0.dev28.dist-info → assemblyline_ui-4.7.0.dev31.dist-info}/WHEEL +0 -0
- {assemblyline_ui-4.7.0.dev28.dist-info → assemblyline_ui-4.7.0.dev31.dist-info}/licenses/LICENCE.md +0 -0
- {assemblyline_ui-4.7.0.dev28.dist-info → assemblyline_ui-4.7.0.dev31.dist-info}/top_level.txt +0 -0
assemblyline_ui/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
4.7.0.
|
|
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,
|
|
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,
|
|
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
|
assemblyline_ui/api/v4/user.py
CHANGED
|
@@ -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
|
|
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(
|
|
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
|
assemblyline_ui/helper/user.py
CHANGED
|
@@ -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.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return f"You've
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
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,8 +1,8 @@
|
|
|
1
|
-
assemblyline_ui/VERSION,sha256=
|
|
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=
|
|
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
|
|
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=
|
|
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=
|
|
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=
|
|
64
|
-
assemblyline_ui/security/oauth_auth.py,sha256=
|
|
65
|
-
assemblyline_ui/security/saml_auth.py,sha256=
|
|
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=
|
|
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.
|
|
78
|
-
assemblyline_ui-4.7.0.
|
|
79
|
-
assemblyline_ui-4.7.0.
|
|
80
|
-
assemblyline_ui-4.7.0.
|
|
81
|
-
assemblyline_ui-4.7.0.
|
|
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,,
|
|
File without changes
|
{assemblyline_ui-4.7.0.dev28.dist-info → assemblyline_ui-4.7.0.dev31.dist-info}/licenses/LICENCE.md
RENAMED
|
File without changes
|
{assemblyline_ui-4.7.0.dev28.dist-info → assemblyline_ui-4.7.0.dev31.dist-info}/top_level.txt
RENAMED
|
File without changes
|