Change `read:me` scope to `profile` scope (#30357)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>shrike
parent
569b7d2f25
commit
e02d23b549
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::Accounts::CredentialsController < Api::BaseController
|
class Api::V1::Accounts::CredentialsController < Api::BaseController
|
||||||
before_action -> { doorkeeper_authorize! :read, :'read:accounts', :'read:me' }, except: [:update]
|
before_action -> { doorkeeper_authorize! :profile, :read, :'read:accounts' }, except: [:update]
|
||||||
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:update]
|
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:update]
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ class Settings::ApplicationsController < Settings::BaseController
|
||||||
def new
|
def new
|
||||||
@application = Doorkeeper::Application.new(
|
@application = Doorkeeper::Application.new(
|
||||||
redirect_uri: Doorkeeper.configuration.native_redirect_uri,
|
redirect_uri: Doorkeeper.configuration.native_redirect_uri,
|
||||||
scopes: 'read:me'
|
scopes: 'profile'
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,9 @@ class ScopeTransformer < Parslet::Transform
|
||||||
@namespace = scope[:namespace]&.to_s
|
@namespace = scope[:namespace]&.to_s
|
||||||
@access = scope[:access] ? [scope[:access].to_s] : DEFAULT_ACCESS.dup
|
@access = scope[:access] ? [scope[:access].to_s] : DEFAULT_ACCESS.dup
|
||||||
@term = scope[:term]&.to_s || DEFAULT_TERM
|
@term = scope[:term]&.to_s || DEFAULT_TERM
|
||||||
|
|
||||||
|
# # override for profile scope which is read only
|
||||||
|
@access = %w(read) if @term == 'profile'
|
||||||
end
|
end
|
||||||
|
|
||||||
def key
|
def key
|
||||||
|
|
|
@ -74,7 +74,8 @@ Doorkeeper.configure do
|
||||||
# For more information go to
|
# For more information go to
|
||||||
# https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes
|
# https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes
|
||||||
default_scopes :read
|
default_scopes :read
|
||||||
optional_scopes :write,
|
optional_scopes :profile,
|
||||||
|
:write,
|
||||||
:'write:accounts',
|
:'write:accounts',
|
||||||
:'write:blocks',
|
:'write:blocks',
|
||||||
:'write:bookmarks',
|
:'write:bookmarks',
|
||||||
|
@ -89,7 +90,6 @@ Doorkeeper.configure do
|
||||||
:'write:reports',
|
:'write:reports',
|
||||||
:'write:statuses',
|
:'write:statuses',
|
||||||
:read,
|
:read,
|
||||||
:'read:me',
|
|
||||||
:'read:accounts',
|
:'read:accounts',
|
||||||
:'read:blocks',
|
:'read:blocks',
|
||||||
:'read:bookmarks',
|
:'read:bookmarks',
|
||||||
|
|
|
@ -135,6 +135,7 @@ en:
|
||||||
media: Media attachments
|
media: Media attachments
|
||||||
mutes: Mutes
|
mutes: Mutes
|
||||||
notifications: Notifications
|
notifications: Notifications
|
||||||
|
profile: Your Mastodon profile
|
||||||
push: Push notifications
|
push: Push notifications
|
||||||
reports: Reports
|
reports: Reports
|
||||||
search: Search
|
search: Search
|
||||||
|
@ -165,6 +166,7 @@ en:
|
||||||
admin:write:reports: perform moderation actions on reports
|
admin:write:reports: perform moderation actions on reports
|
||||||
crypto: use end-to-end encryption
|
crypto: use end-to-end encryption
|
||||||
follow: modify account relationships
|
follow: modify account relationships
|
||||||
|
profile: read only your account's profile information
|
||||||
push: receive your push notifications
|
push: receive your push notifications
|
||||||
read: read all your account's data
|
read: read all your account's data
|
||||||
read:accounts: see accounts information
|
read:accounts: see accounts information
|
||||||
|
@ -174,7 +176,6 @@ en:
|
||||||
read:filters: see your filters
|
read:filters: see your filters
|
||||||
read:follows: see your follows
|
read:follows: see your follows
|
||||||
read:lists: see your lists
|
read:lists: see your lists
|
||||||
read:me: read only your account's basic information
|
|
||||||
read:mutes: see your mutes
|
read:mutes: see your mutes
|
||||||
read:notifications: see your notifications
|
read:notifications: see your notifications
|
||||||
read:reports: see your reports
|
read:reports: see your reports
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class ChangeReadMeScopeToProfile < ActiveRecord::Migration[7.1]
|
||||||
|
def up
|
||||||
|
replace_scopes('read:me', 'profile')
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
replace_scopes('profile', 'read:me')
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def replace_scopes(old_scope, new_scope)
|
||||||
|
Doorkeeper::Application.where("scopes LIKE '%#{old_scope}%'").in_batches do |applications|
|
||||||
|
applications.update_all("scopes = replace(scopes, '#{old_scope}', '#{new_scope}')")
|
||||||
|
end
|
||||||
|
|
||||||
|
Doorkeeper::AccessToken.where("scopes LIKE '%#{old_scope}%'").in_batches do |access_tokens|
|
||||||
|
access_tokens.update_all("scopes = replace(scopes, '#{old_scope}', '#{new_scope}')")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[7.1].define(version: 2024_05_22_041528) do
|
ActiveRecord::Schema[7.1].define(version: 2024_06_03_195202) do
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
|
||||||
|
|
|
@ -130,11 +130,20 @@ namespace :tests do
|
||||||
# This is checking the attribute rather than the method, to avoid the legacy fallback
|
# This is checking the attribute rather than the method, to avoid the legacy fallback
|
||||||
# and ensure the data has been migrated
|
# and ensure the data has been migrated
|
||||||
unless Account.find_local('qcuser').user[:otp_secret] == 'anotpsecretthatshouldbeencrypted'
|
unless Account.find_local('qcuser').user[:otp_secret] == 'anotpsecretthatshouldbeencrypted'
|
||||||
puts "DEBUG: #{Account.find_local('qcuser').user.inspect}"
|
|
||||||
puts 'OTP secret for user not preserved as expected'
|
puts 'OTP secret for user not preserved as expected'
|
||||||
exit(1)
|
exit(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
unless Doorkeeper::Application.find(2)[:scopes] == 'write:accounts profile'
|
||||||
|
puts 'Application OAuth scopes not rewritten as expected'
|
||||||
|
exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
unless Doorkeeper::Application.find(2).access_tokens.first[:scopes] == 'write:accounts profile'
|
||||||
|
puts 'OAuth access token scopes not rewritten as expected'
|
||||||
|
exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
puts 'No errors found. Database state is consistent with a successful migration process.'
|
puts 'No errors found. Database state is consistent with a successful migration process.'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -152,6 +161,23 @@ namespace :tests do
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'https://example.com/users/foobar', 'foobar@example.com', now(), now()),
|
(1, 'https://example.com/users/foobar', 'foobar@example.com', now(), now()),
|
||||||
(1, 'https://example.com/users/foobar', 'foobar@example.com', now(), now());
|
(1, 'https://example.com/users/foobar', 'foobar@example.com', now(), now());
|
||||||
|
|
||||||
|
/* Doorkeeper records
|
||||||
|
While the `read:me` scope was technically not valid in 3.3.0,
|
||||||
|
it is still useful for the purposes of testing the `ChangeReadMeScopeToProfile`
|
||||||
|
migration.
|
||||||
|
*/
|
||||||
|
|
||||||
|
INSERT INTO "oauth_applications"
|
||||||
|
(id, name, uid, secret, redirect_uri, scopes, created_at, updated_at)
|
||||||
|
VALUES
|
||||||
|
(2, 'foo', 'foo', 'foo', 'https://example.com/#foo', 'write:accounts read:me', now(), now()),
|
||||||
|
(3, 'bar', 'bar', 'bar', 'https://example.com/#bar', 'read:me', now(), now());
|
||||||
|
|
||||||
|
INSERT INTO "oauth_access_tokens"
|
||||||
|
(token, application_id, scopes, resource_owner_id, created_at)
|
||||||
|
VALUES
|
||||||
|
('secret', 2, 'write:accounts read:me', 4, now());
|
||||||
SQL
|
SQL
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,12 @@ describe ScopeTransformer do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with scope "profile"' do
|
||||||
|
let(:input) { 'profile' }
|
||||||
|
|
||||||
|
it_behaves_like 'a scope', nil, 'profile', 'read'
|
||||||
|
end
|
||||||
|
|
||||||
context 'with scope "read"' do
|
context 'with scope "read"' do
|
||||||
let(:input) { 'read' }
|
let(:input) { 'read' }
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,8 @@ RSpec.describe 'credentials API' do
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'allows the read:me scope' do
|
describe 'allows the profile scope' do
|
||||||
let(:scopes) { 'read:me' }
|
let(:scopes) { 'profile' }
|
||||||
|
|
||||||
it 'returns the response successfully' do
|
it 'returns the response successfully' do
|
||||||
subject
|
subject
|
||||||
|
|
Loading…
Reference in New Issue