diff --git a/packages/postgres-database/src/simcore_postgres_database/migration/versions/215b2cac1dbc_new_two_factor_enabled_user_column.py b/packages/postgres-database/src/simcore_postgres_database/migration/versions/215b2cac1dbc_new_two_factor_enabled_user_column.py new file mode 100644 index 00000000000..981432c75a1 --- /dev/null +++ b/packages/postgres-database/src/simcore_postgres_database/migration/versions/215b2cac1dbc_new_two_factor_enabled_user_column.py @@ -0,0 +1,35 @@ +"""new two_factor_enabled user column + +Revision ID: 215b2cac1dbc +Revises: 22404057a50c +Create Date: 2023-11-21 14:42:42.170235+00:00 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = "215b2cac1dbc" +down_revision = "22404057a50c" +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column( + "users", + sa.Column( + "two_factor_enabled", + sa.Boolean(), + server_default=sa.text("true"), + nullable=False, + ), + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column("users", "two_factor_enabled") + # ### end Alembic commands ### diff --git a/packages/postgres-database/src/simcore_postgres_database/models/users.py b/packages/postgres-database/src/simcore_postgres_database/models/users.py index 7c04800a07a..3505771f0d4 100644 --- a/packages/postgres-database/src/simcore_postgres_database/models/users.py +++ b/packages/postgres-database/src/simcore_postgres_database/models/users.py @@ -100,6 +100,14 @@ class UserStatus(Enum): nullable=True, # since 2FA can be configured optional doc="Confirmed user phone used e.g. to send a code for a two-factor-authentication", ), + sa.Column( + "two_factor_enabled", + sa.Boolean, + server_default=sa.sql.expression.true(), + nullable=False, + doc="Wheter 2FA is enabled at login by this user." + "NOTE that this is checked ONLY if application activates 2FA", + ), sa.Column("password_hash", sa.String, nullable=False), sa.Column( "primary_gid", diff --git a/services/web/server/src/simcore_service_webserver/login/handlers_auth.py b/services/web/server/src/simcore_service_webserver/login/handlers_auth.py index b18dff0ae45..bd6088a8d08 100644 --- a/services/web/server/src/simcore_service_webserver/login/handlers_auth.py +++ b/services/web/server/src/simcore_service_webserver/login/handlers_auth.py @@ -1,5 +1,4 @@ import logging -from typing import Final from aiohttp import web from aiohttp.web import RouteTableDef @@ -99,9 +98,8 @@ async def login(request: web.Request): product=product, ) - # Some roles have login privileges - has_privileges: Final[bool] = UserRole(user["role"]) > UserRole.USER - if has_privileges or not settings.LOGIN_2FA_REQUIRED: + skip_2fa = not user.get("two_factor_enabled", True) + if skip_2fa or not settings.LOGIN_2FA_REQUIRED: return await login_granted_response(request, user=user) # no phone