From f6dc504542cb4e696769fe53d7737ec950f93b3b Mon Sep 17 00:00:00 2001 From: Marc-Andrieu Date: Fri, 5 Sep 2025 23:40:47 +0200 Subject: [PATCH 01/10] Enable promo-based Piwigo groups --- app/utils/auth/providers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/utils/auth/providers.py b/app/utils/auth/providers.py index 2780ac572c..d7004b0487 100644 --- a/app/utils/auth/providers.py +++ b/app/utils/auth/providers.py @@ -176,7 +176,9 @@ def get_userinfo(self, user: models_users.CoreUser) -> dict[str, Any]: return { "sub": user.id, "name": user.full_name, - "groups": [group.name for group in user.groups] + [user.account_type.value], + "groups": [group.name for group in user.groups] + + [user.account_type.value] + + [str(user.promo)], "email": user.email, } From d5dee8b5a3d2bd556ad85e2bfcf6b6c29ca36267 Mon Sep 17 00:00:00 2001 From: Marc-Andrieu Date: Sun, 7 Sep 2025 10:21:20 +0200 Subject: [PATCH 02/10] Migration: +2000 on promos below 2000 --- migrations/versions/40_promo_above_2000.py | 102 +++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 migrations/versions/40_promo_above_2000.py diff --git a/migrations/versions/40_promo_above_2000.py b/migrations/versions/40_promo_above_2000.py new file mode 100644 index 0000000000..f3fed7a1f9 --- /dev/null +++ b/migrations/versions/40_promo_above_2000.py @@ -0,0 +1,102 @@ +"""40-promo-above-2000 + +Create Date: 2025-09-07 09:54:34.421809 +""" + +import uuid +from typing import TYPE_CHECKING, Sequence, Union + +from app.core.schools.schools_type import SchoolType + +if TYPE_CHECKING: + from pytest_alembic import MigrationContext + +import sqlalchemy as sa +from alembic import op + +from app.types.sqlalchemy import TZDateTime + +# revision identifiers, used by Alembic. +revision: str = "91fadc90f892" +down_revision: str | None = "2880c583d7f1" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + op.execute("UPDATE core_user SET promo = 2000 + promo WHERE promo < 2000") + + +def downgrade() -> None: + # we afterwards cannot distinguish those who had 2023 from 23 + pass + + +user_id_23 = str(uuid.uuid4()) +user_id_2023 = str(uuid.uuid4()) +user_id_null = str(uuid.uuid4()) + + +def pre_test_upgrade( + alembic_runner: "MigrationContext", + alembic_connection: sa.Connection, +) -> None: + alembic_runner.insert_into( + "core_user", + [ + { + "id": user_id_23, + "email": "email23", + "school_id": str(SchoolType.no_school.value), + "password_hash": "password_hash", + "account_type": "student", + "name": "name", + "firstname": "firstname", + "promo": 23, + }, + { + "id": user_id_2023, + "email": "email2023", + "school_id": str(SchoolType.no_school.value), + "password_hash": "password_hash", + "account_type": "student", + "name": "name", + "firstname": "firstname", + "promo": 2023, + }, + { + "id": user_id_null, + "email": "emailnull", + "school_id": str(SchoolType.no_school.value), + "password_hash": "password_hash", + "account_type": "student", + "name": "name", + "firstname": "firstname", + # promo is null + }, + ], + ) + + +def test_upgrade( + alembic_runner: "MigrationContext", + alembic_connection: sa.Connection, +) -> None: + assert ( + alembic_connection.execute( + sa.text(f"SELECT promo FROM core_user WHERE user_id = {user_id_23}"), + ).first()[9] + == 2023 + ) + assert ( + alembic_connection.execute( + sa.text(f"SELECT promo FROM core_user WHERE user_id = {user_id_2023}"), + ).first()[9] + == 2023 + ) + assert ( + alembic_connection.execute( + sa.text(f"SELECT promo FROM core_user WHERE user_id = {user_id_null}"), + ).first()[9] + is None + ) From 0bfa1533aa601bca7ce20395ee6bd55895f9cfb1 Mon Sep 17 00:00:00 2001 From: Marc-Andrieu Date: Sun, 7 Sep 2025 10:24:41 +0200 Subject: [PATCH 03/10] fixes migration --- migrations/versions/40_promo_above_2000.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/migrations/versions/40_promo_above_2000.py b/migrations/versions/40_promo_above_2000.py index f3fed7a1f9..d5ce71ea75 100644 --- a/migrations/versions/40_promo_above_2000.py +++ b/migrations/versions/40_promo_above_2000.py @@ -4,7 +4,8 @@ """ import uuid -from typing import TYPE_CHECKING, Sequence, Union +from collections.abc import Sequence +from typing import TYPE_CHECKING from app.core.schools.schools_type import SchoolType @@ -14,8 +15,6 @@ import sqlalchemy as sa from alembic import op -from app.types.sqlalchemy import TZDateTime - # revision identifiers, used by Alembic. revision: str = "91fadc90f892" down_revision: str | None = "2880c583d7f1" @@ -84,19 +83,19 @@ def test_upgrade( ) -> None: assert ( alembic_connection.execute( - sa.text(f"SELECT promo FROM core_user WHERE user_id = {user_id_23}"), - ).first()[9] + sa.text(f"SELECT promo FROM core_user WHERE user_id = '{user_id_23}'"), + ).first()[0] == 2023 ) assert ( alembic_connection.execute( - sa.text(f"SELECT promo FROM core_user WHERE user_id = {user_id_2023}"), - ).first()[9] + sa.text(f"SELECT promo FROM core_user WHERE user_id = '{user_id_2023}'"), + ).first()[0] == 2023 ) assert ( alembic_connection.execute( - sa.text(f"SELECT promo FROM core_user WHERE user_id = {user_id_null}"), - ).first()[9] + sa.text(f"SELECT promo FROM core_user WHERE user_id = '{user_id_null}'"), + ).first()[0] is None ) From fd39b840aa564c36604ee940ae1a6478e663a6eb Mon Sep 17 00:00:00 2001 From: Marc-Andrieu Date: Sun, 7 Sep 2025 10:28:11 +0200 Subject: [PATCH 04/10] Fix(migration): mypy --- migrations/versions/40_promo_above_2000.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migrations/versions/40_promo_above_2000.py b/migrations/versions/40_promo_above_2000.py index d5ce71ea75..126e399ea7 100644 --- a/migrations/versions/40_promo_above_2000.py +++ b/migrations/versions/40_promo_above_2000.py @@ -84,18 +84,18 @@ def test_upgrade( assert ( alembic_connection.execute( sa.text(f"SELECT promo FROM core_user WHERE user_id = '{user_id_23}'"), - ).first()[0] + ).all()[0][0] == 2023 ) assert ( alembic_connection.execute( sa.text(f"SELECT promo FROM core_user WHERE user_id = '{user_id_2023}'"), - ).first()[0] + ).all()[0][0] == 2023 ) assert ( alembic_connection.execute( sa.text(f"SELECT promo FROM core_user WHERE user_id = '{user_id_null}'"), - ).first()[0] + ).all()[0][0] is None ) From 6bd542d8a4e45fd15115169e5e75a9c566518902 Mon Sep 17 00:00:00 2001 From: Marc-Andrieu Date: Sun, 7 Sep 2025 10:53:49 +0200 Subject: [PATCH 05/10] Fix(test): column name --- migrations/versions/40_promo_above_2000.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migrations/versions/40_promo_above_2000.py b/migrations/versions/40_promo_above_2000.py index 126e399ea7..1e3b8f1f42 100644 --- a/migrations/versions/40_promo_above_2000.py +++ b/migrations/versions/40_promo_above_2000.py @@ -83,19 +83,19 @@ def test_upgrade( ) -> None: assert ( alembic_connection.execute( - sa.text(f"SELECT promo FROM core_user WHERE user_id = '{user_id_23}'"), + sa.text(f"SELECT promo FROM core_user WHERE id = '{user_id_23}'"), ).all()[0][0] == 2023 ) assert ( alembic_connection.execute( - sa.text(f"SELECT promo FROM core_user WHERE user_id = '{user_id_2023}'"), + sa.text(f"SELECT promo FROM core_user WHERE id = '{user_id_2023}'"), ).all()[0][0] == 2023 ) assert ( alembic_connection.execute( - sa.text(f"SELECT promo FROM core_user WHERE user_id = '{user_id_null}'"), + sa.text(f"SELECT promo FROM core_user WHERE id = '{user_id_null}'"), ).all()[0][0] is None ) From b98a361d3e6be53c092d6f584632090facfca567 Mon Sep 17 00:00:00 2001 From: Marc-Andrieu <146140470+Marc-Andrieu@users.noreply.github.com> Date: Mon, 15 Sep 2025 15:34:14 +0200 Subject: [PATCH 06/10] Pass promo only if exists and >=2014 --- app/utils/auth/providers.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/utils/auth/providers.py b/app/utils/auth/providers.py index d7004b0487..6f3d873894 100644 --- a/app/utils/auth/providers.py +++ b/app/utils/auth/providers.py @@ -173,12 +173,18 @@ def get_userinfo(self, user: models_users.CoreUser) -> dict[str, Any]: # For Piwigo, providing the username is sufficient. The name of the claim (here `"name"`) needs to be set in Piwigo oidc plugin configuration page. # A modified Piwigo oidc plugin allows managing groups from the oidc provider + promo = user.promo + if promo is not None: + if promo >= 2014: + promo = str(promo) + else: + promo = None return { "sub": user.id, "name": user.full_name, "groups": [group.name for group in user.groups] + [user.account_type.value] - + [str(user.promo)], + + [promo], "email": user.email, } From 161777e2c3bc8bbc69d577a12e445f83d4fc5e49 Mon Sep 17 00:00:00 2001 From: Marc-Andrieu <146140470+Marc-Andrieu@users.noreply.github.com> Date: Tue, 16 Sep 2025 00:58:10 +0200 Subject: [PATCH 07/10] Ruff --- app/utils/auth/providers.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/utils/auth/providers.py b/app/utils/auth/providers.py index 6f3d873894..cf86af85bf 100644 --- a/app/utils/auth/providers.py +++ b/app/utils/auth/providers.py @@ -175,10 +175,7 @@ def get_userinfo(self, user: models_users.CoreUser) -> dict[str, Any]: # A modified Piwigo oidc plugin allows managing groups from the oidc provider promo = user.promo if promo is not None: - if promo >= 2014: - promo = str(promo) - else: - promo = None + promo = str(promo) if promo >= 2014 else None return { "sub": user.id, "name": user.full_name, From f0aa77aebfa4e880f16c1747e2503fd8bc0b842b Mon Sep 17 00:00:00 2001 From: Marc-Andrieu <146140470+Marc-Andrieu@users.noreply.github.com> Date: Tue, 16 Sep 2025 01:04:41 +0200 Subject: [PATCH 08/10] Mypy --- app/utils/auth/providers.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/utils/auth/providers.py b/app/utils/auth/providers.py index cf86af85bf..c99f7558f0 100644 --- a/app/utils/auth/providers.py +++ b/app/utils/auth/providers.py @@ -174,14 +174,12 @@ def get_userinfo(self, user: models_users.CoreUser) -> dict[str, Any]: # For Piwigo, providing the username is sufficient. The name of the claim (here `"name"`) needs to be set in Piwigo oidc plugin configuration page. # A modified Piwigo oidc plugin allows managing groups from the oidc provider promo = user.promo - if promo is not None: - promo = str(promo) if promo >= 2014 else None return { "sub": user.id, "name": user.full_name, "groups": [group.name for group in user.groups] + [user.account_type.value] - + [promo], + + [str(promo) if promo is not None and promo >= 2014 else None], "email": user.email, } From 86885f66a736f050afd3d53ee32b567f2487e830 Mon Sep 17 00:00:00 2001 From: Marc-Andrieu <146140470+Marc-Andrieu@users.noreply.github.com> Date: Tue, 16 Sep 2025 01:14:20 +0200 Subject: [PATCH 09/10] Rebase migration --- .../{40_promo_above_2000.py => 41_promo_above_2000.py} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename migrations/versions/{40_promo_above_2000.py => 41_promo_above_2000.py} (97%) diff --git a/migrations/versions/40_promo_above_2000.py b/migrations/versions/41_promo_above_2000.py similarity index 97% rename from migrations/versions/40_promo_above_2000.py rename to migrations/versions/41_promo_above_2000.py index 1e3b8f1f42..66abaa160e 100644 --- a/migrations/versions/40_promo_above_2000.py +++ b/migrations/versions/41_promo_above_2000.py @@ -1,4 +1,4 @@ -"""40-promo-above-2000 +"""41-promo-above-2000 Create Date: 2025-09-07 09:54:34.421809 """ @@ -17,7 +17,7 @@ # revision identifiers, used by Alembic. revision: str = "91fadc90f892" -down_revision: str | None = "2880c583d7f1" +down_revision: str | None = "0f66a87dc3ce" branch_labels: str | Sequence[str] | None = None depends_on: str | Sequence[str] | None = None From 4c90dd0507f1db555cd3fc3d69dd0d4039ec7671 Mon Sep 17 00:00:00 2001 From: Marc-Andrieu <146140470+Marc-Andrieu@users.noreply.github.com> Date: Mon, 13 Oct 2025 15:14:43 +0200 Subject: [PATCH 10/10] Update migration --- .../{41_promo_above_2000.py => 43_promo_above_2000.py} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename migrations/versions/{41_promo_above_2000.py => 43_promo_above_2000.py} (97%) diff --git a/migrations/versions/41_promo_above_2000.py b/migrations/versions/43_promo_above_2000.py similarity index 97% rename from migrations/versions/41_promo_above_2000.py rename to migrations/versions/43_promo_above_2000.py index 66abaa160e..c5151ca8f0 100644 --- a/migrations/versions/41_promo_above_2000.py +++ b/migrations/versions/43_promo_above_2000.py @@ -1,4 +1,4 @@ -"""41-promo-above-2000 +"""43-promo-above-2000 Create Date: 2025-09-07 09:54:34.421809 """ @@ -17,7 +17,7 @@ # revision identifiers, used by Alembic. revision: str = "91fadc90f892" -down_revision: str | None = "0f66a87dc3ce" +down_revision: str | None = "c4812e1ab108" branch_labels: str | Sequence[str] | None = None depends_on: str | Sequence[str] | None = None