From: Tom Hughes Date: Wed, 9 Jan 2019 17:27:16 +0000 (+0000) Subject: Merge remote-tracking branch 'upstream/pull/2109' X-Git-Tag: live~3819 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/6c2432ae423c6744b8443c63d0e02e1ccc2d3011?hp=b184b39f344b7298370c246d8f45d10f48d01a7e Merge remote-tracking branch 'upstream/pull/2109' --- diff --git a/app/abilities/ability.rb b/app/abilities/ability.rb index 7138374f3..09e9be2cf 100644 --- a/app/abilities/ability.rb +++ b/app/abilities/ability.rb @@ -4,13 +4,20 @@ class Ability include CanCan::Ability def initialize(user) + can [:relation, :relation_history, :way, :way_history, :node, :node_history, :changeset, :note], :browse + can [:index, :feed, :read, :download, :query], Changeset can :index, ChangesetComment + can :search, :direction can [:index, :permalink, :edit, :help, :fixthemap, :offline, :export, :about, :preview, :copyright, :key, :id], :site can [:index, :rss, :show, :comments], DiaryEntry + can [:finish, :embed], :export can [:search, :search_latlon, :search_ca_postcode, :search_osm_nominatim, :search_geonames, :search_osm_nominatim_reverse, :search_geonames_reverse], :geocoder can [:index, :create, :comment, :feed, :show, :search, :mine], Note can [:index, :show], Redaction + can [:search_all, :search_nodes, :search_ways, :search_relations], :search + can [:trackpoints], :swf + can [:index, :show, :data, :georss, :picture, :icon], Trace can [:terms, :api_users, :login, :logout, :new, :create, :save, :confirm, :confirm_resend, :confirm_email, :lost_password, :reset_password, :show, :api_read, :auth_success, :auth_failure], User can [:index, :show, :blocks_on, :blocks_by], UserBlock @@ -21,10 +28,12 @@ class Ability can [:new, :create, :reply, :show, :inbox, :outbox, :mark, :destroy], Message can [:close, :reopen], Note can [:new, :create], Report + can [:mine, :new, :create, :edit, :update, :delete, :api_create, :api_read, :api_update, :api_delete, :api_data], Trace can [:account, :go_public, :make_friend, :remove_friend, :api_details, :api_gpx_files], User can [:read, :read_one, :update, :update_one, :delete_one], UserPreference - if user.terms_agreed? || !REQUIRE_TERMS_AGREED # rubocop:disable Style/IfUnlessModifier + if user.terms_agreed? || !REQUIRE_TERMS_AGREED + can [:create, :update, :upload, :close, :subscribe, :unsubscribe, :expand_bbox], Changeset can :create, ChangesetComment end diff --git a/app/abilities/capability.rb b/app/abilities/capability.rb index ae30a0ebd..556d4036c 100644 --- a/app/abilities/capability.rb +++ b/app/abilities/capability.rb @@ -5,12 +5,15 @@ class Capability def initialize(token) can [:create, :comment, :close, :reopen], Note if capability?(token, :allow_write_notes) + can [:api_read, :api_data], Trace if capability?(token, :allow_read_gpx) + can [:api_create, :api_update, :api_delete], Trace if capability?(token, :allow_write_gpx) can [:api_details], User if capability?(token, :allow_read_prefs) can [:api_gpx_files], User if capability?(token, :allow_read_gpx) can [:read, :read_one], UserPreference if capability?(token, :allow_read_prefs) can [:update, :update_one, :delete_one], UserPreference if capability?(token, :allow_write_prefs) if token&.user&.terms_agreed? || !REQUIRE_TERMS_AGREED + can [:create, :update, :upload, :close, :subscribe, :unsubscribe, :expand_bbox], Changeset if capability?(token, :allow_write_api) can :create, ChangesetComment if capability?(token, :allow_write_api) end diff --git a/app/controllers/amf_controller.rb b/app/controllers/amf_controller.rb index 4f6adae5d..fdad432a8 100644 --- a/app/controllers/amf_controller.rb +++ b/app/controllers/amf_controller.rb @@ -41,6 +41,11 @@ class AmfController < ApplicationController skip_before_action :verify_authenticity_token before_action :check_api_writable + # AMF Controller implements its own authentication and authorization checks + # completely independently of the rest of the codebase, so best just to let + # it keep doing its own thing. + skip_authorization_check + # Main AMF handlers: process the raw AMF string (using AMF library) and # calls each action (private method) accordingly. diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index d97feace2..90883376c 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -253,48 +253,9 @@ class ApiController < ApplicationController # * maximum area that can be requested in a bbox request in square degrees # * number of tracepoints that are returned in each tracepoints page def capabilities - doc = OSM::API.new.get_xml_doc - - api = XML::Node.new "api" - version = XML::Node.new "version" - version["minimum"] = API_VERSION.to_s - version["maximum"] = API_VERSION.to_s - api << version - area = XML::Node.new "area" - area["maximum"] = MAX_REQUEST_AREA.to_s - api << area - notearea = XML::Node.new "note_area" - notearea["maximum"] = MAX_NOTE_REQUEST_AREA.to_s - api << notearea - tracepoints = XML::Node.new "tracepoints" - tracepoints["per_page"] = TRACEPOINTS_PER_PAGE.to_s - api << tracepoints - waynodes = XML::Node.new "waynodes" - waynodes["maximum"] = MAX_NUMBER_OF_WAY_NODES.to_s - api << waynodes - changesets = XML::Node.new "changesets" - changesets["maximum_elements"] = Changeset::MAX_ELEMENTS.to_s - api << changesets - timeout = XML::Node.new "timeout" - timeout["seconds"] = API_TIMEOUT.to_s - api << timeout - status = XML::Node.new "status" - status["database"] = database_status.to_s - status["api"] = api_status.to_s - status["gpx"] = gpx_status.to_s - api << status - doc.root << api - policy = XML::Node.new "policy" - blacklist = XML::Node.new "imagery" - IMAGERY_BLACKLIST.each do |url_regex| - xnd = XML::Node.new "blacklist" - xnd["regex"] = url_regex.to_s - blacklist << xnd - end - policy << blacklist - doc.root << policy - - render :xml => doc.to_s + @database_status = database_status + @api_status = api_status + @gpx_status = gpx_status end # External apps that use the api are able to query which permissions diff --git a/app/controllers/browse_controller.rb b/app/controllers/browse_controller.rb index 6eb967568..0fccbb506 100644 --- a/app/controllers/browse_controller.rb +++ b/app/controllers/browse_controller.rb @@ -6,6 +6,7 @@ class BrowseController < ApplicationController before_action(:except => [:query]) { |c| c.check_database_readable(true) } before_action :require_oauth around_action :web_timeout + authorize_resource :class => false def relation @type = "relation" diff --git a/app/controllers/changesets_controller.rb b/app/controllers/changesets_controller.rb index e4fd593d7..97ff85f02 100644 --- a/app/controllers/changesets_controller.rb +++ b/app/controllers/changesets_controller.rb @@ -8,7 +8,10 @@ class ChangesetsController < ApplicationController before_action :authorize_web, :only => [:index, :feed] before_action :set_locale, :only => [:index, :feed] before_action :authorize, :only => [:create, :update, :upload, :close, :subscribe, :unsubscribe] - before_action :require_allow_write_api, :only => [:create, :update, :upload, :close, :subscribe, :unsubscribe] + before_action :api_deny_access_handler, :only => [:create, :update, :upload, :close, :subscribe, :unsubscribe, :expand_bbox] + + authorize_resource + before_action :require_public_data, :only => [:create, :update, :upload, :close, :subscribe, :unsubscribe] before_action :check_api_writable, :only => [:create, :update, :upload, :subscribe, :unsubscribe] before_action :check_api_readable, :except => [:create, :update, :upload, :download, :query, :index, :feed, :subscribe, :unsubscribe] diff --git a/app/controllers/directions_controller.rb b/app/controllers/directions_controller.rb index b04db6b6f..ec2327400 100644 --- a/app/controllers/directions_controller.rb +++ b/app/controllers/directions_controller.rb @@ -2,6 +2,7 @@ class DirectionsController < ApplicationController before_action :authorize_web before_action :set_locale before_action :require_oauth, :only => [:search] + authorize_resource :class => false def search render :layout => map_layout diff --git a/app/controllers/export_controller.rb b/app/controllers/export_controller.rb index afdf4d8d7..18ac15c10 100644 --- a/app/controllers/export_controller.rb +++ b/app/controllers/export_controller.rb @@ -2,6 +2,7 @@ class ExportController < ApplicationController before_action :authorize_web before_action :set_locale before_action :update_totp, :only => [:finish] + authorize_resource :class => false caches_page :embed diff --git a/app/controllers/geocoder_controller.rb b/app/controllers/geocoder_controller.rb index da5245687..b9cf8d096 100644 --- a/app/controllers/geocoder_controller.rb +++ b/app/controllers/geocoder_controller.rb @@ -6,6 +6,7 @@ class GeocoderController < ApplicationController before_action :authorize_web before_action :set_locale before_action :require_oauth, :only => [:search] + authorize_resource :class => false def search @params = normalize_params diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 0d40b6691..3a2e4040f 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -3,6 +3,7 @@ class SearchController < ApplicationController # Can search by tag k, v, or both (type->k,value->v) # Can search by name (k=name,v=....) skip_before_action :verify_authenticity_token + authorize_resource :class => false def search_all do_search(true, true, true) diff --git a/app/controllers/swf_controller.rb b/app/controllers/swf_controller.rb index 96237f029..1a424c387 100644 --- a/app/controllers/swf_controller.rb +++ b/app/controllers/swf_controller.rb @@ -1,6 +1,7 @@ class SwfController < ApplicationController skip_before_action :verify_authenticity_token before_action :check_api_readable + authorize_resource :class => false # to log: # RAILS_DEFAULT_LOGGER.error("Args: #{args[0]}, #{args[1]}, #{args[2]}, #{args[3]}") diff --git a/app/controllers/traces_controller.rb b/app/controllers/traces_controller.rb index b78ae2959..253bc4160 100644 --- a/app/controllers/traces_controller.rb +++ b/app/controllers/traces_controller.rb @@ -4,14 +4,15 @@ class TracesController < ApplicationController skip_before_action :verify_authenticity_token, :only => [:api_create, :api_read, :api_update, :api_delete, :api_data] before_action :authorize_web before_action :set_locale - before_action :require_user, :only => [:mine, :new, :create, :edit, :delete] before_action :authorize, :only => [:api_create, :api_read, :api_update, :api_delete, :api_data] + before_action :api_deny_access_handler, :only => [:api_create, :api_read, :api_update, :api_delete, :api_data] + + authorize_resource + before_action :check_database_readable, :except => [:api_read, :api_data] before_action :check_database_writable, :only => [:new, :create, :edit, :delete, :api_create, :api_update, :api_delete] before_action :check_api_readable, :only => [:api_read, :api_data] before_action :check_api_writable, :only => [:api_create, :api_update, :api_delete] - before_action :require_allow_read_gpx, :only => [:api_read, :api_data] - before_action :require_allow_write_gpx, :only => [:api_create, :api_update, :api_delete] before_action :offline_warning, :only => [:mine, :show] before_action :offline_redirect, :only => [:new, :create, :edit, :delete, :data, :api_create, :api_delete, :api_data] around_action :api_call_handle_error, :only => [:api_create, :api_read, :api_update, :api_delete, :api_data] diff --git a/app/views/api/capabilities.builder b/app/views/api/capabilities.builder new file mode 100644 index 000000000..3fa79058b --- /dev/null +++ b/app/views/api/capabilities.builder @@ -0,0 +1,22 @@ +xml.instruct! :xml, :version => "1.0" +xml.osm(OSM::API.new.xml_root_attributes) do |osm| + osm.api do |api| + api.version(:minimum => API_VERSION.to_s, :maximum => API_VERSION.to_s) + api.area(:maximum => MAX_REQUEST_AREA.to_s) + api.note_area(:maximum => MAX_NOTE_REQUEST_AREA.to_s) + api.tracepoints(:per_page => TRACEPOINTS_PER_PAGE.to_s) + api.waynodes(:maximum => MAX_NUMBER_OF_WAY_NODES.to_s) + api.changesets(:maximum_elements => Changeset::MAX_ELEMENTS.to_s) + api.timeout(:seconds => API_TIMEOUT.to_s) + api.status(:database => @database_status.to_s, + :api => @api_status.to_s, + :gpx => @gpx_status.to_s) + end + osm.policy do |policy| + policy.imagery do |imagery| + IMAGERY_BLACKLIST.each do |url_regex| + imagery.blacklist(:regex => url_regex.to_s) + end + end + end +end diff --git a/app/views/api/permissions.builder b/app/views/api/permissions.builder index 6d26a9e53..f97dd55f8 100644 --- a/app/views/api/permissions.builder +++ b/app/views/api/permissions.builder @@ -1,6 +1,6 @@ # create list of permissions xml.instruct! :xml, :version => "1.0" -xml.osm("version" => API_VERSION.to_s, "generator" => "OpenStreetMap Server") do +xml.osm(OSM::API.new.xml_root_attributes) do xml.permissions do @permissions.each do |permission| xml.permission :name => permission diff --git a/app/views/notes/index.xml.builder b/app/views/notes/index.xml.builder index c1c2be7e4..286b1e1cc 100644 --- a/app/views/notes/index.xml.builder +++ b/app/views/notes/index.xml.builder @@ -1,5 +1,5 @@ xml.instruct! -xml.osm(:version => API_VERSION, :generator => GENERATOR) do |osm| +xml.osm(OSM::API.new.xml_root_attributes) do |osm| osm << (render(:partial => "note", :collection => @notes) || "") end diff --git a/app/views/notes/show.xml.builder b/app/views/notes/show.xml.builder index f16cda3a6..51b3daebd 100644 --- a/app/views/notes/show.xml.builder +++ b/app/views/notes/show.xml.builder @@ -1,5 +1,5 @@ xml.instruct! -xml.osm(:version => API_VERSION, :generator => GENERATOR) do |osm| +xml.osm(OSM::API.new.xml_root_attributes) do |osm| osm << render(:partial => "note", :object => @note) end diff --git a/app/views/users/api_read.builder b/app/views/users/api_read.builder index 1598f3c53..78533279c 100644 --- a/app/views/users/api_read.builder +++ b/app/views/users/api_read.builder @@ -1,4 +1,4 @@ xml.instruct! :xml, :version => "1.0" -xml.osm("version" => API_VERSION, "generator" => GENERATOR) do |osm| +xml.osm(OSM::API.new.xml_root_attributes) do |osm| osm << render(:partial => "api_user", :object => @user) end diff --git a/app/views/users/api_users.builder b/app/views/users/api_users.builder index 1d2475743..a3c0f4d9a 100644 --- a/app/views/users/api_users.builder +++ b/app/views/users/api_users.builder @@ -1,4 +1,4 @@ xml.instruct! :xml, :version => "1.0" -xml.osm("version" => API_VERSION, "generator" => GENERATOR) do |osm| +xml.osm(OSM::API.new.xml_root_attributes) do |osm| osm << render(:partial => "api_user", :collection => @users) end diff --git a/lib/osm.rb b/lib/osm.rb index 841cce17b..1951e3c31 100644 --- a/lib/osm.rb +++ b/lib/osm.rb @@ -494,14 +494,20 @@ module OSM doc = XML::Document.new doc.encoding = XML::Encoding::UTF_8 root = XML::Node.new "osm" - root["version"] = API_VERSION.to_s - root["generator"] = GENERATOR - root["copyright"] = COPYRIGHT_OWNER - root["attribution"] = ATTRIBUTION_URL - root["license"] = LICENSE_URL + xml_root_attributes.each do |k, v| + root[k] = v + end doc.root = root doc end + + def xml_root_attributes + { "version" => API_VERSION.to_s, + "generator" => GENERATOR, + "copyright" => COPYRIGHT_OWNER, + "attribution" => ATTRIBUTION_URL, + "license" => LICENSE_URL } + end end def self.ip_to_country(ip_address)