diff --git a/.github/workflows/check_python_dependencies.yml b/.github/workflows/check_python_dependencies.yml index 85a4e796ce78..b691e68d4be9 100644 --- a/.github/workflows/check_python_dependencies.yml +++ b/.github/workflows/check_python_dependencies.yml @@ -14,18 +14,18 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v4 - + - name: Set up Python uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - + - name: Install repo-tools run: pip install edx-repo-tools[find_dependencies] - name: Install setuptool - run: pip install setuptools - + run: pip install setuptools + - name: Run Python script run: | find_python_dependencies \ @@ -35,6 +35,5 @@ jobs: --ignore https://github.com/edx/braze-client \ --ignore https://github.com/edx/edx-name-affirmation \ --ignore https://github.com/mitodl/edx-sga \ - --ignore https://github.com/edx/token-utils \ --ignore https://github.com/open-craft/xblock-poll - + diff --git a/cms/envs/common.py b/cms/envs/common.py index 591247388a9d..8f068a5c0072 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -2530,6 +2530,15 @@ EXAMS_SERVICE_URL = 'http://localhost:18740/api/v1' EXAMS_SERVICE_USERNAME = 'edx_exams_worker' +############## Settings for JWT token handling ############## +TOKEN_SIGNING = { + 'JWT_ISSUER': 'http://127.0.0.1:8740', + 'JWT_SIGNING_ALGORITHM': 'RS512', + 'JWT_SUPPORTED_VERSION': '1.2.0', + 'JWT_PRIVATE_SIGNING_JWK': None, + 'JWT_PUBLIC_SIGNING_JWK_SET': None, +} + FINANCIAL_REPORTS = { 'STORAGE_TYPE': 'localfs', 'BUCKET': None, diff --git a/cms/envs/test.py b/cms/envs/test.py index 49db50608858..d391ccba5e98 100644 --- a/cms/envs/test.py +++ b/cms/envs/test.py @@ -343,3 +343,34 @@ } } } + +############## Settings for JWT token handling ############## +TOKEN_SIGNING = { + 'JWT_ISSUER': 'token-test-issuer', + 'JWT_SIGNING_ALGORITHM': 'RS512', + 'JWT_SUPPORTED_VERSION': '1.2.0', + 'JWT_PRIVATE_SIGNING_JWK': '''{ + "e": "AQAB", + "d": "HIiV7KNjcdhVbpn3KT-I9n3JPf5YbGXsCIedmPqDH1d4QhBofuAqZ9zebQuxkRUpmqtYMv0Zi6ECSUqH387GYQF_XvFUFcjQRPycISd8TH0DAKaDpGr-AYNshnKiEtQpINhcP44I1AYNPCwyoxXA1fGTtmkKChsuWea7o8kytwU5xSejvh5-jiqu2SF4GEl0BEXIAPZsgbzoPIWNxgO4_RzNnWs6nJZeszcaDD0CyezVSuH9QcI6g5QFzAC_YuykSsaaFJhZ05DocBsLczShJ9Omf6PnK9xlm26I84xrEh_7x4fVmNBg3xWTLh8qOnHqGko93A1diLRCrKHOvnpvgQ", + "n": "o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ", + "q": "3T3DEtBUka7hLGdIsDlC96Uadx_q_E4Vb1cxx_4Ss_wGp1Loz3N3ZngGyInsKlmbBgLo1Ykd6T9TRvRNEWEtFSOcm2INIBoVoXk7W5RuPa8Cgq2tjQj9ziGQ08JMejrPlj3Q1wmALJr5VTfvSYBu0WkljhKNCy1KB6fCby0C9WE", + "p": "vUqzWPZnDG4IXyo-k5F0bHV0BNL_pVhQoLW7eyFHnw74IOEfSbdsMspNcPSFIrtgPsn7981qv3lN_staZ6JflKfHayjB_lvltHyZxfl0dvruShZOx1N6ykEo7YrAskC_qxUyrIvqmJ64zPW3jkuOYrFs7Ykj3zFx3Zq1H5568G0", + "kid": "token-test-sign", "kty": "RSA" + }''', + 'JWT_PUBLIC_SIGNING_JWK_SET': '''{ + "keys": [ + { + "kid":"token-test-wrong-key", + "e": "AQAB", + "kty": "RSA", + "n": "o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dffgRQLD1qf5D6sprmYfWVokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ" + }, + { + "kid":"token-test-sign", + "e": "AQAB", + "kty": "RSA", + "n": "o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ" + } + ] + }''', +} diff --git a/lms/djangoapps/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py index cdc59e48c0e6..c639708268dc 100644 --- a/lms/djangoapps/courseware/tests/test_views.py +++ b/lms/djangoapps/courseware/tests/test_views.py @@ -2933,9 +2933,9 @@ def test_render_xblock_with_course_duration_limits_in_mobile_browser(self, mock_ ) @ddt.unpack @patch.dict('django.conf.settings.FEATURES', {'ENABLE_PROCTORED_EXAMS': True}) - @patch('lms.djangoapps.courseware.views.views.unpack_token_for') + @patch('lms.djangoapps.courseware.views.views.unpack_jwt') def test_render_descendant_of_exam_gated_by_access_token(self, exam_access_token, - expected_response, _mock_token_unpack): + expected_response, _mock_unpack_jwt): """ Verify blocks inside an exam that requires token access are gated by a valid exam access JWT issued for that exam sequence. @@ -2968,7 +2968,7 @@ def test_render_descendant_of_exam_gated_by_access_token(self, exam_access_token CourseOverview.load_from_module_store(self.course.id) self.setup_user(admin=False, enroll=True, login=True) - def _mock_token_unpack_fn(token, user_id): + def _mock_unpack_jwt_fn(token, user_id): if token == 'valid-jwt-for-exam-sequence': return {'content_id': str(self.sequence.location)} elif token == 'valid-jwt-for-incorrect-sequence': @@ -2976,7 +2976,7 @@ def _mock_token_unpack_fn(token, user_id): else: raise Exception('invalid JWT') - _mock_token_unpack.side_effect = _mock_token_unpack_fn + _mock_unpack_jwt.side_effect = _mock_unpack_jwt_fn # Problem and Vertical response should be gated on access token for block in [self.problem_block, self.vertical_block]: diff --git a/lms/djangoapps/courseware/views/views.py b/lms/djangoapps/courseware/views/views.py index 6e0804db8ca0..19eabe692997 100644 --- a/lms/djangoapps/courseware/views/views.py +++ b/lms/djangoapps/courseware/views/views.py @@ -46,7 +46,6 @@ from rest_framework.decorators import api_view, throttle_classes from rest_framework.response import Response from rest_framework.throttling import UserRateThrottle -from token_utils.api import unpack_token_for from web_fragments.fragment import Fragment from xmodule.course_block import ( COURSE_VISIBILITY_PUBLIC, @@ -138,6 +137,7 @@ from openedx.core.djangoapps.zendesk_proxy.utils import create_zendesk_ticket from openedx.core.djangolib.markup import HTML, Text from openedx.core.lib.courses import get_course_by_id +from openedx.core.lib.jwt import unpack_jwt from openedx.core.lib.mobile_utils import is_request_from_mobile_app from openedx.features.course_duration_limits.access import generate_course_expired_fragment from openedx.features.course_experience import course_home_url @@ -1535,7 +1535,7 @@ def _check_sequence_exam_access(request, location): try: # unpack will validate both expiration and the requesting user matches the # token user - exam_access_unpacked = unpack_token_for(exam_access_token, request.user.id) + exam_access_unpacked = unpack_jwt(exam_access_token, request.user.id) except: # pylint: disable=bare-except log.exception(f"Failed to validate exam access token. user_id={request.user.id} location={location}") return False diff --git a/lms/envs/common.py b/lms/envs/common.py index cb7643c3668e..8c966e67f6d0 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -4311,10 +4311,12 @@ def _make_locale_paths(settings): # pylint: disable=missing-function-docstring # Exam Service EXAMS_SERVICE_URL = 'http://localhost:18740/api/v1' +############## Settings for JWT token handling ############## TOKEN_SIGNING = { 'JWT_ISSUER': 'http://127.0.0.1:8740', 'JWT_SIGNING_ALGORITHM': 'RS512', 'JWT_SUPPORTED_VERSION': '1.2.0', + 'JWT_PRIVATE_SIGNING_JWK': None, 'JWT_PUBLIC_SIGNING_JWK_SET': None, } diff --git a/lms/envs/test.py b/lms/envs/test.py index a9e8aaf9f2e2..38c12370f1c7 100644 --- a/lms/envs/test.py +++ b/lms/envs/test.py @@ -657,3 +657,35 @@ # case of new django version these values will override. if django.VERSION[0] >= 4: # for greater than django 3.2 use with schemes. CSRF_TRUSTED_ORIGINS = CSRF_TRUSTED_ORIGINS_WITH_SCHEME + + +############## Settings for JWT token handling ############## +TOKEN_SIGNING = { + 'JWT_ISSUER': 'token-test-issuer', + 'JWT_SIGNING_ALGORITHM': 'RS512', + 'JWT_SUPPORTED_VERSION': '1.2.0', + 'JWT_PRIVATE_SIGNING_JWK': '''{ + "e": "AQAB", + "d": "HIiV7KNjcdhVbpn3KT-I9n3JPf5YbGXsCIedmPqDH1d4QhBofuAqZ9zebQuxkRUpmqtYMv0Zi6ECSUqH387GYQF_XvFUFcjQRPycISd8TH0DAKaDpGr-AYNshnKiEtQpINhcP44I1AYNPCwyoxXA1fGTtmkKChsuWea7o8kytwU5xSejvh5-jiqu2SF4GEl0BEXIAPZsgbzoPIWNxgO4_RzNnWs6nJZeszcaDD0CyezVSuH9QcI6g5QFzAC_YuykSsaaFJhZ05DocBsLczShJ9Omf6PnK9xlm26I84xrEh_7x4fVmNBg3xWTLh8qOnHqGko93A1diLRCrKHOvnpvgQ", + "n": "o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ", + "q": "3T3DEtBUka7hLGdIsDlC96Uadx_q_E4Vb1cxx_4Ss_wGp1Loz3N3ZngGyInsKlmbBgLo1Ykd6T9TRvRNEWEtFSOcm2INIBoVoXk7W5RuPa8Cgq2tjQj9ziGQ08JMejrPlj3Q1wmALJr5VTfvSYBu0WkljhKNCy1KB6fCby0C9WE", + "p": "vUqzWPZnDG4IXyo-k5F0bHV0BNL_pVhQoLW7eyFHnw74IOEfSbdsMspNcPSFIrtgPsn7981qv3lN_staZ6JflKfHayjB_lvltHyZxfl0dvruShZOx1N6ykEo7YrAskC_qxUyrIvqmJ64zPW3jkuOYrFs7Ykj3zFx3Zq1H5568G0", + "kid": "token-test-sign", "kty": "RSA" + }''', + 'JWT_PUBLIC_SIGNING_JWK_SET': '''{ + "keys": [ + { + "kid":"token-test-wrong-key", + "e": "AQAB", + "kty": "RSA", + "n": "o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dffgRQLD1qf5D6sprmYfWVokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ" + }, + { + "kid":"token-test-sign", + "e": "AQAB", + "kty": "RSA", + "n": "o5cn3ljSRi6FaDEKTn0PS-oL9EFyv1pI7dRgffQLD1qf5D6sprmYfWWokSsrWig8u2y0HChSygR6Jn5KXBqQn6FpM0dDJLnWQDRXHLl3Ey1iPYgDSmOIsIGrV9ZyNCQwk03wAgWbfdBTig3QSDYD-sTNOs3pc4UD_PqAvU2nz_1SS2ZiOwOn5F6gulE1L0iE3KEUEvOIagfHNVhz0oxa_VRZILkzV-zr6R_TW1m97h4H8jXl_VJyQGyhMGGypuDrQ9_vaY_RLEulLCyY0INglHWQ7pckxBtI5q55-Vio2wgewe2_qYcGsnBGaDNbySAsvYcWRrqDiFyzrJYivodqTQ" + } + ] + }''', +} diff --git a/openedx/core/lib/jwt.py b/openedx/core/lib/jwt.py new file mode 100644 index 000000000000..47642b869560 --- /dev/null +++ b/openedx/core/lib/jwt.py @@ -0,0 +1,91 @@ +""" +JWT Token handling and signing functions. +""" + +import json +from time import time + +from django.conf import settings +from jwkest import Expired, Invalid, MissingKey, jwk +from jwkest.jws import JWS + + +def create_jwt(lms_user_id, expires_in_seconds, additional_token_claims, now=None): + """ + Produce an encoded JWT (string) indicating some temporary permission for the indicated user. + + What permission that is must be encoded in additional_claims. + Arguments: + lms_user_id (int): LMS user ID this token is being generated for + expires_in_seconds (int): Time to token expiry, specified in seconds. + additional_token_claims (dict): Additional claims to include in the token. + now(int): optional now value for testing + """ + now = now or int(time()) + + payload = { + 'lms_user_id': lms_user_id, + 'exp': now + expires_in_seconds, + 'iat': now, + 'iss': settings.TOKEN_SIGNING['JWT_ISSUER'], + 'version': settings.TOKEN_SIGNING['JWT_SUPPORTED_VERSION'], + } + payload.update(additional_token_claims) + return _encode_and_sign(payload) + + +def _encode_and_sign(payload): + """ + Encode and sign the provided payload. + + The signing key and algorithm are pulled from settings. + """ + keys = jwk.KEYS() + + serialized_keypair = json.loads(settings.TOKEN_SIGNING['JWT_PRIVATE_SIGNING_JWK']) + keys.add(serialized_keypair) + algorithm = settings.TOKEN_SIGNING['JWT_SIGNING_ALGORITHM'] + + data = json.dumps(payload) + jws = JWS(data, alg=algorithm) + return jws.sign_compact(keys=keys) + + +def unpack_jwt(token, lms_user_id, now=None): + """ + Unpack and verify an encoded JWT. + + Validate the user and expiration. + + Arguments: + token (string): The token to be unpacked and verified. + lms_user_id (int): LMS user ID this token should match with. + now (int): Optional now value for testing. + + Returns a valid, decoded json payload (string). + """ + now = now or int(time()) + payload = _unpack_and_verify(token) + + if "lms_user_id" not in payload: + raise MissingKey("LMS user id is missing") + if "exp" not in payload: + raise MissingKey("Expiration is missing") + if payload["lms_user_id"] != lms_user_id: + raise Invalid("User does not match") + if payload["exp"] < now: + raise Expired("Token is expired") + + return payload + + +def _unpack_and_verify(token): + """ + Unpack and verify the provided token. + + The signing key and algorithm are pulled from settings. + """ + keys = jwk.KEYS() + keys.load_jwks(settings.TOKEN_SIGNING['JWT_PUBLIC_SIGNING_JWK_SET']) + decoded = JWS().verify_compact(token.encode('utf-8'), keys) + return decoded diff --git a/openedx/core/lib/tests/test_jwt.py b/openedx/core/lib/tests/test_jwt.py new file mode 100644 index 000000000000..79caf0207fa1 --- /dev/null +++ b/openedx/core/lib/tests/test_jwt.py @@ -0,0 +1,126 @@ +""" +Tests for token handling +""" +import unittest + +from django.conf import settings +from jwkest import BadSignature, Expired, Invalid, MissingKey, jwk +from jwkest.jws import JWS + +from openedx.core.lib.jwt import _encode_and_sign, create_jwt, unpack_jwt + + +test_user_id = 121 +invalid_test_user_id = 120 +test_timeout = 60 +test_now = 1661432902 +test_claims = {"foo": "bar", "baz": "quux", "meaning": 42} +expected_full_token = { + "lms_user_id": test_user_id, + "iat": 1661432902, + "exp": 1661432902 + 60, + "iss": "token-test-issuer", # these lines from test_settings.py + "version": "1.2.0", # these lines from test_settings.py +} + + +class TestSign(unittest.TestCase): + """ + Tests for JWT creation and signing. + """ + + def test_create_jwt(self): + token = create_jwt(test_user_id, test_timeout, {}, test_now) + + decoded = _verify_jwt(token) + self.assertEqual(expected_full_token, decoded) + + def test_create_jwt_with_claims(self): + token = create_jwt(test_user_id, test_timeout, test_claims, test_now) + + expected_token_with_claims = expected_full_token.copy() + expected_token_with_claims.update(test_claims) + + decoded = _verify_jwt(token) + self.assertEqual(expected_token_with_claims, decoded) + + def test_malformed_token(self): + token = create_jwt(test_user_id, test_timeout, test_claims, test_now) + token = token + "a" + + expected_token_with_claims = expected_full_token.copy() + expected_token_with_claims.update(test_claims) + + with self.assertRaises(BadSignature): + _verify_jwt(token) + + +def _verify_jwt(jwt_token): + """ + Helper function which verifies the signature and decodes the token + from string back to claims form + """ + keys = jwk.KEYS() + keys.load_jwks(settings.TOKEN_SIGNING['JWT_PUBLIC_SIGNING_JWK_SET']) + decoded = JWS().verify_compact(jwt_token.encode('utf-8'), keys) + return decoded + + +class TestUnpack(unittest.TestCase): + """ + Tests for JWT unpacking. + """ + + def test_unpack_jwt(self): + token = create_jwt(test_user_id, test_timeout, {}, test_now) + decoded = unpack_jwt(token, test_user_id, test_now) + + self.assertEqual(expected_full_token, decoded) + + def test_unpack_jwt_with_claims(self): + token = create_jwt(test_user_id, test_timeout, test_claims, test_now) + + expected_token_with_claims = expected_full_token.copy() + expected_token_with_claims.update(test_claims) + + decoded = unpack_jwt(token, test_user_id, test_now) + + self.assertEqual(expected_token_with_claims, decoded) + + def test_malformed_token(self): + token = create_jwt(test_user_id, test_timeout, test_claims, test_now) + token = token + "a" + + expected_token_with_claims = expected_full_token.copy() + expected_token_with_claims.update(test_claims) + + with self.assertRaises(BadSignature): + unpack_jwt(token, test_user_id, test_now) + + def test_unpack_token_with_invalid_user(self): + token = create_jwt(invalid_test_user_id, test_timeout, {}, test_now) + + with self.assertRaises(Invalid): + unpack_jwt(token, test_user_id, test_now) + + def test_unpack_expired_token(self): + token = create_jwt(test_user_id, test_timeout, {}, test_now) + + with self.assertRaises(Expired): + unpack_jwt(token, test_user_id, test_now + test_timeout + 1) + + def test_missing_expired_lms_user_id(self): + payload = expected_full_token.copy() + del payload['lms_user_id'] + token = _encode_and_sign(payload) + + with self.assertRaises(MissingKey): + unpack_jwt(token, test_user_id, test_now) + + def test_missing_expired_key(self): + payload = expected_full_token.copy() + del payload['exp'] + token = _encode_and_sign(payload) + + with self.assertRaises(MissingKey): + unpack_jwt(token, test_user_id, test_now) diff --git a/requirements/edx-sandbox/base.txt b/requirements/edx-sandbox/base.txt index 1bd3d149f487..44dbf56601ac 100644 --- a/requirements/edx-sandbox/base.txt +++ b/requirements/edx-sandbox/base.txt @@ -75,7 +75,7 @@ random2==1.0.2 # via -r requirements/edx-sandbox/base.in regex==2024.11.6 # via nltk -scipy==1.15.0 +scipy==1.15.1 # via # -r requirements/edx-sandbox/base.in # chem diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 86431ca50e3e..e605205c28c4 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -24,7 +24,7 @@ amqp==5.3.1 # via kombu analytics-python==1.4.post1 # via -r requirements/edx/kernel.in -aniso8601==9.0.1 +aniso8601==10.0.0 # via edx-tincan-py35 annotated-types==0.7.0 # via pydantic @@ -72,20 +72,20 @@ bleach[css]==6.2.0 # xblock-poll boto==2.49.0 # via -r requirements/edx/kernel.in -boto3==1.35.93 +boto3==1.35.99 # via # -r requirements/edx/kernel.in # django-ses # fs-s3fs # ora2 -botocore==1.35.93 +botocore==1.35.99 # via # -r requirements/edx/kernel.in # boto3 # s3transfer bridgekeeper==0.9 # via -r requirements/edx/kernel.in -cachecontrol==0.14.1 +cachecontrol==0.14.2 # via firebase-admin cachetools==5.5.0 # via google-auth @@ -138,7 +138,7 @@ click-plugins==1.1.1 # via celery click-repl==0.3.0 # via celery -code-annotations==2.1.0 +code-annotations==2.2.0 # via # edx-enterprise # edx-toggles @@ -168,7 +168,7 @@ defusedxml==0.7.1 # ora2 # python3-openid # social-auth-core -django==4.2.17 +django==4.2.18 # via # -c requirements/edx/../common_constraints.txt # -c requirements/edx/../constraints.txt @@ -221,7 +221,6 @@ django==4.2.17 # edx-search # edx-submissions # edx-toggles - # edx-token-utils # edx-when # edxval # enmerkar @@ -329,7 +328,7 @@ django-sekizai==4.1.0 # via # -r requirements/edx/kernel.in # openedx-django-wiki -django-ses==4.3.1 +django-ses==4.3.2 # via -r requirements/edx/bundled.in django-simple-history==3.4.0 # via @@ -538,8 +537,6 @@ edx-toggles==5.2.0 # edxval # event-tracking # ora2 -edx-token-utils==0.2.1 - # via -r requirements/edx/kernel.in edx-when==2.5.0 # via # -r requirements/edx/kernel.in @@ -596,7 +593,7 @@ google-api-core[grpc]==2.24.0 # google-cloud-core # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.157.0 +google-api-python-client==2.159.0 # via firebase-admin google-auth==2.37.0 # via @@ -612,7 +609,7 @@ google-cloud-core==2.4.1 # via # google-cloud-firestore # google-cloud-storage -google-cloud-firestore==2.19.0 +google-cloud-firestore==2.20.0 # via firebase-admin google-cloud-storage==2.19.0 # via firebase-admin @@ -747,9 +744,9 @@ markupsafe==3.0.2 # mako # openedx-calc # xblock -maxminddb==2.6.2 +maxminddb==2.6.3 # via geoip2 -meilisearch==0.33.0 +meilisearch==0.33.1 # via # -r requirements/edx/kernel.in # edx-search @@ -759,7 +756,7 @@ monotonic==1.6 # via # analytics-python # py2neo -more-itertools==10.5.0 +more-itertools==10.6.0 # via cssutils mpmath==1.3.0 # via sympy @@ -769,7 +766,7 @@ multidict==6.1.0 # via # aiohttp # yarl -mysqlclient==2.2.6 +mysqlclient==2.2.7 # via # -r requirements/edx/kernel.in # openedx-forum @@ -816,7 +813,7 @@ openedx-django-require==2.1.0 # via -r requirements/edx/kernel.in openedx-django-wiki==2.1.0 # via -r requirements/edx/kernel.in -openedx-events==9.15.0 +openedx-events==9.15.1 # via # -r requirements/edx/kernel.in # edx-enterprise @@ -892,7 +889,7 @@ proto-plus==1.25.0 # via # google-api-core # google-cloud-firestore -protobuf==5.29.2 +protobuf==5.29.3 # via # google-api-core # google-cloud-firestore @@ -924,7 +921,7 @@ pycryptodomex==3.21.0 # edx-proctoring # lti-consumer-xblock # pyjwkest -pydantic==2.10.4 +pydantic==2.10.5 # via camel-converter pydantic-core==2.27.2 # via pydantic @@ -933,7 +930,6 @@ pygments==2.19.1 pyjwkest==1.4.2 # via # -r requirements/edx/kernel.in - # edx-token-utils # lti-consumer-xblock pyjwt[crypto]==2.10.1 # via @@ -1098,7 +1094,7 @@ s3transfer==0.10.4 # via boto3 sailthru-client==2.2.3 # via edx-ace -scipy==1.15.0 +scipy==1.15.1 # via # chem # openedx-calc @@ -1254,7 +1250,7 @@ webob==1.8.9 # xblock wheel==0.45.1 # via django-pipeline -wrapt==1.17.0 +wrapt==1.17.2 # via -r requirements/edx/kernel.in xblock[django]==5.1.0 # via diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index e328b6dcb1f2..9bbc4b3c8278 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -50,7 +50,7 @@ analytics-python==1.4.post1 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -aniso8601==9.0.1 +aniso8601==10.0.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -145,14 +145,14 @@ boto==2.49.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -boto3==1.35.93 +boto3==1.35.99 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # django-ses # fs-s3fs # ora2 -botocore==1.35.93 +botocore==1.35.99 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -166,7 +166,7 @@ build==1.2.2.post1 # via # -r requirements/edx/../pip-tools.txt # pip-tools -cachecontrol==0.14.1 +cachecontrol==0.14.2 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -268,7 +268,7 @@ click-repl==0.3.0 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # celery -code-annotations==2.1.0 +code-annotations==2.2.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -338,7 +338,7 @@ distlib==0.3.9 # via # -r requirements/edx/testing.txt # virtualenv -django==4.2.17 +django==4.2.18 # via # -c requirements/edx/../common_constraints.txt # -c requirements/edx/../constraints.txt @@ -395,7 +395,6 @@ django==4.2.17 # edx-search # edx-submissions # edx-toggles - # edx-token-utils # edx-when # edxval # enmerkar @@ -460,7 +459,7 @@ django-crum==0.7.9 # edx-rbac # edx-toggles # super-csv -django-debug-toolbar==4.4.6 +django-debug-toolbar==5.0.1 # via -r requirements/edx/development.in django-fernet-fields-v2==0.9 # via @@ -550,7 +549,7 @@ django-sekizai==4.1.0 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # openedx-django-wiki -django-ses==4.3.1 +django-ses==4.3.2 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -578,12 +577,12 @@ django-storages==1.14.3 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # edxval -django-stubs==5.1.1 +django-stubs==5.1.2 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/development.in # djangorestframework-stubs -django-stubs-ext==5.1.1 +django-stubs-ext==5.1.2 # via django-stubs django-user-tasks==3.2.0 # via @@ -845,10 +844,6 @@ edx-toggles==5.2.0 # edxval # event-tracking # ora2 -edx-token-utils==0.2.1 - # via - # -r requirements/edx/doc.txt - # -r requirements/edx/testing.txt edx-when==2.5.0 # via # -r requirements/edx/doc.txt @@ -889,7 +884,7 @@ execnet==2.1.1 # pytest-xdist factory-boy==3.3.1 # via -r requirements/edx/testing.txt -faker==33.3.0 +faker==33.3.1 # via # -r requirements/edx/testing.txt # factory-boy @@ -962,7 +957,7 @@ google-api-core[grpc]==2.24.0 # google-cloud-core # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.157.0 +google-api-python-client==2.159.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -988,7 +983,7 @@ google-cloud-core==2.4.1 # -r requirements/edx/testing.txt # google-cloud-firestore # google-cloud-storage -google-cloud-firestore==2.19.0 +google-cloud-firestore==2.20.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1243,7 +1238,7 @@ markupsafe==3.0.2 # mako # openedx-calc # xblock -maxminddb==2.6.2 +maxminddb==2.6.3 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1252,7 +1247,7 @@ mccabe==0.7.0 # via # -r requirements/edx/testing.txt # pylint -meilisearch==0.33.0 +meilisearch==0.33.1 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1273,7 +1268,7 @@ monotonic==1.6 # -r requirements/edx/testing.txt # analytics-python # py2neo -more-itertools==10.5.0 +more-itertools==10.6.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1298,7 +1293,7 @@ mypy==1.14.1 # via -r requirements/edx/development.in mypy-extensions==1.0.0 # via mypy -mysqlclient==2.2.6 +mysqlclient==2.2.7 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1373,7 +1368,7 @@ openedx-django-wiki==2.1.0 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt -openedx-events==9.15.0 +openedx-events==9.15.1 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1515,7 +1510,7 @@ proto-plus==1.25.0 # -r requirements/edx/testing.txt # google-api-core # google-cloud-firestore -protobuf==5.29.2 +protobuf==5.29.3 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1570,7 +1565,7 @@ pycryptodomex==3.21.0 # edx-proctoring # lti-consumer-xblock # pyjwkest -pydantic==2.10.4 +pydantic==2.10.5 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -1599,7 +1594,6 @@ pyjwkest==1.4.2 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt - # edx-token-utils # lti-consumer-xblock pyjwt[crypto]==2.10.1 # via @@ -1898,7 +1892,7 @@ sailthru-client==2.2.3 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # edx-ace -scipy==1.15.0 +scipy==1.15.1 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -2123,10 +2117,8 @@ types-pyyaml==6.0.12.20241230 # via # django-stubs # djangorestframework-stubs -types-requests==2.31.0.6 +types-requests==2.32.0.20241016 # via djangorestframework-stubs -types-urllib3==1.26.25.14 - # via types-requests typing-extensions==4.12.2 # via # -r requirements/edx/doc.txt @@ -2182,6 +2174,7 @@ urllib3==2.2.3 # elasticsearch # py2neo # requests + # types-requests user-util==1.1.0 # via # -r requirements/edx/doc.txt @@ -2248,7 +2241,7 @@ wheel==0.45.1 # -r requirements/edx/testing.txt # django-pipeline # pip-tools -wrapt==1.17.0 +wrapt==1.17.2 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt diff --git a/requirements/edx/doc.txt b/requirements/edx/doc.txt index 97c9de68dfd9..3223d7933c0f 100644 --- a/requirements/edx/doc.txt +++ b/requirements/edx/doc.txt @@ -35,7 +35,7 @@ amqp==5.3.1 # kombu analytics-python==1.4.post1 # via -r requirements/edx/base.txt -aniso8601==9.0.1 +aniso8601==10.0.0 # via # -r requirements/edx/base.txt # edx-tincan-py35 @@ -107,20 +107,20 @@ bleach[css]==6.2.0 # xblock-poll boto==2.49.0 # via -r requirements/edx/base.txt -boto3==1.35.93 +boto3==1.35.99 # via # -r requirements/edx/base.txt # django-ses # fs-s3fs # ora2 -botocore==1.35.93 +botocore==1.35.99 # via # -r requirements/edx/base.txt # boto3 # s3transfer bridgekeeper==0.9 # via -r requirements/edx/base.txt -cachecontrol==0.14.1 +cachecontrol==0.14.2 # via # -r requirements/edx/base.txt # firebase-admin @@ -191,7 +191,7 @@ click-repl==0.3.0 # via # -r requirements/edx/base.txt # celery -code-annotations==2.1.0 +code-annotations==2.2.0 # via # -r requirements/edx/base.txt # -r requirements/edx/doc.in @@ -227,7 +227,7 @@ defusedxml==0.7.1 # ora2 # python3-openid # social-auth-core -django==4.2.17 +django==4.2.18 # via # -c requirements/edx/../common_constraints.txt # -c requirements/edx/../constraints.txt @@ -280,7 +280,6 @@ django==4.2.17 # edx-search # edx-submissions # edx-toggles - # edx-token-utils # edx-when # edxval # enmerkar @@ -404,7 +403,7 @@ django-sekizai==4.1.0 # via # -r requirements/edx/base.txt # openedx-django-wiki -django-ses==4.3.1 +django-ses==4.3.2 # via -r requirements/edx/base.txt django-simple-history==3.4.0 # via @@ -629,8 +628,6 @@ edx-toggles==5.2.0 # edxval # event-tracking # ora2 -edx-token-utils==0.2.1 - # via -r requirements/edx/base.txt edx-when==2.5.0 # via # -r requirements/edx/base.txt @@ -704,7 +701,7 @@ google-api-core[grpc]==2.24.0 # google-cloud-core # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.157.0 +google-api-python-client==2.159.0 # via # -r requirements/edx/base.txt # firebase-admin @@ -726,7 +723,7 @@ google-cloud-core==2.4.1 # -r requirements/edx/base.txt # google-cloud-firestore # google-cloud-storage -google-cloud-firestore==2.19.0 +google-cloud-firestore==2.20.0 # via # -r requirements/edx/base.txt # firebase-admin @@ -905,11 +902,11 @@ markupsafe==3.0.2 # mako # openedx-calc # xblock -maxminddb==2.6.2 +maxminddb==2.6.3 # via # -r requirements/edx/base.txt # geoip2 -meilisearch==0.33.0 +meilisearch==0.33.1 # via # -r requirements/edx/base.txt # edx-search @@ -922,7 +919,7 @@ monotonic==1.6 # -r requirements/edx/base.txt # analytics-python # py2neo -more-itertools==10.5.0 +more-itertools==10.6.0 # via # -r requirements/edx/base.txt # cssutils @@ -939,7 +936,7 @@ multidict==6.1.0 # -r requirements/edx/base.txt # aiohttp # yarl -mysqlclient==2.2.6 +mysqlclient==2.2.7 # via # -r requirements/edx/base.txt # openedx-forum @@ -993,7 +990,7 @@ openedx-django-require==2.1.0 # via -r requirements/edx/base.txt openedx-django-wiki==2.1.0 # via -r requirements/edx/base.txt -openedx-events==9.15.0 +openedx-events==9.15.1 # via # -r requirements/edx/base.txt # edx-enterprise @@ -1090,7 +1087,7 @@ proto-plus==1.25.0 # -r requirements/edx/base.txt # google-api-core # google-cloud-firestore -protobuf==5.29.2 +protobuf==5.29.3 # via # -r requirements/edx/base.txt # google-api-core @@ -1128,7 +1125,7 @@ pycryptodomex==3.21.0 # edx-proctoring # lti-consumer-xblock # pyjwkest -pydantic==2.10.4 +pydantic==2.10.5 # via # -r requirements/edx/base.txt # camel-converter @@ -1149,7 +1146,6 @@ pygments==2.19.1 pyjwkest==1.4.2 # via # -r requirements/edx/base.txt - # edx-token-utils # lti-consumer-xblock pyjwt[crypto]==2.10.1 # via @@ -1341,7 +1337,7 @@ sailthru-client==2.2.3 # via # -r requirements/edx/base.txt # edx-ace -scipy==1.15.0 +scipy==1.15.1 # via # -r requirements/edx/base.txt # chem @@ -1579,7 +1575,7 @@ wheel==0.45.1 # via # -r requirements/edx/base.txt # django-pipeline -wrapt==1.17.0 +wrapt==1.17.2 # via # -r requirements/edx/base.txt # astroid diff --git a/requirements/edx/kernel.in b/requirements/edx/kernel.in index d1a132778133..a17b9db4c868 100644 --- a/requirements/edx/kernel.in +++ b/requirements/edx/kernel.in @@ -84,7 +84,6 @@ edx-rest-api-client edx-search edx-submissions edx-toggles # Feature toggles management -edx-token-utils # Validate exam access tokens edx-when edxval event-tracking diff --git a/requirements/edx/semgrep.txt b/requirements/edx/semgrep.txt index d7386250db56..4114970e9173 100644 --- a/requirements/edx/semgrep.txt +++ b/requirements/edx/semgrep.txt @@ -116,7 +116,7 @@ ruamel-yaml==0.18.10 # via semgrep ruamel-yaml-clib==0.2.12 # via ruamel-yaml -semgrep==1.101.0 +semgrep==1.102.0 # via -r requirements/edx/semgrep.in tomli==2.0.2 # via semgrep @@ -131,7 +131,7 @@ urllib3==2.2.3 # semgrep wcmatch==8.5.2 # via semgrep -wrapt==1.17.0 +wrapt==1.17.2 # via # deprecated # opentelemetry-instrumentation diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 5e99738b3cc8..3a5d13c088ca 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -31,7 +31,7 @@ amqp==5.3.1 # kombu analytics-python==1.4.post1 # via -r requirements/edx/base.txt -aniso8601==9.0.1 +aniso8601==10.0.0 # via # -r requirements/edx/base.txt # edx-tincan-py35 @@ -104,20 +104,20 @@ bleach[css]==6.2.0 # xblock-poll boto==2.49.0 # via -r requirements/edx/base.txt -boto3==1.35.93 +boto3==1.35.99 # via # -r requirements/edx/base.txt # django-ses # fs-s3fs # ora2 -botocore==1.35.93 +botocore==1.35.99 # via # -r requirements/edx/base.txt # boto3 # s3transfer bridgekeeper==0.9 # via -r requirements/edx/base.txt -cachecontrol==0.14.1 +cachecontrol==0.14.2 # via # -r requirements/edx/base.txt # firebase-admin @@ -200,7 +200,7 @@ click-repl==0.3.0 # via # -r requirements/edx/base.txt # celery -code-annotations==2.1.0 +code-annotations==2.2.0 # via # -r requirements/edx/base.txt # -r requirements/edx/testing.in @@ -253,7 +253,7 @@ dill==0.3.9 # via pylint distlib==0.3.9 # via virtualenv -django==4.2.17 +django==4.2.18 # via # -c requirements/edx/../common_constraints.txt # -c requirements/edx/../constraints.txt @@ -306,7 +306,6 @@ django==4.2.17 # edx-search # edx-submissions # edx-toggles - # edx-token-utils # edx-when # edxval # enmerkar @@ -430,7 +429,7 @@ django-sekizai==4.1.0 # via # -r requirements/edx/base.txt # openedx-django-wiki -django-ses==4.3.1 +django-ses==4.3.2 # via -r requirements/edx/base.txt django-simple-history==3.4.0 # via @@ -652,8 +651,6 @@ edx-toggles==5.2.0 # edxval # event-tracking # ora2 -edx-token-utils==0.2.1 - # via -r requirements/edx/base.txt edx-when==2.5.0 # via # -r requirements/edx/base.txt @@ -684,7 +681,7 @@ execnet==2.1.1 # via pytest-xdist factory-boy==3.3.1 # via -r requirements/edx/testing.in -faker==33.3.0 +faker==33.3.1 # via factory-boy fastapi==0.115.6 # via pact-python @@ -735,7 +732,7 @@ google-api-core[grpc]==2.24.0 # google-cloud-core # google-cloud-firestore # google-cloud-storage -google-api-python-client==2.157.0 +google-api-python-client==2.159.0 # via # -r requirements/edx/base.txt # firebase-admin @@ -757,7 +754,7 @@ google-cloud-core==2.4.1 # -r requirements/edx/base.txt # google-cloud-firestore # google-cloud-storage -google-cloud-firestore==2.19.0 +google-cloud-firestore==2.20.0 # via # -r requirements/edx/base.txt # firebase-admin @@ -950,13 +947,13 @@ markupsafe==3.0.2 # mako # openedx-calc # xblock -maxminddb==2.6.2 +maxminddb==2.6.3 # via # -r requirements/edx/base.txt # geoip2 mccabe==0.7.0 # via pylint -meilisearch==0.33.0 +meilisearch==0.33.1 # via # -r requirements/edx/base.txt # edx-search @@ -969,7 +966,7 @@ monotonic==1.6 # -r requirements/edx/base.txt # analytics-python # py2neo -more-itertools==10.5.0 +more-itertools==10.6.0 # via # -r requirements/edx/base.txt # cssutils @@ -986,7 +983,7 @@ multidict==6.1.0 # -r requirements/edx/base.txt # aiohttp # yarl -mysqlclient==2.2.6 +mysqlclient==2.2.7 # via # -r requirements/edx/base.txt # openedx-forum @@ -1040,7 +1037,7 @@ openedx-django-require==2.1.0 # via -r requirements/edx/base.txt openedx-django-wiki==2.1.0 # via -r requirements/edx/base.txt -openedx-events==9.15.0 +openedx-events==9.15.1 # via # -r requirements/edx/base.txt # edx-enterprise @@ -1149,7 +1146,7 @@ proto-plus==1.25.0 # -r requirements/edx/base.txt # google-api-core # google-cloud-firestore -protobuf==5.29.2 +protobuf==5.29.3 # via # -r requirements/edx/base.txt # google-api-core @@ -1195,7 +1192,7 @@ pycryptodomex==3.21.0 # edx-proctoring # lti-consumer-xblock # pyjwkest -pydantic==2.10.4 +pydantic==2.10.5 # via # -r requirements/edx/base.txt # camel-converter @@ -1213,7 +1210,6 @@ pygments==2.19.1 pyjwkest==1.4.2 # via # -r requirements/edx/base.txt - # edx-token-utils # lti-consumer-xblock pyjwt[crypto]==2.10.1 # via @@ -1454,7 +1450,7 @@ sailthru-client==2.2.3 # via # -r requirements/edx/base.txt # edx-ace -scipy==1.15.0 +scipy==1.15.1 # via # -r requirements/edx/base.txt # chem @@ -1669,7 +1665,7 @@ wheel==0.45.1 # via # -r requirements/edx/base.txt # django-pipeline -wrapt==1.17.0 +wrapt==1.17.2 # via # -r requirements/edx/base.txt # astroid diff --git a/requirements/pip.txt b/requirements/pip.txt index ea16b6b4de8b..de73c8cb9586 100644 --- a/requirements/pip.txt +++ b/requirements/pip.txt @@ -12,5 +12,5 @@ pip==24.2 # via # -c requirements/common_constraints.txt # -r requirements/pip.in -setuptools==75.7.0 +setuptools==75.8.0 # via -r requirements/pip.in diff --git a/scripts/user_retirement/requirements/base.txt b/scripts/user_retirement/requirements/base.txt index 56fe29b90dc3..1aaae8c9255c 100644 --- a/scripts/user_retirement/requirements/base.txt +++ b/scripts/user_retirement/requirements/base.txt @@ -10,9 +10,9 @@ attrs==24.3.0 # via zeep backoff==2.2.1 # via -r scripts/user_retirement/requirements/base.in -boto3==1.35.93 +boto3==1.35.99 # via -r scripts/user_retirement/requirements/base.in -botocore==1.35.93 +botocore==1.35.99 # via # boto3 # s3transfer @@ -35,7 +35,7 @@ click==8.1.6 # edx-django-utils cryptography==44.0.0 # via pyjwt -django==4.2.17 +django==4.2.18 # via # -c scripts/user_retirement/requirements/../../../requirements/common_constraints.txt # -c scripts/user_retirement/requirements/../../../requirements/constraints.txt @@ -52,7 +52,7 @@ edx-rest-api-client==6.0.0 # via -r scripts/user_retirement/requirements/base.in google-api-core==2.24.0 # via google-api-python-client -google-api-python-client==2.157.0 +google-api-python-client==2.159.0 # via -r scripts/user_retirement/requirements/base.in google-auth==2.37.0 # via @@ -79,7 +79,7 @@ jmespath==1.0.1 # botocore lxml==5.3.0 # via zeep -more-itertools==10.5.0 +more-itertools==10.6.0 # via simple-salesforce newrelic==10.4.0 # via edx-django-utils @@ -89,7 +89,7 @@ platformdirs==4.3.6 # via zeep proto-plus==1.25.0 # via google-api-core -protobuf==5.29.2 +protobuf==5.29.3 # via # google-api-core # googleapis-common-protos diff --git a/scripts/user_retirement/requirements/testing.txt b/scripts/user_retirement/requirements/testing.txt index e63881b77cac..77238bc89033 100644 --- a/scripts/user_retirement/requirements/testing.txt +++ b/scripts/user_retirement/requirements/testing.txt @@ -14,11 +14,11 @@ attrs==24.3.0 # zeep backoff==2.2.1 # via -r scripts/user_retirement/requirements/base.txt -boto3==1.35.93 +boto3==1.35.99 # via # -r scripts/user_retirement/requirements/base.txt # moto -botocore==1.35.93 +botocore==1.35.99 # via # -r scripts/user_retirement/requirements/base.txt # boto3 @@ -52,7 +52,7 @@ cryptography==44.0.0 # pyjwt ddt==1.7.2 # via -r scripts/user_retirement/requirements/testing.in -django==4.2.17 +django==4.2.18 # via # -r scripts/user_retirement/requirements/base.txt # django-crum @@ -76,7 +76,7 @@ google-api-core==2.24.0 # via # -r scripts/user_retirement/requirements/base.txt # google-api-python-client -google-api-python-client==2.157.0 +google-api-python-client==2.159.0 # via -r scripts/user_retirement/requirements/base.txt google-auth==2.37.0 # via @@ -126,7 +126,7 @@ markupsafe==3.0.2 # werkzeug mock==5.1.0 # via -r scripts/user_retirement/requirements/testing.in -more-itertools==10.5.0 +more-itertools==10.6.0 # via # -r scripts/user_retirement/requirements/base.txt # simple-salesforce @@ -152,7 +152,7 @@ proto-plus==1.25.0 # via # -r scripts/user_retirement/requirements/base.txt # google-api-core -protobuf==5.29.2 +protobuf==5.29.3 # via # -r scripts/user_retirement/requirements/base.txt # google-api-core @@ -227,7 +227,7 @@ requests-toolbelt==1.0.0 # via # -r scripts/user_retirement/requirements/base.txt # zeep -responses==0.25.3 +responses==0.25.6 # via # -r scripts/user_retirement/requirements/testing.in # moto