DEV: Backfill API key scope modes (#31606)

### What is this change?

Follow-up to #31601. This will be used for display in the admin API keys
UI.
This commit is contained in:
Ted Johansson
2025-03-11 10:00:27 +08:00
committed by GitHub
parent 54771b5949
commit f2365fd98b
4 changed files with 74 additions and 1 deletions
@@ -0,0 +1,34 @@
# frozen_string_literal: true
class BackfillApiKeyScopeModes < ActiveRecord::Migration[7.2]
def up
DB.exec(<<~SQL)
UPDATE api_keys
SET scope_mode = (
CASE
-- No associated `api_key_scopes` means global.
WHEN NOT EXISTS (
SELECT 1 FROM api_key_scopes aks WHERE aks.api_key_id = api_keys.id
) THEN 0
-- Single associated `api_key_scope` with resource = 'global' and action = 'read' means read only.
WHEN EXISTS (
SELECT 1 FROM api_key_scopes aks
WHERE aks.api_key_id = api_keys.id
AND aks.resource = 'global'
AND aks.action = 'read'
GROUP BY aks.api_key_id
HAVING COUNT(*) = 1
) THEN 1
-- Otherwise, associated scopes other than read only means granular.
ELSE 2
END
);
SQL
end
def down
raise ActiveRecord::IrreversibleMigration
end
end
+16 -1
View File
@@ -1,3 +1,18 @@
# frozen_string_literal: true
Fabricator(:api_key) {}
Fabricator(:api_key)
Fabricator(:global_api_key, from: :api_key)
Fabricator(:read_only_api_key, from: :api_key) do
api_key_scopes(count: 1) do |attrs, i|
Fabricate.build(:api_key_scope, resource: "global", action: "read")
end
end
Fabricator(:granular_api_key, from: :api_key) do
api_key_scopes(count: 1) do |attrs, i|
Fabricate.build(:api_key_scope, resource: "topics", action: "read")
Fabricate.build(:api_key_scope, resource: "topics", action: "write")
end
end
@@ -0,0 +1,3 @@
# frozen_string_literal: true
Fabricator(:api_key_scope)
@@ -0,0 +1,21 @@
# frozen_string_literal: true
require Rails.root.join("db/post_migrate/20250304074934_backfill_api_key_scope_modes.rb")
RSpec.describe BackfillApiKeyScopeModes do
describe "#up" do
fab!(:global_api_key)
fab!(:read_only_api_key)
fab!(:granular_api_key)
it "backfills with the correct scope modes" do
silence_stdout do
expect { described_class.new.up }.to change { read_only_api_key.reload.scope_mode }.from(
nil,
).to("read_only").and change { global_api_key.reload.scope_mode }.from(nil).to(
"global",
).and change { granular_api_key.reload.scope_mode }.from(nil).to("granular")
end
end
end
end