From: Tom Hughes Date: Sat, 15 Feb 2025 11:15:25 +0000 (+0000) Subject: Merge remote-tracking branch 'upstream/pull/5452' X-Git-Tag: live~300 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/5ca24de0d04bef18353d3f0ecdd069d0bca34ce2?hp=12920987f560a074381d4c8bae2c756db16647d8 Merge remote-tracking branch 'upstream/pull/5452' --- diff --git a/app/abilities/api_ability.rb b/app/abilities/api_ability.rb index a0340c5cd..7bbd9889a 100644 --- a/app/abilities/api_ability.rb +++ b/app/abilities/api_ability.rb @@ -30,6 +30,8 @@ class ApiAbility can [:read, :update, :destroy], Message if scopes.include?("consume_messages") can :create, Message if scopes.include?("send_messages") + can :read, :active_user_blocks_list if scopes.include?("read_prefs") + if user.terms_agreed? can [:create, :update, :upload, :close, :subscribe, :unsubscribe], Changeset if scopes.include?("write_map") can :create, ChangesetComment if scopes.include?("write_changeset_comments") diff --git a/app/controllers/api/user_blocks/active_lists_controller.rb b/app/controllers/api/user_blocks/active_lists_controller.rb new file mode 100644 index 000000000..535d7393a --- /dev/null +++ b/app/controllers/api/user_blocks/active_lists_controller.rb @@ -0,0 +1,16 @@ +module Api + module UserBlocks + class ActiveListsController < ApiController + before_action -> { authorize(:skip_blocks => true) } + + authorize_resource :class => :active_user_blocks_list + + before_action :set_request_formats + + def show + @user_blocks = current_user.blocks.active.order(:id => :desc) + @skip_reason = true + end + end + end +end diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 0fe1ba18d..9b2ee9b53 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -49,9 +49,9 @@ class ApiController < ApplicationController end end - def authorize(errormessage: "Couldn't authenticate you", skip_terms: false) + def authorize(errormessage: "Couldn't authenticate you", skip_blocks: false, skip_terms: false) # make the current_user object from any auth sources we have - setup_user_auth(:skip_terms => skip_terms) + setup_user_auth(:skip_blocks => skip_blocks, :skip_terms => skip_terms) # handle authenticate pass/fail unless current_user @@ -97,7 +97,7 @@ class ApiController < ApplicationController # sets up the current_user for use by other methods. this is mostly called # from the authorize method, but can be called elsewhere if authorisation # is optional. - def setup_user_auth(skip_terms: false) + def setup_user_auth(skip_blocks: false, skip_terms: false) logger.info " setup_user_auth" # try and setup using OAuth self.current_user = User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token&.accessible? @@ -105,13 +105,15 @@ class ApiController < ApplicationController # have we identified the user? if current_user # check if the user has been banned - user_block = current_user.blocks.active.take - unless user_block.nil? - set_locale - if user_block.zero_hour? - report_error t("application.setup_user_auth.blocked_zero_hour"), :forbidden - else - report_error t("application.setup_user_auth.blocked"), :forbidden + unless skip_blocks + user_block = current_user.blocks.active.take + unless user_block.nil? + set_locale + if user_block.zero_hour? + report_error t("application.setup_user_auth.blocked_zero_hour"), :forbidden + else + report_error t("application.setup_user_auth.blocked"), :forbidden + end end end diff --git a/app/views/api/user_blocks/_user_block.json.jbuilder b/app/views/api/user_blocks/_user_block.json.jbuilder index 3288dd6ad..2e65b52da 100644 --- a/app/views/api/user_blocks/_user_block.json.jbuilder +++ b/app/views/api/user_blocks/_user_block.json.jbuilder @@ -1,13 +1,11 @@ -json.user_block do - json.id user_block.id - json.created_at user_block.created_at.xmlschema - json.updated_at user_block.updated_at.xmlschema - json.ends_at user_block.ends_at.xmlschema - json.needs_view user_block.needs_view +json.id user_block.id +json.created_at user_block.created_at.xmlschema +json.updated_at user_block.updated_at.xmlschema +json.ends_at user_block.ends_at.xmlschema +json.needs_view user_block.needs_view - json.user :uid => user_block.user_id, :user => user_block.user.display_name - json.creator :uid => user_block.creator_id, :user => user_block.creator.display_name - json.revoker :uid => user_block.revoker_id, :user => user_block.revoker.display_name if user_block.revoker +json.user :uid => user_block.user_id, :user => user_block.user.display_name +json.creator :uid => user_block.creator_id, :user => user_block.creator.display_name +json.revoker :uid => user_block.revoker_id, :user => user_block.revoker.display_name if user_block.revoker - json.reason user_block.reason -end +json.reason user_block.reason unless @skip_reason diff --git a/app/views/api/user_blocks/_user_block.xml.builder b/app/views/api/user_blocks/_user_block.xml.builder index a41dc56d7..288e89663 100644 --- a/app/views/api/user_blocks/_user_block.xml.builder +++ b/app/views/api/user_blocks/_user_block.xml.builder @@ -10,5 +10,6 @@ xml.user_block(attrs) do xml.user :uid => user_block.user_id, :user => user_block.user.display_name xml.creator :uid => user_block.creator_id, :user => user_block.creator.display_name xml.revoker :uid => user_block.revoker_id, :user => user_block.revoker.display_name if user_block.revoker - xml.reason user_block.reason + + xml.reason user_block.reason unless @skip_reason end diff --git a/app/views/api/user_blocks/active_lists/show.json.jbuilder b/app/views/api/user_blocks/active_lists/show.json.jbuilder new file mode 100644 index 000000000..aaf1c2119 --- /dev/null +++ b/app/views/api/user_blocks/active_lists/show.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.user_blocks do + json.array! @user_blocks, :partial => "api/user_blocks/user_block", :as => :user_block +end diff --git a/app/views/api/user_blocks/active_lists/show.xml.builder b/app/views/api/user_blocks/active_lists/show.xml.builder new file mode 100644 index 000000000..907392646 --- /dev/null +++ b/app/views/api/user_blocks/active_lists/show.xml.builder @@ -0,0 +1,5 @@ +xml.instruct! + +xml.osm(OSM::API.new.xml_root_attributes) do |osm| + osm << (render(:partial => "api/user_blocks/user_block", :collection => @user_blocks) || "") +end diff --git a/app/views/api/user_blocks/show.json.jbuilder b/app/views/api/user_blocks/show.json.jbuilder index 6cfc0ded5..a90b7cd19 100644 --- a/app/views/api/user_blocks/show.json.jbuilder +++ b/app/views/api/user_blocks/show.json.jbuilder @@ -1,3 +1,5 @@ json.partial! "api/root_attributes" -json.partial! @user_block +json.user_block do + json.partial! @user_block +end diff --git a/config/routes.rb b/config/routes.rb index 54bf037cf..45fc19f2c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -122,6 +122,9 @@ OpenStreetMap::Application.routes.draw do end resources :user_blocks, :only => :show, :id => /\d+/, :controller => "user_blocks" + namespace :user_blocks, :path => "user/blocks" do + resource :active_list, :path => "active", :only => :show + end end # Data browsing diff --git a/test/controllers/api/user_blocks/active_lists_controller_test.rb b/test/controllers/api/user_blocks/active_lists_controller_test.rb new file mode 100644 index 000000000..6856dca8d --- /dev/null +++ b/test/controllers/api/user_blocks/active_lists_controller_test.rb @@ -0,0 +1,78 @@ +require "test_helper" + +module Api + module UserBlocks + class ActiveListsControllerTest < ActionDispatch::IntegrationTest + ## + # test all routes which lead to this controller + def test_routes + assert_routing( + { :path => "/api/0.6/user/blocks/active", :method => :get }, + { :controller => "api/user_blocks/active_lists", :action => "show" } + ) + assert_routing( + { :path => "/api/0.6/user/blocks/active.json", :method => :get }, + { :controller => "api/user_blocks/active_lists", :action => "show", :format => "json" } + ) + end + + def test_show_no_auth_header + get api_user_blocks_active_list_path + assert_response :unauthorized + end + + def test_show_no_permission + user = create(:user) + user_auth_header = bearer_authorization_header(user, :scopes => %w[]) + + get api_user_blocks_active_list_path, :headers => user_auth_header + assert_response :forbidden + end + + def test_show_empty + user = create(:user) + user_auth_header = bearer_authorization_header(user, :scopes => %w[read_prefs]) + create(:user_block, :expired, :user => user) + + get api_user_blocks_active_list_path, :headers => user_auth_header + assert_response :success + assert_dom "user_block", :count => 0 + end + + def test_show + user = create(:moderator_user) + user_auth_header = bearer_authorization_header(user, :scopes => %w[read_prefs]) + create(:user_block, :expired, :user => user) + block0 = create(:user_block, :user => user) + block1 = create(:user_block, :user => user) + create(:user_block) + create(:user_block, :creator => user) + + get api_user_blocks_active_list_path, :headers => user_auth_header + assert_response :success + assert_dom "user_block", :count => 2 do |dom_blocks| + assert_dom dom_blocks[0], "> @id", block1.id.to_s + assert_dom dom_blocks[1], "> @id", block0.id.to_s + end + end + + def test_show_json + user = create(:moderator_user) + user_auth_header = bearer_authorization_header(user, :scopes => %w[read_prefs]) + create(:user_block, :expired, :user => user) + block0 = create(:user_block, :user => user) + block1 = create(:user_block, :user => user) + create(:user_block) + create(:user_block, :creator => user) + + get api_user_blocks_active_list_path(:format => "json"), :headers => user_auth_header + assert_response :success + js = ActiveSupport::JSON.decode(@response.body) + assert_not_nil js + assert_equal 2, js["user_blocks"].count + assert_equal block1.id, js["user_blocks"][0]["id"] + assert_equal block0.id, js["user_blocks"][1]["id"] + end + end + end +end