diff --git a/CHANGELOG b/CHANGELOG index d56e67fb..1b095a7b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,12 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +## [0.2.3] - 2024-10-20 + +- Add count of submissions to the Leaderboard of Hackathons. +- Fixed the password reset view to not validate the email address. (update the `django-allauth`) +- Improve Team Admin page to make it easier to adjust the team members. + ## [0.2.2] - 2024-10-03 - Refreshing after 30 seconds the Students page when status="sent". diff --git a/portal/config/settings/settings.py b/portal/config/settings/settings.py index fc5a882b..6ecef55a 100644 --- a/portal/config/settings/settings.py +++ b/portal/config/settings/settings.py @@ -213,6 +213,7 @@ "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", + "allauth.account.middleware.AccountMiddleware", ] # STORAGES @@ -597,14 +598,21 @@ class MediaRootS3Boto3Storage(S3Boto3Storage): }, }, "loggers": { - "": { + "root": { "handlers": ["console"], "level": "DEBUG", }, "parso": { - "handlers": ["console"], "level": "WARNING", - "propagate": False, + }, + "botocore": { + "level": "WARNING", + }, + "urllib3": { + "level": "WARNING", + }, + "s3transfer": { + "level": "WARNING", }, }, } diff --git a/portal/poetry.lock b/portal/poetry.lock index 9f0b275f..256f3bc3 100644 --- a/portal/poetry.lock +++ b/portal/poetry.lock @@ -650,23 +650,23 @@ bcrypt = ["bcrypt"] [[package]] name = "django-allauth" -version = "0.55.2" +version = "65.0.2" description = "Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "django-allauth-0.55.2.tar.gz", hash = "sha256:7b713c9947f1917e5c1c5a106fd6208d2c2c71435542fec6d60b01fd7bada3a8"}, + {file = "django_allauth-65.0.2.tar.gz", hash = "sha256:6b5b3a7a65b1c28078b6eb0dd234310b58a44e8addfd187dc30437b0b2bc41a5"}, ] [package.dependencies] -Django = ">=3.1" -pyjwt = {version = ">=1.7", extras = ["crypto"]} -python3-openid = ">=3.0.8" -requests = ">=2.0.0" -requests-oauthlib = ">=0.3.0" +Django = ">=4.2" [package.extras] +mfa = ["fido2 (>=1.1.2)", "qrcode (>=7.0.0)"] +openid = ["python3-openid (>=3.0.8)"] saml = ["python3-saml (>=1.15.0,<2.0.0)"] +socialaccount = ["pyjwt[crypto] (>=1.7)", "requests (>=2.0.0)", "requests-oauthlib (>=0.3.0)"] +steam = ["python3-openid (>=3.0.8)"] [[package]] name = "django-anymail" @@ -1531,22 +1531,6 @@ files = [ {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, ] -[[package]] -name = "oauthlib" -version = "3.2.2" -description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" -optional = false -python-versions = ">=3.6" -files = [ - {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, - {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, -] - -[package.extras] -rsa = ["cryptography (>=3.0.0)"] -signals = ["blinker (>=1.4.0)"] -signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] - [[package]] name = "packaging" version = "24.1" @@ -1973,26 +1957,6 @@ files = [ [package.extras] windows-terminal = ["colorama (>=0.4.6)"] -[[package]] -name = "pyjwt" -version = "2.8.0" -description = "JSON Web Token implementation in Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "PyJWT-2.8.0-py3-none-any.whl", hash = "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320"}, - {file = "PyJWT-2.8.0.tar.gz", hash = "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de"}, -] - -[package.dependencies] -cryptography = {version = ">=3.4.0", optional = true, markers = "extra == \"crypto\""} - -[package.extras] -crypto = ["cryptography (>=3.4.0)"] -dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] -docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] -tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] - [[package]] name = "pytest" version = "7.4.4" @@ -2097,24 +2061,6 @@ text-unidecode = ">=1.3" [package.extras] unidecode = ["Unidecode (>=1.1.1)"] -[[package]] -name = "python3-openid" -version = "3.2.0" -description = "OpenID support for modern servers and consumers." -optional = false -python-versions = "*" -files = [ - {file = "python3-openid-3.2.0.tar.gz", hash = "sha256:33fbf6928f401e0b790151ed2b5290b02545e8775f982485205a066f874aaeaf"}, - {file = "python3_openid-3.2.0-py3-none-any.whl", hash = "sha256:6626f771e0417486701e0b4daff762e7212e820ca5b29fcc0d05f6f8736dfa6b"}, -] - -[package.dependencies] -defusedxml = "*" - -[package.extras] -mysql = ["mysql-connector-python"] -postgresql = ["psycopg2"] - [[package]] name = "pytz" version = "2023.4" @@ -2419,24 +2365,6 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] -[[package]] -name = "requests-oauthlib" -version = "2.0.0" -description = "OAuthlib authentication support for Requests." -optional = false -python-versions = ">=3.4" -files = [ - {file = "requests-oauthlib-2.0.0.tar.gz", hash = "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9"}, - {file = "requests_oauthlib-2.0.0-py2.py3-none-any.whl", hash = "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36"}, -] - -[package.dependencies] -oauthlib = ">=3.0.0" -requests = ">=2.0.0" - -[package.extras] -rsa = ["oauthlib[signedtoken] (>=3.0.0)"] - [[package]] name = "rjsmin" version = "1.2.2" @@ -3036,4 +2964,4 @@ watchdog = ["watchdog (>=2.3)"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "6ecc53193893840486bbb7b1fd1054324ba4443bc35430dcfdf98d84380b6ed5" +content-hash = "dea91ebee7842a810fc763a08e4fcf81ec5de3f1631a09957f2729521109d8e2" diff --git a/portal/portal/hackathons/admin.py b/portal/portal/hackathons/admin.py index aa29f516..b6fedff4 100644 --- a/portal/portal/hackathons/admin.py +++ b/portal/portal/hackathons/admin.py @@ -37,6 +37,7 @@ class TeamAdmin(admin.ModelAdmin): "hackathon", ) list_filter = ("hackathon",) + filter_horizontal = ("users",) @admin.register(models.Attendance) diff --git a/portal/portal/hackathons/views.py b/portal/portal/hackathons/views.py index 15e3f31b..e4efd510 100644 --- a/portal/portal/hackathons/views.py +++ b/portal/portal/hackathons/views.py @@ -42,7 +42,11 @@ def get( "created", ): if submission.content_object not in submissions: - submissions[submission.content_object] = submission + count = models.Submission.objects.filter( + content_type=submission.content_type, + object_id=submission.object_id, + ).count() + submissions[submission.content_object] = (submission, count) context = self.get_context_data(object=self.object, submissions=submissions) diff --git a/portal/portal/templates/hackathons/leaderboard.html b/portal/portal/templates/hackathons/leaderboard.html index 040d5597..646c6ca7 100644 --- a/portal/portal/templates/hackathons/leaderboard.html +++ b/portal/portal/templates/hackathons/leaderboard.html @@ -18,6 +18,7 @@

Leaderboard

Team Name Score + Submissions @@ -28,7 +29,8 @@

Leaderboard

{{ obj.hackathon_team_id }} {{ obj.name }} - {{ submission.score|floatformat:3 }} + {{ submission.0.score|floatformat:3 }} + {{ submission.1 }} {% endfor %} diff --git a/portal/portal/users/adapters.py b/portal/portal/users/adapters.py index cbc262c2..f3ca27ce 100644 --- a/portal/portal/users/adapters.py +++ b/portal/portal/users/adapters.py @@ -36,6 +36,12 @@ def is_open_for_signup(self, request: HttpRequest): def clean_email(self, email): email = super().clean_email(email) + request = getattr(self, "request", None) + + # Skip unique email check if it's a password reset request + if request and request.path == reverse("account_reset_password"): + return email + if email and app_settings.UNIQUE_EMAIL: if EmailAddress.objects.filter(email=email).exists(): raise ValidationError( diff --git a/portal/pyproject.toml b/portal/pyproject.toml index b4c5998d..d5c20980 100644 --- a/portal/pyproject.toml +++ b/portal/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "portal" -version = "0.2.2" +version = "0.2.3" description = "LDSA Portal for running Starters Academy" authors = [ "Hugo Castilho ", @@ -35,7 +35,6 @@ crispy-bootstrap4 = "^2022.1" # Django Dependencies django = "^4.2.4" django-anymail = "^10.1" -django-allauth = "^0.55.0" django-compressor = "^4.4" django-constance = {extras = ["database"], version = "^3.1.0"} django-crispy-forms = "^2.0" @@ -43,6 +42,7 @@ django-environ = "^0.10.0" django-model-utils = "^4.3.1" django-redis = "^5.3.0" djangorestframework = "^3.14.0" +django-allauth = "^65.0.2" [tool.poetry.group.prod.dependencies] gunicorn = "^21.2.0"