From 31757da7e611666be48b92e4196de4d31cbc64d7 Mon Sep 17 00:00:00 2001 From: pakelley Date: Wed, 26 Feb 2025 10:44:25 -0800 Subject: [PATCH] chore: remove jwt token ff --- label_studio/jwt_auth/auth.py | 4 +--- label_studio/jwt_auth/middleware.py | 6 +----- label_studio/organizations/functions.py | 14 +++++--------- label_studio/tests/jwt_auth/test_auth.py | 4 ---- label_studio/tests/jwt_auth/test_middleware.py | 9 --------- label_studio/tests/jwt_auth/test_models.py | 7 ------- label_studio/tests/jwt_auth/test_views.py | 6 ------ .../Organization/PeoplePage/PeoplePage.jsx | 6 ++++-- web/apps/labelstudio/src/pages/index.js | 10 ++++++---- web/libs/core/src/lib/utils/feature-flags.ts | 3 --- .../pages/AccountSettings/sections/index.tsx | 18 ++++++++---------- 11 files changed, 25 insertions(+), 62 deletions(-) diff --git a/label_studio/jwt_auth/auth.py b/label_studio/jwt_auth/auth.py index bd1f483483e9..692aca03769a 100644 --- a/label_studio/jwt_auth/auth.py +++ b/label_studio/jwt_auth/auth.py @@ -13,11 +13,9 @@ class TokenAuthenticationPhaseout(TokenAuthentication): def authenticate(self, request): """Authenticate the request and log if successful.""" - from core.feature_flags import flag_set auth_result = super().authenticate(request) - JWT_ACCESS_TOKEN_ENABLED = flag_set('fflag__feature_develop__prompts__dia_1829_jwt_token_auth') - if JWT_ACCESS_TOKEN_ENABLED and (auth_result is not None): + if auth_result is not None: user, _ = auth_result org = user.active_organization org_id = org.id if org else None diff --git a/label_studio/jwt_auth/middleware.py b/label_studio/jwt_auth/middleware.py index 3553ef1f9d04..b3e9db83ae3a 100644 --- a/label_studio/jwt_auth/middleware.py +++ b/label_studio/jwt_auth/middleware.py @@ -14,7 +14,6 @@ def __init__(self, get_response): self.get_response = get_response def __call__(self, request): - from core.feature_flags import flag_set from rest_framework_simplejwt.authentication import JWTAuthentication from rest_framework_simplejwt.exceptions import AuthenticationFailed, InvalidToken, TokenError @@ -22,10 +21,7 @@ def __call__(self, request): user_and_token = JWTAuthentication().authenticate(request) if user_and_token: user = User.objects.get(pk=user_and_token[0].pk) - JWT_ACCESS_TOKEN_ENABLED = flag_set( - 'fflag__feature_develop__prompts__dia_1829_jwt_token_auth', user=user - ) - if JWT_ACCESS_TOKEN_ENABLED and user.active_organization.jwt.api_tokens_enabled: + if user.active_organization.jwt.api_tokens_enabled: request.user = user request.is_jwt = True except User.DoesNotExist: diff --git a/label_studio/organizations/functions.py b/label_studio/organizations/functions.py index f70c81d6c1e9..8226030befda 100644 --- a/label_studio/organizations/functions.py +++ b/label_studio/organizations/functions.py @@ -5,19 +5,15 @@ def create_organization(title, created_by, **kwargs): - from core.feature_flags import flag_set - - JWT_ACCESS_TOKEN_ENABLED = flag_set('fflag__feature_develop__prompts__dia_1829_jwt_token_auth') with transaction.atomic(): org = Organization.objects.create(title=title, created_by=created_by, **kwargs) OrganizationMember.objects.create(user=created_by, organization=org) - if JWT_ACCESS_TOKEN_ENABLED: - # set auth tokens to new system for new users - org.jwt.api_tokens_enabled = True - org.jwt.legacy_api_tokens_enabled = False - org.jwt.save() - return org + # set auth tokens to new system for new users + org.jwt.api_tokens_enabled = True + org.jwt.legacy_api_tokens_enabled = False + org.jwt.save() + return org def destroy_organization(org): diff --git a/label_studio/tests/jwt_auth/test_auth.py b/label_studio/tests/jwt_auth/test_auth.py index 4185e5d8aa39..44a7dc349a2e 100644 --- a/label_studio/tests/jwt_auth/test_auth.py +++ b/label_studio/tests/jwt_auth/test_auth.py @@ -6,11 +6,9 @@ from rest_framework.authtoken.models import Token from rest_framework.test import APIClient -from ..utils import mock_feature_flag from .utils import create_user_with_token_settings -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_logging_when_legacy_token_auth_enabled(caplog): user = create_user_with_token_settings(api_tokens_enabled=False, legacy_api_tokens_enabled=True) @@ -29,7 +27,6 @@ def test_logging_when_legacy_token_auth_enabled(caplog): assert record.endpoint == '/api/projects/' -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_no_logging_when_legacy_token_auth_disabled(caplog): user = create_user_with_token_settings(api_tokens_enabled=True, legacy_api_tokens_enabled=False) @@ -44,7 +41,6 @@ def test_no_logging_when_legacy_token_auth_disabled(caplog): assert len(basic_auth_logs) == 0 -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_legacy_api_token_disabled_user_cannot_use_legacy_token(): user = create_user_with_token_settings(api_tokens_enabled=True, legacy_api_tokens_enabled=False) diff --git a/label_studio/tests/jwt_auth/test_middleware.py b/label_studio/tests/jwt_auth/test_middleware.py index 619504b67316..c2ff40bcd8d3 100644 --- a/label_studio/tests/jwt_auth/test_middleware.py +++ b/label_studio/tests/jwt_auth/test_middleware.py @@ -6,11 +6,9 @@ from rest_framework.test import APIClient from users.models import User -from ..utils import mock_feature_flag from .utils import create_user_with_token_settings -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_request_without_auth_header_returns_401(): client = APIClient() @@ -18,7 +16,6 @@ def test_request_without_auth_header_returns_401(): assert response.status_code == status.HTTP_401_UNAUTHORIZED -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_request_with_invalid_token_returns_401(): client = APIClient() @@ -27,7 +24,6 @@ def test_request_with_invalid_token_returns_401(): assert response.status_code == status.HTTP_401_UNAUTHORIZED -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_request_with_valid_token_returns_authenticated_user(): user = create_user_with_token_settings(api_tokens_enabled=True, legacy_api_tokens_enabled=False) @@ -41,7 +37,6 @@ def test_request_with_valid_token_returns_authenticated_user(): assert response.wsgi_request.user == user -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_jwt_token_auth_disabled_user_cannot_use_jwt_token(): user = create_user_with_token_settings(api_tokens_enabled=False, legacy_api_tokens_enabled=True) @@ -53,7 +48,6 @@ def test_jwt_token_auth_disabled_user_cannot_use_jwt_token(): assert response.status_code == status.HTTP_401_UNAUTHORIZED -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_user_with_both_auth_enabled_can_use_both_methods(): user = create_user_with_token_settings(api_tokens_enabled=True, legacy_api_tokens_enabled=True) @@ -78,7 +72,6 @@ def test_user_with_both_auth_enabled_can_use_both_methods(): assert response.wsgi_request.user == user -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_user_with_no_auth_enabled_cannot_use_either_method(): user = create_user_with_token_settings(api_tokens_enabled=False, legacy_api_tokens_enabled=False) @@ -101,7 +94,6 @@ def test_user_with_no_auth_enabled_cannot_use_either_method(): assert response.status_code == status.HTTP_401_UNAUTHORIZED -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_jwt_token_invalid_after_user_deleted(): user = create_user_with_token_settings(api_tokens_enabled=True, legacy_api_tokens_enabled=False) @@ -119,7 +111,6 @@ def test_jwt_token_invalid_after_user_deleted(): assert response.status_code == status.HTTP_401_UNAUTHORIZED -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_user_with_default_auth_settings_can_use_jwt_but_not_legacy_token(): # Create user and org with default settings from create_organization diff --git a/label_studio/tests/jwt_auth/test_models.py b/label_studio/tests/jwt_auth/test_models.py index 2f8406bba450..4367f497f404 100644 --- a/label_studio/tests/jwt_auth/test_models.py +++ b/label_studio/tests/jwt_auth/test_models.py @@ -5,11 +5,9 @@ from rest_framework_simplejwt.settings import api_settings as simple_jwt_settings from rest_framework_simplejwt.token_blacklist.models import BlacklistedToken, OutstandingToken -from ..utils import mock_feature_flag from .utils import create_user_with_token_settings -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_jwt_settings_permissions(): user = create_user_with_token_settings(api_tokens_enabled=True, legacy_api_tokens_enabled=False) @@ -28,7 +26,6 @@ def test_jwt_settings_permissions(): assert org.jwt.has_permission(user) is False -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.fixture def token_backend(): return LSTokenBackend( @@ -43,7 +40,6 @@ def token_backend(): ) -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) def test_encode_returns_only_header_and_payload(token_backend): payload = { 'user_id': 123, @@ -59,7 +55,6 @@ def test_encode_returns_only_header_and_payload(token_backend): assert all(part.replace('-', '+').replace('_', '/') for part in parts) -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) def test_encode_full_returns_complete_jwt(token_backend): payload = { 'user_id': 123, @@ -74,7 +69,6 @@ def test_encode_full_returns_complete_jwt(token_backend): assert all(part.replace('-', '+').replace('_', '/') for part in parts) -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) def test_encode_vs_encode_full_comparison(token_backend): payload = { 'user_id': 123, @@ -87,7 +81,6 @@ def test_encode_vs_encode_full_comparison(token_backend): assert full_token.startswith(partial_token) -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_token_lifecycle(): """Test full token lifecycle including creation, access token generation, blacklisting, and validation""" diff --git a/label_studio/tests/jwt_auth/test_views.py b/label_studio/tests/jwt_auth/test_views.py index 8dadc29f82bb..6e5d31ddd2cf 100644 --- a/label_studio/tests/jwt_auth/test_views.py +++ b/label_studio/tests/jwt_auth/test_views.py @@ -4,10 +4,8 @@ from rest_framework.test import APIClient from rest_framework_simplejwt.exceptions import TokenError from tests.jwt_auth.utils import create_user_with_token_settings -from tests.utils import mock_feature_flag -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_blacklist_view_returns_404_with_already_blacklisted_token(client): user = create_user_with_token_settings(api_tokens_enabled=True, legacy_api_tokens_enabled=False) @@ -20,7 +18,6 @@ def test_blacklist_view_returns_404_with_already_blacklisted_token(client): assert response.status_code == status.HTTP_404_NOT_FOUND -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_blacklist_view_returns_204_with_valid_token(client): user = create_user_with_token_settings(api_tokens_enabled=True, legacy_api_tokens_enabled=False) @@ -34,7 +31,6 @@ def test_blacklist_view_returns_204_with_valid_token(client): token.check_blacklist() -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_create_token_when_no_existing_token(): user = create_user_with_token_settings(api_tokens_enabled=True, legacy_api_tokens_enabled=False) @@ -49,7 +45,6 @@ def test_create_token_when_no_existing_token(): assert 'token' in response.data -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_create_token_when_existing_valid_token(): user = create_user_with_token_settings(api_tokens_enabled=True, legacy_api_tokens_enabled=False) @@ -69,7 +64,6 @@ def test_create_token_when_existing_valid_token(): assert 'You already have a valid token' in response.data['detail'] -@mock_feature_flag(flag_name='fflag__feature_develop__prompts__dia_1829_jwt_token_auth', value=True) @pytest.mark.django_db def test_create_token_after_blacklisting_previous(): user = create_user_with_token_settings(api_tokens_enabled=True, legacy_api_tokens_enabled=False) diff --git a/web/apps/labelstudio/src/pages/Organization/PeoplePage/PeoplePage.jsx b/web/apps/labelstudio/src/pages/Organization/PeoplePage/PeoplePage.jsx index 7da496b5c780..dc50e48c4f6f 100644 --- a/web/apps/labelstudio/src/pages/Organization/PeoplePage/PeoplePage.jsx +++ b/web/apps/labelstudio/src/pages/Organization/PeoplePage/PeoplePage.jsx @@ -9,7 +9,7 @@ import { Space } from "../../../components/Space/Space"; import { useAPI } from "../../../providers/ApiProvider"; import { useConfig } from "../../../providers/ConfigProvider"; import { Block, Elem } from "../../../utils/bem"; -import { FF_AUTH_TOKENS, FF_LSDV_E_297, isFF } from "../../../utils/feature-flags"; +import { FF_LSDV_E_297, isFF } from "../../../utils/feature-flags"; import { copyText } from "../../../utils/helpers"; import "./PeopleInvitation.scss"; import { PeopleList } from "./PeopleList"; @@ -157,7 +157,9 @@ export const PeoplePage = () => { - {isFF(FF_AUTH_TOKENS) && } + diff --git a/web/apps/labelstudio/src/pages/index.js b/web/apps/labelstudio/src/pages/index.js index 1f696787930b..38fd054e74ab 100644 --- a/web/apps/labelstudio/src/pages/index.js +++ b/web/apps/labelstudio/src/pages/index.js @@ -2,8 +2,10 @@ import { ProjectsPage } from "./Projects/Projects"; import { OrganizationPage } from "./Organization"; import { ModelsPage } from "./Organization/Models/ModelsPage"; import { AccountSettingsPage } from "@humansignal/core"; -import { FF_AUTH_TOKENS, isFF } from "../utils/feature-flags"; -export const Pages = [ProjectsPage, OrganizationPage, ModelsPage, isFF(FF_AUTH_TOKENS) && AccountSettingsPage].filter( - Boolean, -); +export const Pages = [ + ProjectsPage, + OrganizationPage, + ModelsPage, + AccountSettingsPage, +].filter(Boolean); diff --git a/web/libs/core/src/lib/utils/feature-flags.ts b/web/libs/core/src/lib/utils/feature-flags.ts index f30d3c890d82..cc9ce37dcdd0 100644 --- a/web/libs/core/src/lib/utils/feature-flags.ts +++ b/web/libs/core/src/lib/utils/feature-flags.ts @@ -35,13 +35,10 @@ export const FF_UNSAVED_CHANGES = "fflag_feat_front_leap_1198_unsaved_changes_18 /** * Enables JWT tokens */ -export const FF_AUTH_TOKENS = "fflag__feature_develop__prompts__dia_1829_jwt_token_auth"; - export function isFF(id: string) { // TODO: remove the override + if statement once LSE and LSO start building react the same way and fflag_fix_front_lsdv_4620_memory_leaks_100723_short is removed const override: Record = { fflag_fix_front_lsdv_4620_memory_leaks_100723_short: false, - // [FF_AUTH_TOKENS]: false, }; if (window?.APP_SETTINGS?.sentry_environment === "opensource" && id in override) { return override[id]; diff --git a/web/libs/core/src/pages/AccountSettings/sections/index.tsx b/web/libs/core/src/pages/AccountSettings/sections/index.tsx index ad22ce9a1df0..d34a1f66bd16 100644 --- a/web/libs/core/src/pages/AccountSettings/sections/index.tsx +++ b/web/libs/core/src/pages/AccountSettings/sections/index.tsx @@ -6,7 +6,6 @@ import type React from "react"; import { PersonalJWTToken } from "./PersonalJWTToken"; import "./index.raw.css"; import type { AuthTokenSettings } from "../types"; -import { FF_AUTH_TOKENS, isFF } from "@humansignal/core/lib/utils/feature-flags"; type SectionType = { title: string; @@ -32,16 +31,15 @@ export const accountSettingsSections = (settings: AuthTokenSettings): SectionTyp id: "membership-info", component: MembershipInfo, }, - settings.api_tokens_enabled && - isFF(FF_AUTH_TOKENS) && { - title: "Personal Access Token", - id: "personal-access-token", - // component: PersonalAccessToken, - component: PersonalJWTToken, - description: PersonalAccessTokenDescription, - }, + settings.api_tokens_enabled && { + title: "Personal Access Token", + id: "personal-access-token", + // component: PersonalAccessToken, + component: PersonalJWTToken, + description: PersonalAccessTokenDescription, + }, settings.legacy_api_tokens_enabled && { - title: isFF(FF_AUTH_TOKENS) ? "Legacy Token" : "Access Token", + title: "Legacy Token", id: "personal-access-token", // component: PersonalAccessToken, component: PersonalAccessToken,