Add user block api call
This commit is contained in:
parent
fd20647320
commit
6569ed24e4
6 changed files with 202 additions and 4 deletions
|
@ -43,7 +43,9 @@ class ApiAbility
|
||||||
|
|
||||||
can :destroy, Note if scopes.include?("write_notes")
|
can :destroy, Note if scopes.include?("write_notes")
|
||||||
|
|
||||||
can :redact, [OldNode, OldWay, OldRelation] if user&.terms_agreed? && scopes.include?("write_redactions")
|
can :redact, [OldNode, OldWay, OldRelation] if user.terms_agreed? && scopes.include?("write_redactions")
|
||||||
|
|
||||||
|
can :create, UserBlock if scopes.include?("write_blocks")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
module Api
|
module Api
|
||||||
class UserBlocksController < ApiController
|
class UserBlocksController < ApiController
|
||||||
|
before_action :check_api_writable, :only => :create
|
||||||
|
before_action :authorize, :only => :create
|
||||||
|
|
||||||
authorize_resource
|
authorize_resource
|
||||||
|
|
||||||
before_action :set_request_formats
|
before_action :set_request_formats
|
||||||
|
@ -11,5 +14,33 @@ module Api
|
||||||
rescue ActiveRecord::RecordNotFound
|
rescue ActiveRecord::RecordNotFound
|
||||||
raise OSM::APINotFoundError
|
raise OSM::APINotFoundError
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
raise OSM::APIBadUserInput, "No user was given" unless params[:user]
|
||||||
|
|
||||||
|
user = User.visible.find_by(:id => params[:user])
|
||||||
|
raise OSM::APINotFoundError unless user
|
||||||
|
raise OSM::APIBadUserInput, "No reason was given" unless params[:reason]
|
||||||
|
raise OSM::APIBadUserInput, "No period was given" unless params[:period]
|
||||||
|
|
||||||
|
period = Integer(params[:period], :exception => false)
|
||||||
|
raise OSM::APIBadUserInput, "Period should be a number of hours" unless period
|
||||||
|
|
||||||
|
max_period = UserBlock::PERIODS.max
|
||||||
|
raise OSM::APIBadUserInput, "Period must be between 0 and #{max_period}" if period.negative? || period > max_period
|
||||||
|
raise OSM::APIBadUserInput, "Needs_view must be true if provided" unless params[:needs_view].nil? || params[:needs_view] == "true"
|
||||||
|
|
||||||
|
ends_at = Time.now.utc + period.hours
|
||||||
|
needs_view = params[:needs_view] == "true"
|
||||||
|
@user_block = UserBlock.create(
|
||||||
|
:user => user,
|
||||||
|
:creator => current_user,
|
||||||
|
:reason => params[:reason],
|
||||||
|
:ends_at => ends_at,
|
||||||
|
:deactivates_at => (ends_at unless needs_view),
|
||||||
|
:needs_view => needs_view
|
||||||
|
)
|
||||||
|
render :show
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2713,6 +2713,7 @@ en:
|
||||||
write_gpx: Upload GPS traces
|
write_gpx: Upload GPS traces
|
||||||
write_notes: Modify notes
|
write_notes: Modify notes
|
||||||
write_redactions: Redact map data
|
write_redactions: Redact map data
|
||||||
|
write_blocks: Create and revoke user blocks
|
||||||
read_email: Read user email address
|
read_email: Read user email address
|
||||||
consume_messages: Read, update status and delete user messages
|
consume_messages: Read, update status and delete user messages
|
||||||
send_messages: Send private messages to other users
|
send_messages: Send private messages to other users
|
||||||
|
|
|
@ -121,7 +121,7 @@ OpenStreetMap::Application.routes.draw do
|
||||||
resource :subscription, :only => [:create, :destroy], :controller => "note_subscriptions"
|
resource :subscription, :only => [:create, :destroy], :controller => "note_subscriptions"
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :user_blocks, :only => :show, :id => /\d+/, :controller => "user_blocks"
|
resources :user_blocks, :only => [:show, :create], :id => /\d+/, :controller => "user_blocks"
|
||||||
namespace :user_blocks, :path => "user/blocks" do
|
namespace :user_blocks, :path => "user/blocks" do
|
||||||
resource :active_list, :path => "active", :only => :show
|
resource :active_list, :path => "active", :only => :show
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
module Oauth
|
module Oauth
|
||||||
SCOPES = %w[
|
SCOPES = %w[
|
||||||
read_prefs write_prefs write_diary
|
read_prefs write_prefs write_diary
|
||||||
write_api write_changeset_comments read_gpx write_gpx write_notes write_redactions
|
write_api write_changeset_comments read_gpx write_gpx write_notes write_redactions write_blocks
|
||||||
consume_messages send_messages openid
|
consume_messages send_messages openid
|
||||||
].freeze
|
].freeze
|
||||||
PRIVILEGED_SCOPES = %w[read_email skip_authorization].freeze
|
PRIVILEGED_SCOPES = %w[read_email skip_authorization].freeze
|
||||||
MODERATOR_SCOPES = %w[write_redactions].freeze
|
MODERATOR_SCOPES = %w[write_redactions write_blocks].freeze
|
||||||
|
|
||||||
class Scope
|
class Scope
|
||||||
attr_reader :name
|
attr_reader :name
|
||||||
|
|
|
@ -3,6 +3,10 @@ require "test_helper"
|
||||||
module Api
|
module Api
|
||||||
class UserBlocksControllerTest < ActionDispatch::IntegrationTest
|
class UserBlocksControllerTest < ActionDispatch::IntegrationTest
|
||||||
def test_routes
|
def test_routes
|
||||||
|
assert_routing(
|
||||||
|
{ :path => "/api/0.6/user_blocks", :method => :post },
|
||||||
|
{ :controller => "api/user_blocks", :action => "create" }
|
||||||
|
)
|
||||||
assert_routing(
|
assert_routing(
|
||||||
{ :path => "/api/0.6/user_blocks/1", :method => :get },
|
{ :path => "/api/0.6/user_blocks/1", :method => :get },
|
||||||
{ :controller => "api/user_blocks", :action => "show", :id => "1" }
|
{ :controller => "api/user_blocks", :action => "show", :id => "1" }
|
||||||
|
@ -43,5 +47,165 @@ module Api
|
||||||
assert_response :not_found
|
assert_response :not_found
|
||||||
assert_equal "text/plain", @response.media_type
|
assert_equal "text/plain", @response.media_type
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_create_no_permission
|
||||||
|
blocked_user = create(:user)
|
||||||
|
assert_empty blocked_user.blocks
|
||||||
|
|
||||||
|
post api_user_blocks_path(:user => blocked_user.id, :reason => "because", :period => 1)
|
||||||
|
assert_response :unauthorized
|
||||||
|
assert_empty blocked_user.blocks
|
||||||
|
|
||||||
|
regular_creator_user = create(:user)
|
||||||
|
auth_header = bearer_authorization_header(regular_creator_user, :scopes => %w[read_prefs])
|
||||||
|
post api_user_blocks_path(:user => blocked_user.id, :reason => "because", :period => 1), :headers => auth_header
|
||||||
|
assert_response :forbidden
|
||||||
|
assert_empty blocked_user.blocks
|
||||||
|
|
||||||
|
auth_header = bearer_authorization_header(regular_creator_user, :scopes => %w[read_prefs write_blocks])
|
||||||
|
post api_user_blocks_path(:user => blocked_user.id, :reason => "because", :period => 1), :headers => auth_header
|
||||||
|
assert_response :forbidden
|
||||||
|
assert_empty blocked_user.blocks
|
||||||
|
|
||||||
|
moderator_creator_user = create(:moderator_user)
|
||||||
|
auth_header = bearer_authorization_header(moderator_creator_user, :scopes => %w[read_prefs])
|
||||||
|
post api_user_blocks_path(:user => blocked_user.id, :reason => "because", :period => 1), :headers => auth_header
|
||||||
|
assert_response :forbidden
|
||||||
|
assert_empty blocked_user.blocks
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create_invalid_because_no_user
|
||||||
|
blocked_user = create(:user, :deleted)
|
||||||
|
assert_empty blocked_user.blocks
|
||||||
|
|
||||||
|
creator_user = create(:moderator_user)
|
||||||
|
auth_header = bearer_authorization_header(creator_user, :scopes => %w[read_prefs write_blocks])
|
||||||
|
post api_user_blocks_path(:reason => "because", :period => 1), :headers => auth_header
|
||||||
|
assert_response :bad_request
|
||||||
|
assert_equal "text/plain", @response.media_type
|
||||||
|
assert_equal "No user was given", @response.body
|
||||||
|
|
||||||
|
assert_empty blocked_user.blocks
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create_invalid_because_user_is_unknown
|
||||||
|
creator_user = create(:moderator_user)
|
||||||
|
auth_header = bearer_authorization_header(creator_user, :scopes => %w[read_prefs write_blocks])
|
||||||
|
post api_user_blocks_path(:user => 0, :reason => "because", :period => 1), :headers => auth_header
|
||||||
|
assert_response :not_found
|
||||||
|
assert_equal "text/plain", @response.media_type
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create_invalid_because_user_is_deleted
|
||||||
|
blocked_user = create(:user, :deleted)
|
||||||
|
assert_empty blocked_user.blocks
|
||||||
|
|
||||||
|
creator_user = create(:moderator_user)
|
||||||
|
auth_header = bearer_authorization_header(creator_user, :scopes => %w[read_prefs write_blocks])
|
||||||
|
post api_user_blocks_path(:user => blocked_user.id, :reason => "because", :period => 1), :headers => auth_header
|
||||||
|
assert_response :not_found
|
||||||
|
assert_equal "text/plain", @response.media_type
|
||||||
|
|
||||||
|
assert_empty blocked_user.blocks
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create_invalid_because_missing_reason
|
||||||
|
create_with_params_and_assert_bad_request("No reason was given", :period => "10")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create_invalid_because_missing_period
|
||||||
|
create_with_params_and_assert_bad_request("No period was given", :reason => "because")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create_invalid_because_non_numeric_period
|
||||||
|
create_with_params_and_assert_bad_request("Period should be a number of hours", :reason => "because", :period => "one hour")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create_invalid_because_negative_period
|
||||||
|
create_with_params_and_assert_bad_request("Period must be between 0 and #{UserBlock::PERIODS.max}", :reason => "go away", :period => "-1")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create_invalid_because_excessive_period
|
||||||
|
create_with_params_and_assert_bad_request("Period must be between 0 and #{UserBlock::PERIODS.max}", :reason => "go away", :period => "10000000")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create_invalid_because_unknown_needs_view
|
||||||
|
create_with_params_and_assert_bad_request("Needs_view must be true if provided", :reason => "because", :period => "1", :needs_view => "maybe")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create_success
|
||||||
|
blocked_user = create(:user)
|
||||||
|
creator_user = create(:moderator_user)
|
||||||
|
|
||||||
|
assert_empty blocked_user.blocks
|
||||||
|
auth_header = bearer_authorization_header(creator_user, :scopes => %w[read_prefs write_blocks])
|
||||||
|
post api_user_blocks_path(:user => blocked_user.id, :reason => "because", :period => 1), :headers => auth_header
|
||||||
|
assert_response :success
|
||||||
|
assert_equal 1, blocked_user.blocks.length
|
||||||
|
|
||||||
|
block = blocked_user.blocks.take
|
||||||
|
assert_predicate block, :active?
|
||||||
|
assert_equal "because", block.reason
|
||||||
|
assert_equal creator_user, block.creator
|
||||||
|
|
||||||
|
assert_equal "application/xml", @response.media_type
|
||||||
|
assert_select "osm>user_block", 1 do
|
||||||
|
assert_select ">@id", block.id.to_s
|
||||||
|
assert_select ">@needs_view", "false"
|
||||||
|
assert_select ">user", 1
|
||||||
|
assert_select ">user>@uid", blocked_user.id.to_s
|
||||||
|
assert_select ">creator", 1
|
||||||
|
assert_select ">creator>@uid", creator_user.id.to_s
|
||||||
|
assert_select ">revoker", 0
|
||||||
|
assert_select ">reason", 1
|
||||||
|
assert_select ">reason", "because"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create_success_with_needs_view
|
||||||
|
blocked_user = create(:user)
|
||||||
|
creator_user = create(:moderator_user)
|
||||||
|
|
||||||
|
assert_empty blocked_user.blocks
|
||||||
|
auth_header = bearer_authorization_header(creator_user, :scopes => %w[read_prefs write_blocks])
|
||||||
|
post api_user_blocks_path(:user => blocked_user.id, :reason => "because", :period => "1", :needs_view => "true"), :headers => auth_header
|
||||||
|
assert_response :success
|
||||||
|
assert_equal 1, blocked_user.blocks.length
|
||||||
|
|
||||||
|
block = blocked_user.blocks.take
|
||||||
|
assert_predicate block, :active?
|
||||||
|
assert_equal "because", block.reason
|
||||||
|
assert_equal creator_user, block.creator
|
||||||
|
|
||||||
|
assert_equal "application/xml", @response.media_type
|
||||||
|
assert_select "osm>user_block", 1 do
|
||||||
|
assert_select ">@id", block.id.to_s
|
||||||
|
assert_select ">@needs_view", "true"
|
||||||
|
assert_select ">user", 1
|
||||||
|
assert_select ">user>@uid", blocked_user.id.to_s
|
||||||
|
assert_select ">creator", 1
|
||||||
|
assert_select ">creator>@uid", creator_user.id.to_s
|
||||||
|
assert_select ">revoker", 0
|
||||||
|
assert_select ">reason", 1
|
||||||
|
assert_select ">reason", "because"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def create_with_params_and_assert_bad_request(message, **params)
|
||||||
|
blocked_user = create(:user)
|
||||||
|
assert_empty blocked_user.blocks
|
||||||
|
|
||||||
|
moderator_creator_user = create(:moderator_user)
|
||||||
|
auth_header = bearer_authorization_header(moderator_creator_user, :scopes => %w[read_prefs write_blocks])
|
||||||
|
|
||||||
|
post api_user_blocks_path({ :user => blocked_user.id }.merge(params)), :headers => auth_header
|
||||||
|
assert_response :bad_request
|
||||||
|
assert_equal "text/plain", @response.media_type
|
||||||
|
assert_equal message, @response.body
|
||||||
|
|
||||||
|
assert_empty blocked_user.blocks
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue