fix(auth): harden oauth identity upgrade paths
This commit is contained in:
@@ -38,23 +38,22 @@ VALUES
|
||||
('auth_source_default_email_balance', '0'),
|
||||
('auth_source_default_email_concurrency', '5'),
|
||||
('auth_source_default_email_subscriptions', '[]'),
|
||||
('auth_source_default_email_grant_on_signup', 'true'),
|
||||
('auth_source_default_email_grant_on_signup', 'false'),
|
||||
('auth_source_default_email_grant_on_first_bind', 'false'),
|
||||
('auth_source_default_linuxdo_balance', '0'),
|
||||
('auth_source_default_linuxdo_concurrency', '5'),
|
||||
('auth_source_default_linuxdo_subscriptions', '[]'),
|
||||
('auth_source_default_linuxdo_grant_on_signup', 'true'),
|
||||
('auth_source_default_linuxdo_grant_on_signup', 'false'),
|
||||
('auth_source_default_linuxdo_grant_on_first_bind', 'false'),
|
||||
('auth_source_default_oidc_balance', '0'),
|
||||
('auth_source_default_oidc_concurrency', '5'),
|
||||
('auth_source_default_oidc_subscriptions', '[]'),
|
||||
('auth_source_default_oidc_grant_on_signup', 'true'),
|
||||
('auth_source_default_oidc_grant_on_signup', 'false'),
|
||||
('auth_source_default_oidc_grant_on_first_bind', 'false'),
|
||||
('auth_source_default_wechat_balance', '0'),
|
||||
('auth_source_default_wechat_concurrency', '5'),
|
||||
('auth_source_default_wechat_subscriptions', '[]'),
|
||||
('auth_source_default_wechat_grant_on_signup', 'true'),
|
||||
('auth_source_default_wechat_grant_on_signup', 'false'),
|
||||
('auth_source_default_wechat_grant_on_first_bind', 'false'),
|
||||
('force_email_on_third_party_signup', 'false')
|
||||
ON CONFLICT (key) DO NOTHING;
|
||||
|
||||
|
||||
@@ -31,6 +31,41 @@ BEGIN
|
||||
END IF;
|
||||
|
||||
EXECUTE $sql$
|
||||
WITH legacy AS (
|
||||
SELECT
|
||||
uei.id,
|
||||
uei.user_id,
|
||||
BTRIM(uei.provider_user_id) AS provider_user_id,
|
||||
BTRIM(uei.provider_username) AS provider_username,
|
||||
BTRIM(uei.display_name) AS display_name,
|
||||
public.__migration_115_safe_legacy_metadata_jsonb(uei.metadata) AS metadata_json,
|
||||
uei.created_at,
|
||||
uei.updated_at
|
||||
FROM user_external_identities AS uei
|
||||
JOIN users AS u ON u.id = uei.user_id
|
||||
WHERE u.deleted_at IS NULL
|
||||
AND LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'linuxdo'
|
||||
AND BTRIM(COALESCE(uei.provider_user_id, '')) <> ''
|
||||
),
|
||||
legacy_subjects AS (
|
||||
SELECT
|
||||
provider_user_id AS provider_subject,
|
||||
COUNT(DISTINCT user_id) AS distinct_user_count
|
||||
FROM legacy
|
||||
GROUP BY provider_user_id
|
||||
),
|
||||
canonical_legacy AS (
|
||||
SELECT
|
||||
legacy.*,
|
||||
ROW_NUMBER() OVER (
|
||||
PARTITION BY legacy.provider_user_id
|
||||
ORDER BY COALESCE(legacy.updated_at, legacy.created_at, NOW()) DESC, legacy.id DESC
|
||||
) AS canonical_row_num
|
||||
FROM legacy
|
||||
JOIN legacy_subjects AS subjects
|
||||
ON subjects.provider_subject = legacy.provider_user_id
|
||||
AND subjects.distinct_user_count = 1
|
||||
)
|
||||
INSERT INTO auth_identities (
|
||||
user_id,
|
||||
provider_type,
|
||||
@@ -52,11 +87,18 @@ SELECT
|
||||
'display_name', legacy.display_name,
|
||||
'migration', '115_auth_identity_legacy_external_backfill'
|
||||
)
|
||||
FROM (
|
||||
FROM canonical_legacy AS legacy
|
||||
WHERE legacy.canonical_row_num = 1
|
||||
ON CONFLICT (provider_type, provider_key, provider_subject) DO NOTHING;
|
||||
$sql$;
|
||||
|
||||
EXECUTE $sql$
|
||||
WITH legacy AS (
|
||||
SELECT
|
||||
uei.id,
|
||||
uei.user_id,
|
||||
BTRIM(uei.provider_user_id) AS provider_user_id,
|
||||
BTRIM(uei.provider_union_id) AS provider_union_id,
|
||||
BTRIM(uei.provider_username) AS provider_username,
|
||||
BTRIM(uei.display_name) AS display_name,
|
||||
public.__migration_115_safe_legacy_metadata_jsonb(uei.metadata) AS metadata_json,
|
||||
@@ -65,13 +107,28 @@ FROM (
|
||||
FROM user_external_identities AS uei
|
||||
JOIN users AS u ON u.id = uei.user_id
|
||||
WHERE u.deleted_at IS NULL
|
||||
AND LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'linuxdo'
|
||||
AND BTRIM(COALESCE(uei.provider_user_id, '')) <> ''
|
||||
) AS legacy
|
||||
ON CONFLICT (provider_type, provider_key, provider_subject) DO NOTHING;
|
||||
$sql$;
|
||||
|
||||
EXECUTE $sql$
|
||||
AND LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat'
|
||||
AND BTRIM(COALESCE(uei.provider_union_id, '')) <> ''
|
||||
),
|
||||
legacy_subjects AS (
|
||||
SELECT
|
||||
provider_union_id AS provider_subject,
|
||||
COUNT(DISTINCT user_id) AS distinct_user_count
|
||||
FROM legacy
|
||||
GROUP BY provider_union_id
|
||||
),
|
||||
canonical_legacy AS (
|
||||
SELECT
|
||||
legacy.*,
|
||||
ROW_NUMBER() OVER (
|
||||
PARTITION BY legacy.provider_union_id
|
||||
ORDER BY COALESCE(legacy.updated_at, legacy.created_at, NOW()) DESC, legacy.id DESC
|
||||
) AS canonical_row_num
|
||||
FROM legacy
|
||||
JOIN legacy_subjects AS subjects
|
||||
ON subjects.provider_subject = legacy.provider_union_id
|
||||
AND subjects.distinct_user_count = 1
|
||||
)
|
||||
INSERT INTO auth_identities (
|
||||
user_id,
|
||||
provider_type,
|
||||
@@ -96,27 +153,36 @@ SELECT
|
||||
'display_name', legacy.display_name,
|
||||
'migration', '115_auth_identity_legacy_external_backfill'
|
||||
)
|
||||
FROM (
|
||||
SELECT
|
||||
uei.id,
|
||||
uei.user_id,
|
||||
BTRIM(uei.provider_user_id) AS provider_user_id,
|
||||
BTRIM(uei.provider_union_id) AS provider_union_id,
|
||||
BTRIM(uei.provider_username) AS provider_username,
|
||||
BTRIM(uei.display_name) AS display_name,
|
||||
public.__migration_115_safe_legacy_metadata_jsonb(uei.metadata) AS metadata_json,
|
||||
uei.created_at,
|
||||
uei.updated_at
|
||||
FROM user_external_identities AS uei
|
||||
JOIN users AS u ON u.id = uei.user_id
|
||||
WHERE u.deleted_at IS NULL
|
||||
AND LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat'
|
||||
AND BTRIM(COALESCE(uei.provider_union_id, '')) <> ''
|
||||
) AS legacy
|
||||
FROM canonical_legacy AS legacy
|
||||
WHERE legacy.canonical_row_num = 1
|
||||
ON CONFLICT (provider_type, provider_key, provider_subject) DO NOTHING;
|
||||
$sql$;
|
||||
|
||||
EXECUTE $sql$
|
||||
WITH legacy AS (
|
||||
SELECT
|
||||
uei.user_id,
|
||||
BTRIM(uei.provider_user_id) AS provider_user_id,
|
||||
BTRIM(uei.provider_union_id) AS provider_union_id,
|
||||
BTRIM(COALESCE(meta.metadata_json ->> 'channel', '')) AS channel,
|
||||
BTRIM(COALESCE(meta.metadata_json ->> 'channel_app_id', meta.metadata_json ->> 'appid', meta.metadata_json ->> 'app_id', '')) AS channel_app_id,
|
||||
meta.metadata_json
|
||||
FROM user_external_identities AS uei
|
||||
JOIN users AS u ON u.id = uei.user_id
|
||||
CROSS JOIN LATERAL (
|
||||
SELECT public.__migration_115_safe_legacy_metadata_jsonb(uei.metadata) AS metadata_json
|
||||
) AS meta
|
||||
WHERE u.deleted_at IS NULL
|
||||
AND LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat'
|
||||
AND BTRIM(COALESCE(uei.provider_union_id, '')) <> ''
|
||||
),
|
||||
legacy_subjects AS (
|
||||
SELECT
|
||||
provider_union_id AS provider_subject,
|
||||
COUNT(DISTINCT user_id) AS distinct_user_count
|
||||
FROM legacy
|
||||
GROUP BY provider_union_id
|
||||
)
|
||||
INSERT INTO auth_identity_channels (
|
||||
identity_id,
|
||||
provider_type,
|
||||
@@ -138,23 +204,10 @@ SELECT
|
||||
'unionid', legacy.provider_union_id,
|
||||
'migration', '115_auth_identity_legacy_external_backfill'
|
||||
)
|
||||
FROM (
|
||||
SELECT
|
||||
uei.user_id,
|
||||
BTRIM(uei.provider_user_id) AS provider_user_id,
|
||||
BTRIM(uei.provider_union_id) AS provider_union_id,
|
||||
BTRIM(COALESCE(meta.metadata_json ->> 'channel', '')) AS channel,
|
||||
BTRIM(COALESCE(meta.metadata_json ->> 'channel_app_id', meta.metadata_json ->> 'appid', meta.metadata_json ->> 'app_id', '')) AS channel_app_id,
|
||||
meta.metadata_json
|
||||
FROM user_external_identities AS uei
|
||||
JOIN users AS u ON u.id = uei.user_id
|
||||
CROSS JOIN LATERAL (
|
||||
SELECT public.__migration_115_safe_legacy_metadata_jsonb(uei.metadata) AS metadata_json
|
||||
) AS meta
|
||||
WHERE u.deleted_at IS NULL
|
||||
AND LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat'
|
||||
AND BTRIM(COALESCE(uei.provider_union_id, '')) <> ''
|
||||
) AS legacy
|
||||
FROM legacy
|
||||
JOIN legacy_subjects AS subjects
|
||||
ON subjects.provider_subject = legacy.provider_union_id
|
||||
AND subjects.distinct_user_count = 1
|
||||
JOIN auth_identities AS ai
|
||||
ON ai.user_id = legacy.user_id
|
||||
AND ai.provider_type = 'wechat'
|
||||
|
||||
@@ -74,6 +74,82 @@ $sql$;
|
||||
|
||||
EXECUTE $sql$
|
||||
INSERT INTO auth_identity_migration_reports (report_type, report_key, details)
|
||||
SELECT
|
||||
'legacy_external_identity_conflict',
|
||||
'legacy_external_identity:' || legacy.id::text,
|
||||
legacy.metadata_json || jsonb_build_object(
|
||||
'legacy_identity_id', legacy.id,
|
||||
'legacy_user_id', legacy.user_id,
|
||||
'provider_type', legacy.provider_type,
|
||||
'provider_key', legacy.provider_key,
|
||||
'provider_subject', legacy.provider_subject,
|
||||
'conflicting_legacy_user_ids', ambiguous.conflicting_legacy_user_ids,
|
||||
'reason', 'legacy canonical identity subject belongs to multiple legacy users and cannot be auto-resolved',
|
||||
'migration', '116_auth_identity_legacy_external_safety_reports'
|
||||
)
|
||||
FROM (
|
||||
SELECT
|
||||
uei.id,
|
||||
uei.user_id,
|
||||
LOWER(BTRIM(COALESCE(uei.provider, ''))) AS provider_type,
|
||||
CASE
|
||||
WHEN LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat' THEN 'wechat-main'
|
||||
ELSE 'linuxdo'
|
||||
END AS provider_key,
|
||||
CASE
|
||||
WHEN LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat' THEN BTRIM(COALESCE(uei.provider_union_id, ''))
|
||||
ELSE BTRIM(COALESCE(uei.provider_user_id, ''))
|
||||
END AS provider_subject,
|
||||
public.__migration_116_safe_legacy_metadata_jsonb(uei.metadata) AS metadata_json
|
||||
FROM user_external_identities AS uei
|
||||
JOIN users AS u ON u.id = uei.user_id
|
||||
WHERE u.deleted_at IS NULL
|
||||
AND LOWER(BTRIM(COALESCE(uei.provider, ''))) IN ('linuxdo', 'wechat')
|
||||
AND (
|
||||
(LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'linuxdo' AND BTRIM(COALESCE(uei.provider_user_id, '')) <> '')
|
||||
OR
|
||||
(LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat' AND BTRIM(COALESCE(uei.provider_union_id, '')) <> '')
|
||||
)
|
||||
) AS legacy
|
||||
JOIN (
|
||||
SELECT
|
||||
provider_type,
|
||||
provider_key,
|
||||
provider_subject,
|
||||
to_jsonb(array_agg(DISTINCT user_id ORDER BY user_id)) AS conflicting_legacy_user_ids
|
||||
FROM (
|
||||
SELECT
|
||||
uei.user_id,
|
||||
LOWER(BTRIM(COALESCE(uei.provider, ''))) AS provider_type,
|
||||
CASE
|
||||
WHEN LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat' THEN 'wechat-main'
|
||||
ELSE 'linuxdo'
|
||||
END AS provider_key,
|
||||
CASE
|
||||
WHEN LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat' THEN BTRIM(COALESCE(uei.provider_union_id, ''))
|
||||
ELSE BTRIM(COALESCE(uei.provider_user_id, ''))
|
||||
END AS provider_subject
|
||||
FROM user_external_identities AS uei
|
||||
JOIN users AS u ON u.id = uei.user_id
|
||||
WHERE u.deleted_at IS NULL
|
||||
AND LOWER(BTRIM(COALESCE(uei.provider, ''))) IN ('linuxdo', 'wechat')
|
||||
AND (
|
||||
(LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'linuxdo' AND BTRIM(COALESCE(uei.provider_user_id, '')) <> '')
|
||||
OR
|
||||
(LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat' AND BTRIM(COALESCE(uei.provider_union_id, '')) <> '')
|
||||
)
|
||||
) AS legacy_subjects
|
||||
GROUP BY provider_type, provider_key, provider_subject
|
||||
HAVING COUNT(DISTINCT user_id) > 1
|
||||
) AS ambiguous
|
||||
ON ambiguous.provider_type = legacy.provider_type
|
||||
AND ambiguous.provider_key = legacy.provider_key
|
||||
AND ambiguous.provider_subject = legacy.provider_subject
|
||||
ON CONFLICT (report_type, report_key) DO NOTHING;
|
||||
$sql$;
|
||||
|
||||
EXECUTE $sql$
|
||||
INSERT INTO auth_identity_migration_reports (report_type, report_key, details)
|
||||
SELECT
|
||||
'legacy_external_identity_conflict',
|
||||
'legacy_external_identity:' || legacy.id::text,
|
||||
@@ -116,6 +192,39 @@ FROM (
|
||||
(LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat' AND BTRIM(COALESCE(uei.provider_union_id, '')) <> '')
|
||||
)
|
||||
) AS legacy
|
||||
JOIN (
|
||||
SELECT
|
||||
provider_type,
|
||||
provider_key,
|
||||
provider_subject
|
||||
FROM (
|
||||
SELECT
|
||||
uei.user_id,
|
||||
LOWER(BTRIM(COALESCE(uei.provider, ''))) AS provider_type,
|
||||
CASE
|
||||
WHEN LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat' THEN 'wechat-main'
|
||||
ELSE 'linuxdo'
|
||||
END AS provider_key,
|
||||
CASE
|
||||
WHEN LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat' THEN BTRIM(COALESCE(uei.provider_union_id, ''))
|
||||
ELSE BTRIM(COALESCE(uei.provider_user_id, ''))
|
||||
END AS provider_subject
|
||||
FROM user_external_identities AS uei
|
||||
JOIN users AS u ON u.id = uei.user_id
|
||||
WHERE u.deleted_at IS NULL
|
||||
AND LOWER(BTRIM(COALESCE(uei.provider, ''))) IN ('linuxdo', 'wechat')
|
||||
AND (
|
||||
(LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'linuxdo' AND BTRIM(COALESCE(uei.provider_user_id, '')) <> '')
|
||||
OR
|
||||
(LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat' AND BTRIM(COALESCE(uei.provider_union_id, '')) <> '')
|
||||
)
|
||||
) AS legacy_subjects
|
||||
GROUP BY provider_type, provider_key, provider_subject
|
||||
HAVING COUNT(DISTINCT user_id) = 1
|
||||
) AS clear_subjects
|
||||
ON clear_subjects.provider_type = legacy.provider_type
|
||||
AND clear_subjects.provider_key = legacy.provider_key
|
||||
AND clear_subjects.provider_subject = legacy.provider_subject
|
||||
JOIN auth_identities AS ai
|
||||
ON ai.provider_type = legacy.provider_type
|
||||
AND ai.provider_key = legacy.provider_key
|
||||
@@ -125,29 +234,7 @@ ON CONFLICT (report_type, report_key) DO NOTHING;
|
||||
$sql$;
|
||||
|
||||
EXECUTE $sql$
|
||||
INSERT INTO auth_identities (
|
||||
user_id,
|
||||
provider_type,
|
||||
provider_key,
|
||||
provider_subject,
|
||||
verified_at,
|
||||
metadata
|
||||
)
|
||||
SELECT
|
||||
legacy.user_id,
|
||||
legacy.provider_type,
|
||||
legacy.provider_key,
|
||||
legacy.provider_subject,
|
||||
legacy.verified_at,
|
||||
legacy.metadata_json || jsonb_build_object(
|
||||
'legacy_identity_id', legacy.id,
|
||||
'provider_user_id', legacy.provider_user_id,
|
||||
'provider_union_id', NULLIF(legacy.provider_union_id, ''),
|
||||
'provider_username', legacy.provider_username,
|
||||
'display_name', legacy.display_name,
|
||||
'migration', '116_auth_identity_legacy_external_safety_reports'
|
||||
)
|
||||
FROM (
|
||||
WITH legacy AS (
|
||||
SELECT
|
||||
uei.id,
|
||||
uei.user_id,
|
||||
@@ -175,12 +262,58 @@ FROM (
|
||||
OR
|
||||
(LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat' AND BTRIM(COALESCE(uei.provider_union_id, '')) <> '')
|
||||
)
|
||||
) AS legacy
|
||||
),
|
||||
clear_subjects AS (
|
||||
SELECT
|
||||
provider_type,
|
||||
provider_key,
|
||||
provider_subject
|
||||
FROM legacy
|
||||
GROUP BY provider_type, provider_key, provider_subject
|
||||
HAVING COUNT(DISTINCT user_id) = 1
|
||||
),
|
||||
canonical_legacy AS (
|
||||
SELECT
|
||||
legacy.*,
|
||||
ROW_NUMBER() OVER (
|
||||
PARTITION BY legacy.provider_type, legacy.provider_key, legacy.provider_subject
|
||||
ORDER BY legacy.verified_at DESC, legacy.id DESC
|
||||
) AS canonical_row_num
|
||||
FROM legacy
|
||||
JOIN clear_subjects
|
||||
ON clear_subjects.provider_type = legacy.provider_type
|
||||
AND clear_subjects.provider_key = legacy.provider_key
|
||||
AND clear_subjects.provider_subject = legacy.provider_subject
|
||||
)
|
||||
INSERT INTO auth_identities (
|
||||
user_id,
|
||||
provider_type,
|
||||
provider_key,
|
||||
provider_subject,
|
||||
verified_at,
|
||||
metadata
|
||||
)
|
||||
SELECT
|
||||
legacy.user_id,
|
||||
legacy.provider_type,
|
||||
legacy.provider_key,
|
||||
legacy.provider_subject,
|
||||
legacy.verified_at,
|
||||
legacy.metadata_json || jsonb_build_object(
|
||||
'legacy_identity_id', legacy.id,
|
||||
'provider_user_id', legacy.provider_user_id,
|
||||
'provider_union_id', NULLIF(legacy.provider_union_id, ''),
|
||||
'provider_username', legacy.provider_username,
|
||||
'display_name', legacy.display_name,
|
||||
'migration', '116_auth_identity_legacy_external_safety_reports'
|
||||
)
|
||||
FROM canonical_legacy AS legacy
|
||||
LEFT JOIN auth_identities AS ai
|
||||
ON ai.provider_type = legacy.provider_type
|
||||
AND ai.provider_key = legacy.provider_key
|
||||
AND ai.provider_subject = legacy.provider_subject
|
||||
WHERE ai.id IS NULL
|
||||
WHERE legacy.canonical_row_num = 1
|
||||
AND ai.id IS NULL
|
||||
ON CONFLICT (provider_type, provider_key, provider_subject) DO NOTHING;
|
||||
$sql$;
|
||||
|
||||
@@ -225,6 +358,19 @@ FROM (
|
||||
AND BTRIM(COALESCE(uei.provider_union_id, '')) <> ''
|
||||
AND BTRIM(COALESCE(uei.provider_user_id, '')) <> ''
|
||||
) AS legacy
|
||||
JOIN (
|
||||
SELECT
|
||||
BTRIM(COALESCE(uei.provider_union_id, '')) AS provider_subject
|
||||
FROM user_external_identities AS uei
|
||||
JOIN users AS u ON u.id = uei.user_id
|
||||
WHERE u.deleted_at IS NULL
|
||||
AND LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat'
|
||||
AND BTRIM(COALESCE(uei.provider_union_id, '')) <> ''
|
||||
AND BTRIM(COALESCE(uei.provider_user_id, '')) <> ''
|
||||
GROUP BY BTRIM(COALESCE(uei.provider_union_id, ''))
|
||||
HAVING COUNT(DISTINCT uei.user_id) = 1
|
||||
) AS clear_subjects
|
||||
ON clear_subjects.provider_subject = legacy.provider_union_id
|
||||
JOIN auth_identities AS legacy_ai
|
||||
ON legacy_ai.user_id = legacy.user_id
|
||||
AND legacy_ai.provider_type = 'wechat'
|
||||
@@ -245,6 +391,33 @@ ON CONFLICT (report_type, report_key) DO NOTHING;
|
||||
$sql$;
|
||||
|
||||
EXECUTE $sql$
|
||||
WITH legacy AS (
|
||||
SELECT
|
||||
uei.user_id,
|
||||
BTRIM(COALESCE(uei.provider_user_id, '')) AS provider_user_id,
|
||||
BTRIM(COALESCE(uei.provider_union_id, '')) AS provider_union_id,
|
||||
public.__migration_116_safe_legacy_metadata_jsonb(uei.metadata) AS metadata_json,
|
||||
BTRIM(COALESCE(public.__migration_116_safe_legacy_metadata_jsonb(uei.metadata) ->> 'channel', '')) AS channel,
|
||||
BTRIM(COALESCE(
|
||||
public.__migration_116_safe_legacy_metadata_jsonb(uei.metadata) ->> 'channel_app_id',
|
||||
public.__migration_116_safe_legacy_metadata_jsonb(uei.metadata) ->> 'appid',
|
||||
public.__migration_116_safe_legacy_metadata_jsonb(uei.metadata) ->> 'app_id',
|
||||
''
|
||||
)) AS channel_app_id
|
||||
FROM user_external_identities AS uei
|
||||
JOIN users AS u ON u.id = uei.user_id
|
||||
WHERE u.deleted_at IS NULL
|
||||
AND LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat'
|
||||
AND BTRIM(COALESCE(uei.provider_union_id, '')) <> ''
|
||||
AND BTRIM(COALESCE(uei.provider_user_id, '')) <> ''
|
||||
),
|
||||
clear_subjects AS (
|
||||
SELECT
|
||||
provider_union_id AS provider_subject
|
||||
FROM legacy
|
||||
GROUP BY provider_union_id
|
||||
HAVING COUNT(DISTINCT user_id) = 1
|
||||
)
|
||||
INSERT INTO auth_identity_channels (
|
||||
identity_id,
|
||||
provider_type,
|
||||
@@ -266,26 +439,9 @@ SELECT
|
||||
'unionid', legacy.provider_union_id,
|
||||
'migration', '116_auth_identity_legacy_external_safety_reports'
|
||||
)
|
||||
FROM (
|
||||
SELECT
|
||||
uei.user_id,
|
||||
BTRIM(COALESCE(uei.provider_user_id, '')) AS provider_user_id,
|
||||
BTRIM(COALESCE(uei.provider_union_id, '')) AS provider_union_id,
|
||||
public.__migration_116_safe_legacy_metadata_jsonb(uei.metadata) AS metadata_json,
|
||||
BTRIM(COALESCE(public.__migration_116_safe_legacy_metadata_jsonb(uei.metadata) ->> 'channel', '')) AS channel,
|
||||
BTRIM(COALESCE(
|
||||
public.__migration_116_safe_legacy_metadata_jsonb(uei.metadata) ->> 'channel_app_id',
|
||||
public.__migration_116_safe_legacy_metadata_jsonb(uei.metadata) ->> 'appid',
|
||||
public.__migration_116_safe_legacy_metadata_jsonb(uei.metadata) ->> 'app_id',
|
||||
''
|
||||
)) AS channel_app_id
|
||||
FROM user_external_identities AS uei
|
||||
JOIN users AS u ON u.id = uei.user_id
|
||||
WHERE u.deleted_at IS NULL
|
||||
AND LOWER(BTRIM(COALESCE(uei.provider, ''))) = 'wechat'
|
||||
AND BTRIM(COALESCE(uei.provider_union_id, '')) <> ''
|
||||
AND BTRIM(COALESCE(uei.provider_user_id, '')) <> ''
|
||||
) AS legacy
|
||||
FROM legacy
|
||||
JOIN clear_subjects
|
||||
ON clear_subjects.provider_subject = legacy.provider_union_id
|
||||
JOIN auth_identities AS legacy_ai
|
||||
ON legacy_ai.user_id = legacy.user_id
|
||||
AND legacy_ai.provider_type = 'wechat'
|
||||
|
||||
@@ -1,3 +1,68 @@
|
||||
-- Intentionally left as a no-op.
|
||||
-- Legacy installs may have intentionally kept the original signup grant defaults,
|
||||
-- and we cannot distinguish those cases safely from untouched migration 110 rows.
|
||||
-- Auto-backfill untouched migration 110 signup-grant defaults to the corrected false value.
|
||||
-- Rows still matching the migration-110 default payload and timestamp window are treated as
|
||||
-- untouched legacy defaults; any remaining legacy true values are reported for manual review.
|
||||
|
||||
WITH migration_110 AS (
|
||||
SELECT applied_at
|
||||
FROM schema_migrations
|
||||
WHERE filename = '110_pending_auth_and_provider_default_grants.sql'
|
||||
),
|
||||
providers AS (
|
||||
SELECT provider_type
|
||||
FROM (
|
||||
VALUES ('email'), ('linuxdo'), ('oidc'), ('wechat')
|
||||
) AS providers(provider_type)
|
||||
),
|
||||
legacy_provider_defaults AS (
|
||||
SELECT providers.provider_type
|
||||
FROM providers
|
||||
CROSS JOIN migration_110
|
||||
JOIN settings balance
|
||||
ON balance.key = 'auth_source_default_' || providers.provider_type || '_balance'
|
||||
JOIN settings concurrency
|
||||
ON concurrency.key = 'auth_source_default_' || providers.provider_type || '_concurrency'
|
||||
JOIN settings subscriptions
|
||||
ON subscriptions.key = 'auth_source_default_' || providers.provider_type || '_subscriptions'
|
||||
JOIN settings grant_on_signup
|
||||
ON grant_on_signup.key = 'auth_source_default_' || providers.provider_type || '_grant_on_signup'
|
||||
JOIN settings grant_on_first_bind
|
||||
ON grant_on_first_bind.key = 'auth_source_default_' || providers.provider_type || '_grant_on_first_bind'
|
||||
WHERE balance.value = '0'
|
||||
AND concurrency.value = '5'
|
||||
AND subscriptions.value = '[]'
|
||||
AND grant_on_signup.value = 'true'
|
||||
AND grant_on_first_bind.value = 'false'
|
||||
AND balance.updated_at BETWEEN migration_110.applied_at - INTERVAL '1 minute' AND migration_110.applied_at + INTERVAL '1 minute'
|
||||
AND concurrency.updated_at BETWEEN migration_110.applied_at - INTERVAL '1 minute' AND migration_110.applied_at + INTERVAL '1 minute'
|
||||
AND subscriptions.updated_at BETWEEN migration_110.applied_at - INTERVAL '1 minute' AND migration_110.applied_at + INTERVAL '1 minute'
|
||||
AND grant_on_signup.updated_at BETWEEN migration_110.applied_at - INTERVAL '1 minute' AND migration_110.applied_at + INTERVAL '1 minute'
|
||||
AND grant_on_first_bind.updated_at BETWEEN migration_110.applied_at - INTERVAL '1 minute' AND migration_110.applied_at + INTERVAL '1 minute'
|
||||
),
|
||||
updated_signup_grants AS (
|
||||
UPDATE settings
|
||||
SET
|
||||
value = 'false',
|
||||
updated_at = NOW()
|
||||
FROM legacy_provider_defaults
|
||||
WHERE settings.key = 'auth_source_default_' || legacy_provider_defaults.provider_type || '_grant_on_signup'
|
||||
AND settings.value = 'true'
|
||||
RETURNING legacy_provider_defaults.provider_type
|
||||
)
|
||||
INSERT INTO auth_identity_migration_reports (report_type, report_key, details)
|
||||
SELECT
|
||||
'legacy_auth_source_signup_grant_review',
|
||||
providers.provider_type,
|
||||
jsonb_build_object(
|
||||
'provider_type', providers.provider_type,
|
||||
'current_value', grant_on_signup.value,
|
||||
'auto_backfilled', FALSE,
|
||||
'reason', 'legacy_true_default_not_auto_backfilled'
|
||||
)
|
||||
FROM providers
|
||||
JOIN settings grant_on_signup
|
||||
ON grant_on_signup.key = 'auth_source_default_' || providers.provider_type || '_grant_on_signup'
|
||||
LEFT JOIN updated_signup_grants
|
||||
ON updated_signup_grants.provider_type = providers.provider_type
|
||||
WHERE grant_on_signup.value = 'true'
|
||||
AND updated_signup_grants.provider_type IS NULL
|
||||
ON CONFLICT (report_type, report_key) DO NOTHING;
|
||||
|
||||
Reference in New Issue
Block a user