From 2a2ca5d0027d906035fec4efa8a4917427fb154a Mon Sep 17 00:00:00 2001 From: taoky Date: Tue, 29 Apr 2025 20:23:54 +0800 Subject: [PATCH 1/4] Remove aliyunsdkcore --- frontend/auth_providers/sms.py | 29 +---------------------------- requirements-manual.txt | 1 - requirements.txt | 19 +++++++++---------- 3 files changed, 10 insertions(+), 39 deletions(-) diff --git a/frontend/auth_providers/sms.py b/frontend/auth_providers/sms.py index f88182d..2e1edc2 100644 --- a/frontend/auth_providers/sms.py +++ b/frontend/auth_providers/sms.py @@ -1,22 +1,9 @@ -import json - -from django.conf import settings from django.core.validators import RegexValidator from django.shortcuts import redirect from django.urls import path -import aliyunsdkcore.acs_exception.exceptions -import aliyunsdkcore.client -import aliyunsdkcore.request - from .base import BaseLoginView, BaseGetCodeView -client = aliyunsdkcore.client.AcsClient( - settings.SMS_ACCESS_KEY_ID, - settings.SMS_ACCESS_KEY_SECRET, - 'default', -) - class LoginView(BaseLoginView): template_name = 'login_sms.html' @@ -34,21 +21,7 @@ class GetCodeView(BaseGetCodeView): validate_identity = RegexValidator(r'^1[0-9]{10}$', '手机号码格式错误') def send(self, identity, code): - request = aliyunsdkcore.request.CommonRequest() - request.set_accept_format('json') - request.set_domain('dysmsapi.aliyuncs.com') - request.set_method('POST') - request.set_protocol_type('https') - request.set_version('2017-05-25') - request.set_action_name('SendSms') - request.add_query_param('RegionId', 'default') - request.add_query_param('PhoneNumbers', identity) - request.add_query_param('SignName', 'Hackergame') - request.add_query_param('TemplateCode', 'SMS_168560438') - request.add_query_param('TemplateParam', json.dumps({'code': code})) - response = json.loads(client.do_action_with_exception(request)) - if response['Code'] != 'OK': - raise ValueError(response['Code']) + raise ValueError("短信登录暂不可用,请使用其他方式注册。") urlpatterns = [ diff --git a/requirements-manual.txt b/requirements-manual.txt index 0581b02..c554036 100644 --- a/requirements-manual.txt +++ b/requirements-manual.txt @@ -1,6 +1,5 @@ # Packages used directly # requirements.txt should be generated by `pip freeze > requirements.txt`. -aliyun-python-sdk-core==2.15.2 Django==4.2.20 asgiref==3.7.2 django-allauth==65.0.2 diff --git a/requirements.txt b/requirements.txt index 49d9717..49dc198 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,15 +1,13 @@ -aliyun-python-sdk-core==2.15.2 asgiref==3.7.2 -certifi==2024.8.30 +certifi==2025.4.26 cffi==1.17.1 -charset-normalizer==3.3.2 -cryptography==43.0.1 +charset-normalizer==3.4.1 +cryptography==43.0.3 Django==4.2.20 django-allauth==65.0.2 gevent==24.11.1 -greenlet==3.1.1 +greenlet==3.2.1 idna==3.10 -jmespath==0.10.0 Markdown==3.7 psycopg==3.2.3 psycopg-binary==3.2.3 @@ -22,9 +20,10 @@ pymemcache==4.0.0 pyOpenSSL==24.2.1 PyYAML==6.0.2 requests==2.32.3 -sqlparse==0.5.1 -typing_extensions==4.12.2 -urllib3==2.2.3 +setuptools==80.0.0 +sqlparse==0.5.3 +typing_extensions==4.13.2 +urllib3==2.4.0 uWSGI==2.0.28 zope.event==5.0 -zope.interface==7.0.3 +zope.interface==7.2 From 35e1847d09f9116239607ae0f4226635cd47a80a Mon Sep 17 00:00:00 2001 From: taoky Date: Tue, 29 Apr 2025 20:32:42 +0800 Subject: [PATCH 2/4] Upgrade pyOpenSSL and cryptography --- requirements-manual.txt | 3 ++- requirements.txt | 4 ++-- server/user/interface.py | 16 +++++++++++----- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/requirements-manual.txt b/requirements-manual.txt index c554036..6072212 100644 --- a/requirements-manual.txt +++ b/requirements-manual.txt @@ -3,6 +3,7 @@ Django==4.2.20 asgiref==3.7.2 django-allauth==65.0.2 +cryptography==44.0.1 gevent==24.11.1 Markdown==3.7 psycopg==3.2.3 @@ -11,7 +12,7 @@ psycopg-pool==3.2.3 pycryptodome==3.21.0 pygments==2.18.0 pymemcache==4.0.0 -pyOpenSSL==24.2.1 +pyOpenSSL==24.3.0 PyYAML==6.0.2 requests==2.32.3 uWSGI==2.0.28 diff --git a/requirements.txt b/requirements.txt index 49dc198..afe6022 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ asgiref==3.7.2 certifi==2025.4.26 cffi==1.17.1 charset-normalizer==3.4.1 -cryptography==43.0.3 +cryptography==44.0.1 Django==4.2.20 django-allauth==65.0.2 gevent==24.11.1 @@ -17,7 +17,7 @@ pycryptodome==3.21.0 Pygments==2.18.0 PyJWT==2.9.0 pymemcache==4.0.0 -pyOpenSSL==24.2.1 +pyOpenSSL==24.3.0 PyYAML==6.0.2 requests==2.32.3 setuptools==80.0.0 diff --git a/server/user/interface.py b/server/user/interface.py index 1c11ee1..874a4ef 100644 --- a/server/user/interface.py +++ b/server/user/interface.py @@ -1,5 +1,6 @@ import base64 -import OpenSSL +from cryptography.hazmat.primitives import serialization, hashes +from cryptography.hazmat.primitives.asymmetric import padding from hashlib import sha256 from uuid import uuid4 @@ -116,8 +117,10 @@ class User: 'aff': RegexValidator(r'^.{1,100}$', '了解比赛的渠道格式错误'), 'suspicious_reason': None, } - _private_key = OpenSSL.crypto.load_privatekey( - OpenSSL.crypto.FILETYPE_PEM, settings.PRIVATE_KEY) + _private_key = serialization.load_pem_private_key( + settings.PRIVATE_KEY.encode(), + password=None, + ) def __init__(self, context, obj: models.User): self._context = context @@ -154,8 +157,11 @@ def create(cls, context, group, user=None, **kwargs): user = get_user_model().objects.create_user(str(uuid4())) self = cls(context, models.User(user=user.pk)) pk = str(user.pk) - sig = base64.b64encode(OpenSSL.crypto.sign( - self._private_key, pk.encode(), 'sha256')).decode() + sig = base64.b64encode(self._private_key.sign( + pk.encode(), + padding.PKCS1v15(), + hashes.SHA256() + )).decode() self._obj.token = pk + ':' + sig try: server.trigger.interface.Trigger.test_can_update_profile(context) From 015b22b4e48d30adaad4002d4c1e81274bebfec6 Mon Sep 17 00:00:00 2001 From: taoky Date: Tue, 29 Apr 2025 20:44:07 +0800 Subject: [PATCH 3/4] try fix sign --- server/user/interface.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/server/user/interface.py b/server/user/interface.py index 874a4ef..cef45a2 100644 --- a/server/user/interface.py +++ b/server/user/interface.py @@ -1,6 +1,6 @@ import base64 from cryptography.hazmat.primitives import serialization, hashes -from cryptography.hazmat.primitives.asymmetric import padding +from cryptography.hazmat.primitives.asymmetric import ec from hashlib import sha256 from uuid import uuid4 @@ -159,8 +159,7 @@ def create(cls, context, group, user=None, **kwargs): pk = str(user.pk) sig = base64.b64encode(self._private_key.sign( pk.encode(), - padding.PKCS1v15(), - hashes.SHA256() + ec.ECDSA(hashes.SHA256()) )).decode() self._obj.token = pk + ':' + sig try: From 555206eb82df777fd9f36fa0897e6a33dadfce15 Mon Sep 17 00:00:00 2001 From: taoky Date: Tue, 29 Apr 2025 20:45:01 +0800 Subject: [PATCH 4/4] fix testcase for newer Python --- frontend/tests/auth_test.py | 6 +++--- frontend/tests/command_test.py | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/frontend/tests/auth_test.py b/frontend/tests/auth_test.py index eb7c657..a9b189e 100644 --- a/frontend/tests/auth_test.py +++ b/frontend/tests/auth_test.py @@ -110,14 +110,14 @@ def test_ustc(self): self.c.logout() resp = self.c.get("/accounts/ustc/login/", {"ticket": "ST-1234567890"}) self.assertRedirects(resp, reverse("hub"), target_status_code=302) - self.assert_(auth.get_user(self.c).is_authenticated) + self.assertTrue(auth.get_user(self.c).is_authenticated) @mock.patch("frontend.auth_providers.cas.urlopen", new=mock_urlopen) def test_sustech(self): self.c.logout() resp = self.c.get("/accounts/sustech/login/", {"ticket": "ST-1234567890"}) self.assertRedirects(resp, reverse("hub"), target_status_code=302) - self.assert_(auth.get_user(self.c).is_authenticated) + self.assertTrue(auth.get_user(self.c).is_authenticated) class AccountLogViewPermission(TestCase): @@ -141,7 +141,7 @@ def test_low_privilege(self): # get a ustc account self.c.logout() resp = self.c.get("/accounts/sustech/login/", {"ticket": "ST-1234567890"}) - self.assert_(auth.get_user(self.c).is_authenticated) + self.assertTrue(auth.get_user(self.c).is_authenticated) resp = self.c.post( reverse("account"), data=json.dumps({"method": "accountlog", "user": self.u.pk}), diff --git a/frontend/tests/command_test.py b/frontend/tests/command_test.py index 1edcb7c..2f020d8 100644 --- a/frontend/tests/command_test.py +++ b/frontend/tests/command_test.py @@ -96,16 +96,16 @@ def test_import(self): context = Context(elevated=True) challenges = {i.name: i for i in Challenge.get_all(context)} keys = challenges.keys() - self.assert_("示例题目 1" not in keys) - self.assert_("示例题目 2" in keys) - self.assert_("示例题目 3" in keys) + self.assertTrue("示例题目 1" not in keys) + self.assertTrue("示例题目 2" in keys) + self.assertTrue("示例题目 3" in keys) c2 = challenges["示例题目 2"] c3 = challenges["示例题目 3"] - self.assert_(c2.url_orig.endswith("/example.txt")) + self.assertTrue(c2.url_orig.endswith("/example.txt")) self.assertEqual(c3.url_orig, "http://example.com/?token={token}") self.assertEqual(c2.check_url_clicked, False) self.assertEqual(c3.check_url_clicked, True) - self.assert_("codehilite" in c3.detail) + self.assertTrue("codehilite" in c3.detail) flag1 = c2.flags[0] self.assertEqual(flag1["type"], "expr") self.assertEqual("flag{2=2, 1:14}", expr_flag(flag1["flag"], "1:14"))