FEATURE: Extend topic update API scope to allow status updates (#19654)
Allow an API key created with topic:update API scope to make updates to topic status. This change also introduces an optional category_id scope param.
This commit is contained in:
parent
8a1b50f62d
commit
73ec80893d
|
@ -479,7 +479,12 @@ class TopicsController < ApplicationController
|
|||
enabled = params[:enabled] == "true"
|
||||
|
||||
check_for_status_presence(:status, status)
|
||||
@topic = Topic.find_by(id: topic_id)
|
||||
@topic =
|
||||
if params[:category_id]
|
||||
Topic.find_by(id: topic_id, category_id: params[:category_id].to_i)
|
||||
else
|
||||
Topic.find_by(id: topic_id)
|
||||
end
|
||||
|
||||
case status
|
||||
when "closed"
|
||||
|
|
|
@ -28,8 +28,8 @@ class ApiKeyScope < ActiveRecord::Base
|
|||
params: %i[topic_id],
|
||||
},
|
||||
update: {
|
||||
actions: %w[topics#update],
|
||||
params: %i[topic_id],
|
||||
actions: %w[topics#update topics#status],
|
||||
params: %i[topic_id category_id],
|
||||
},
|
||||
read: {
|
||||
actions: %w[topics#show topics#feed topics#posts],
|
||||
|
|
|
@ -4670,7 +4670,7 @@ en:
|
|||
topics:
|
||||
read: Read a topic or a specific post in it. RSS is also supported.
|
||||
write: Create a new topic or post to an existing one.
|
||||
update: Update a topic. Change the title, category, tags, etc.
|
||||
update: Update a topic. Change the title, category, tags, status, archetype, featured_link etc.
|
||||
read_lists: Read topic lists like top, new, latest, etc. RSS is also supported.
|
||||
posts:
|
||||
edit: Edit any post or a specific one.
|
||||
|
|
|
@ -59,7 +59,7 @@ class RouteMatcher
|
|||
|
||||
params.all? do |param|
|
||||
param_alias = aliases&.[](param)
|
||||
allowed_values = [allowed_param_values[param.to_s]].flatten
|
||||
allowed_values = [allowed_param_values.fetch(param.to_s, [])].flatten
|
||||
|
||||
value = requested_params[param.to_s]
|
||||
alias_value = requested_params[param_alias.to_s]
|
||||
|
|
|
@ -1037,6 +1037,99 @@ RSpec.describe TopicsController do
|
|||
expect(topic.posts.last.action_code).to eq("visible.enabled")
|
||||
end
|
||||
end
|
||||
|
||||
context "with API key" do
|
||||
let(:api_key) { Fabricate(:api_key, user: moderator, created_by: moderator) }
|
||||
|
||||
context "when key scope has restricted params" do
|
||||
before do
|
||||
ApiKeyScope.create(
|
||||
resource: "topics",
|
||||
action: "update",
|
||||
api_key_id: api_key.id,
|
||||
allowed_parameters: {
|
||||
"category_id" => ["#{topic.category_id}"],
|
||||
},
|
||||
)
|
||||
end
|
||||
|
||||
it "fails to update topic status in an unpermitted category" do
|
||||
put "/t/#{topic.id}/status.json",
|
||||
params: {
|
||||
status: "closed",
|
||||
enabled: "true",
|
||||
category_id: tracked_category.id,
|
||||
},
|
||||
headers: {
|
||||
"HTTP_API_KEY" => api_key.key,
|
||||
"HTTP_API_USERNAME" => api_key.user.username,
|
||||
}
|
||||
|
||||
expect(response.status).to eq(403)
|
||||
expect(response.body).to include(I18n.t("invalid_access"))
|
||||
expect(topic.reload.closed).to eq(false)
|
||||
end
|
||||
|
||||
it "fails without a category_id" do
|
||||
put "/t/#{topic.id}/status.json",
|
||||
params: {
|
||||
status: "closed",
|
||||
enabled: "true",
|
||||
},
|
||||
headers: {
|
||||
"HTTP_API_KEY" => api_key.key,
|
||||
"HTTP_API_USERNAME" => api_key.user.username,
|
||||
}
|
||||
|
||||
expect(response.status).to eq(403)
|
||||
expect(response.body).to include(I18n.t("invalid_access"))
|
||||
expect(topic.reload.closed).to eq(false)
|
||||
end
|
||||
|
||||
it "updates topic status in a permitted category" do
|
||||
put "/t/#{topic.id}/status.json",
|
||||
params: {
|
||||
status: "closed",
|
||||
enabled: "true",
|
||||
category_id: topic.category_id,
|
||||
},
|
||||
headers: {
|
||||
"HTTP_API_KEY" => api_key.key,
|
||||
"HTTP_API_USERNAME" => api_key.user.username,
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(topic.reload.closed).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when key scope has no param restrictions" do
|
||||
before do
|
||||
ApiKeyScope.create(
|
||||
resource: "topics",
|
||||
action: "update",
|
||||
api_key_id: api_key.id,
|
||||
allowed_parameters: {
|
||||
},
|
||||
)
|
||||
end
|
||||
|
||||
it "updates topic status" do
|
||||
put "/t/#{topic.id}/status.json",
|
||||
params: {
|
||||
status: "closed",
|
||||
enabled: "true",
|
||||
},
|
||||
headers: {
|
||||
"HTTP_API_KEY" => api_key.key,
|
||||
"HTTP_API_USERNAME" => api_key.user.username,
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(topic.reload.closed).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#destroy_timings" do
|
||||
|
|
Loading…
Reference in New Issue