Update wordpress scopes and add ``session/scopes`` endpoint (#15366)

* Update wordpress scopes && add ``session/scopes`` endpointt

* Fix failing spec

* Add users#show scope to discourse_connect

* Update app/controllers/session_controller.rb

Co-authored-by: Roman Rizzi <rizziromanalejandro@gmail.com>

Co-authored-by: Roman Rizzi <rizziromanalejandro@gmail.com>
This commit is contained in:
Angus McLeod 2022-05-02 17:15:32 +02:00 committed by GitHub
parent fad94160c7
commit 9fc3d46003
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 54 additions and 4 deletions

View File

@ -598,6 +598,16 @@ class SessionController < ApplicationController
}
end
def scopes
if is_api?
key = request.env[Auth::DefaultCurrentUserProvider::HEADER_API_KEY]
api_key = ApiKey.active.with_key(key).first
render_serialized(api_key.api_key_scopes, ApiKeyScopeSerializer, root: 'scopes')
else
render body: nil, status: 404
end
end
protected
def normalized_login_param

View File

@ -64,6 +64,7 @@ class ApiKey < ActiveRecord::Base
def request_allowed?(env)
return false if allowed_ips.present? && allowed_ips.none? { |ip| ip.include?(Rack::Request.new(env).ip) }
return true if RouteMatcher.new(methods: :get, actions: "session#scopes").match?(env: env)
api_key_scopes.blank? || api_key_scopes.any? { |s| s.permits?(env) }
end

View File

@ -30,8 +30,7 @@ class ApiKeyScope < ActiveRecord::Base
read_lists: {
actions: list_actions, params: %i[category_id],
aliases: { category_id: :category_slug_path_with_id }
},
wordpress: { actions: %w[topics#wordpress], params: %i[topic_id] }
}
},
posts: {
edit: { actions: %w[posts#update], params: %i[id] }
@ -75,6 +74,12 @@ class ApiKeyScope < ActiveRecord::Base
list_user_badges: { actions: %w[user_badges#username], params: %i[username] },
assign_badge_to_user: { actions: %w[user_badges#create], params: %i[username] },
revoke_badge_from_user: { actions: %w[user_badges#destroy] },
},
wordpress: {
publishing: { actions: %w[site#site posts#create topics#update topics#status topics#show] },
commenting: { actions: %w[topics#wordpress] },
discourse_connect: { actions: %w[admin/users#sync_sso admin/users#log_out admin/users#index users#show] },
utilities: { actions: %w[users#create groups#index] }
}
}

View File

@ -4265,7 +4265,6 @@ en:
write: Create a new topic or post to an existing one.
update: Update a topic. Change the title, category, tags, etc.
read_lists: Read topic lists like top, new, latest, etc. RSS is also supported.
wordpress: Necessary for the WordPress wp-discourse plugin to work.
posts:
edit: Edit any post or a specific one.
categories:
@ -4293,6 +4292,11 @@ en:
list_user_badges: List user badges.
assign_badge_to_user: Assign a badge to a user.
revoke_badge_from_user: Revoke a badge from a user.
wordpress:
publishing: Necessary for the WP Discourse plugin publishing features (required).
commenting: Necessary for the WP Discourse plugin commenting features.
discourse_connect: Necessary for the WP Discourse plugin DiscourseConnect features.
utilities: Necessary if you use WP Discourse plugin Utilities.
web_hooks:
title: "Webhooks"

View File

@ -383,6 +383,7 @@ Discourse::Application.routes.draw do
if Rails.env.test?
post "session/2fa/test-action" => "session#test_second_factor_restricted_route"
end
get "session/scopes" => "session#scopes"
get "composer_messages" => "composer_messages#index"
resources :static

View File

@ -235,7 +235,7 @@ describe Admin::ApiController do
scopes = response.parsed_body['scopes']
expect(scopes.keys).to contain_exactly('topics', 'users', 'email', 'posts', 'uploads', 'global', 'badges', 'categories')
expect(scopes.keys).to contain_exactly('topics', 'users', 'email', 'posts', 'uploads', 'global', 'badges', 'categories', 'wordpress')
end
end
end

View File

@ -2628,4 +2628,33 @@ describe SessionController do
expect(response.status).to eq(401)
end
end
describe '#scopes' do
context "when not a valid api request" do
it "returns 404" do
get "/session/scopes.json"
expect(response.status).to eq(404)
end
end
context "when a valid api request" do
let(:admin) { Fabricate(:admin) }
let(:scope) { ApiKeyScope.new(resource: 'topics', action: 'read', allowed_parameters: { topic_id: '3' }) }
let(:api_key) { Fabricate(:api_key, user: admin, api_key_scopes: [scope]) }
it "returns the scopes of the api key" do
get "/session/scopes.json", headers: {
"Api-Key": api_key.key,
"Api-Username": admin.username
}
expect(response.status).to eq(200)
json = response.parsed_body
expect(json['scopes'].size).to eq(1)
expect(json['scopes'].first["resource"]).to eq("topics")
expect(json['scopes'].first["action"]).to eq("read")
expect(json['scopes'].first["allowed_parameters"]).to eq({ "topic_id": "3" }.as_json)
end
end
end
end