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) && }
+
} primary onClick={showInvitationModal}>
Add People
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,