From: Tom Hughes Date: Tue, 26 Mar 2019 19:14:04 +0000 (+0000) Subject: Merge remote-tracking branch 'upstream/pull/2175' X-Git-Tag: live~2664 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/dcfe326f6515cc7aeb9c02b7536e69863c60cd01?hp=d6af4450d1ea3599cdce6921138155f73e154816 Merge remote-tracking branch 'upstream/pull/2175' --- diff --git a/.gitignore b/.gitignore index 1a2d35c6a..5ba4bc764 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,18 @@ -log -config/piwik.yml +*~ +.DS_Store +.idea +.ruby-gemset +.ruby-version +.vagrant app/assets/javascripts/i18n +config/environments/*.local.yml +config/piwik.yml +config/settings.local.yml +config/settings/*.local.yml +coverage +doc +log public/assets public/attachments public/export tmp -.DS_Store -*~ -doc -.vagrant -.ruby-gemset -.ruby-version -.idea -coverage diff --git a/.travis.yml b/.travis.yml index 9438622cd..1b99a5143 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,6 @@ env: global: - OSM_MEMCACHE_SERVERS="127.0.0.1" before_script: - - cp config/example.application.yml config/application.yml - psql -U postgres -c "CREATE DATABASE openstreetmap" - psql -U postgres -c "CREATE EXTENSION btree_gist" openstreetmap - make -C db/functions libpgosm.so @@ -23,6 +22,7 @@ before_script: - psql -U postgres -c "CREATE FUNCTION tile_for_point(int4, int4) RETURNS int8 AS '/tmp/libpgosm', 'tile_for_point' LANGUAGE C STRICT" openstreetmap - psql -U postgres -c "CREATE FUNCTION xid_to_int4(xid) RETURNS int4 AS '/tmp/libpgosm', 'xid_to_int4' LANGUAGE C STRICT" openstreetmap - cp config/travis.database.yml config/database.yml + - touch config/settings.local.yml - bundle exec rake db:migrate - bundle exec rake i18n:js:export script: diff --git a/CONFIGURE.md b/CONFIGURE.md index c6444ffa9..91a64119e 100644 --- a/CONFIGURE.md +++ b/CONFIGURE.md @@ -2,6 +2,10 @@ After [installing](INSTALL.md) this software, you may need to carry out some of these configuration steps, depending on your tasks. +## Application configuration + +Many settings are available in `config/settings.yml`. You can customize your installation of The Rails Port by overriding these values using `config/settings.local.yml` + ## Populating the database Your installation comes with no geographic data loaded. You can either create new data using one of the editors (Potlatch 2, iD, JOSM etc) or by loading an OSM extract. @@ -71,11 +75,11 @@ Do the following: * Everything else can be left with the default blank values. * Click the "Register" button * On the next page, copy the "consumer key" -* Edit config/application.yml in your rails tree -* Uncomment and change the "potlatch2_key" configuration value +* Edit config/settings.local.yml in your rails tree +* Add the "potlatch2_key" configuration key and the consumer key as the value * Restart your rails server -An example excerpt from application.yml: +An example excerpt from settings.local.yml: ``` # Default editor @@ -86,8 +90,6 @@ potlatch2_key: "8lFmZPsagHV4l3rkAHq0hWY5vV3Ctl3oEFY1aXth" Follow the same process for registering and configuring iD (`id_key`) and the website/Notes (`oauth_key`), or to save time, simply reuse the same consumer key for each. -**NOTE:** If you forget to set up OAuth, then you will get an error message similar to `uninitialized constant ActionView::CompiledTemplates::ID_KEY`. - ## Troubleshooting Rails has its own log. To inspect the log, do this: diff --git a/Gemfile b/Gemfile index 275388666..83f298101 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source "https://rubygems.org" # Require rails -gem "rails", "5.2.2" +gem "rails", "5.2.2.1" # Require things which have moved to gems in ruby 1.9 gem "bigdecimal", "~> 1.1.0", :platforms => :ruby_19 @@ -46,8 +46,10 @@ gem "image_optim_rails" # Load rails plugins gem "actionpack-page_caching" gem "active_record_union" +gem "activerecord-import" gem "cancancan" gem "composite_primary_keys", "~> 11.1.0" +gem "config" gem "delayed_job_active_record" gem "dynamic_form" gem "http_accept_language", "~> 2.0.0" diff --git a/Gemfile.lock b/Gemfile.lock index 0dd07a95e..57feba1fd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,49 +2,51 @@ GEM remote: https://rubygems.org/ specs: SystemTimer (1.2.3) - aasm (5.0.1) + aasm (5.0.2) concurrent-ruby (~> 1.0) - actioncable (5.2.2) - actionpack (= 5.2.2) + actioncable (5.2.2.1) + actionpack (= 5.2.2.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailer (5.2.2) - actionpack (= 5.2.2) - actionview (= 5.2.2) - activejob (= 5.2.2) + actionmailer (5.2.2.1) + actionpack (= 5.2.2.1) + actionview (= 5.2.2.1) + activejob (= 5.2.2.1) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.2.2) - actionview (= 5.2.2) - activesupport (= 5.2.2) + actionpack (5.2.2.1) + actionview (= 5.2.2.1) + activesupport (= 5.2.2.1) rack (~> 2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) actionpack-page_caching (1.1.1) actionpack (>= 4.0.0, < 6) - actionview (5.2.2) - activesupport (= 5.2.2) + actionview (5.2.2.1) + activesupport (= 5.2.2.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.3) active_record_union (1.3.0) activerecord (>= 4.0) - activejob (5.2.2) - activesupport (= 5.2.2) + activejob (5.2.2.1) + activesupport (= 5.2.2.1) globalid (>= 0.3.6) - activemodel (5.2.2) - activesupport (= 5.2.2) - activerecord (5.2.2) - activemodel (= 5.2.2) - activesupport (= 5.2.2) + activemodel (5.2.2.1) + activesupport (= 5.2.2.1) + activerecord (5.2.2.1) + activemodel (= 5.2.2.1) + activesupport (= 5.2.2.1) arel (>= 9.0) - activestorage (5.2.2) - actionpack (= 5.2.2) - activerecord (= 5.2.2) + activerecord-import (0.28.1) + activerecord (>= 3.2) + activestorage (5.2.2.1) + actionpack (= 5.2.2.1) + activerecord (= 5.2.2.1) marcel (~> 0.3.1) - activesupport (5.2.2) + activesupport (5.2.2.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) @@ -65,7 +67,7 @@ GEM bigdecimal (1.1.0) binding_of_caller (0.8.0) debug_inspector (>= 0.0.1) - bootsnap (1.4.0) + bootsnap (1.4.1) msgpack (~> 1.0) browser (2.5.3) builder (3.2.3) @@ -91,7 +93,11 @@ GEM coffee-script-source (1.12.2) composite_primary_keys (11.1.0) activerecord (~> 5.2.1) - concurrent-ruby (1.1.4) + concurrent-ruby (1.1.5) + config (1.7.1) + activesupport (>= 3.0) + deep_merge (~> 1.2.1) + dry-validation (>= 0.12.2) coveralls (0.8.22) json (>= 1.8, < 3) simplecov (~> 0.16.1) @@ -103,25 +109,54 @@ GEM crass (1.0.4) dalli (2.7.9) debug_inspector (0.0.3) + deep_merge (1.2.1) delayed_job (4.1.5) activesupport (>= 3.0, < 5.3) delayed_job_active_record (4.1.3) activerecord (>= 3.0, < 5.3) delayed_job (>= 3.0, < 5) docile (1.3.1) + dry-configurable (0.8.2) + concurrent-ruby (~> 1.0) + dry-core (~> 0.4, >= 0.4.7) + dry-container (0.7.0) + concurrent-ruby (~> 1.0) + dry-configurable (~> 0.1, >= 0.1.3) + dry-core (0.4.7) + concurrent-ruby (~> 1.0) + dry-equalizer (0.2.2) + dry-inflector (0.1.2) + dry-logic (0.5.0) + dry-container (~> 0.2, >= 0.2.6) + dry-core (~> 0.2) + dry-equalizer (~> 0.2) + dry-types (0.14.0) + concurrent-ruby (~> 1.0) + dry-container (~> 0.3) + dry-core (~> 0.4, >= 0.4.4) + dry-equalizer (~> 0.2) + dry-inflector (~> 0.1, >= 0.1.2) + dry-logic (~> 0.5, >= 0.5) + dry-validation (0.13.0) + concurrent-ruby (~> 1.0) + dry-configurable (~> 0.1, >= 0.1.3) + dry-core (~> 0.2, >= 0.2.1) + dry-equalizer (~> 0.2) + dry-logic (~> 0.5, >= 0.5.0) + dry-types (~> 0.14, >= 0.14) dynamic_form (1.1.4) erubi (1.8.0) execjs (2.7.0) exifr (1.3.6) - factory_bot (5.0.0) + factory_bot (5.0.2) activesupport (>= 4.2.0) factory_bot_rails (5.0.1) factory_bot (~> 5.0.0) railties (>= 4.2.0) - fakefs (0.19.1) + fakefs (0.20.0) faraday (0.15.4) multipart-post (>= 1.2, < 3) - ffi (1.9.25) + ffi (1.10.0) fspath (3.1.0) gd2-ffij (0.3.0) ffi (>= 1.0.0) @@ -157,7 +192,7 @@ GEM execjs (>= 1.4.0) multi_json (~> 1.0) therubyracer (~> 0.12.1) - json (2.1.0) + json (2.2.0) jsonify (0.3.1) multi_json (~> 1.0) jsonify-rails (0.3.2) @@ -192,7 +227,7 @@ GEM mini_mime (1.0.1) mini_portile2 (2.4.0) minitest (5.11.3) - msgpack (1.2.6) + msgpack (1.2.9) multi_json (1.13.1) multi_xml (0.6.0) multipart-post (2.0.0) @@ -221,7 +256,7 @@ GEM omniauth-github (1.3.0) omniauth (~> 1.5) omniauth-oauth2 (>= 1.4.0, < 2.0) - omniauth-google-oauth2 (0.6.0) + omniauth-google-oauth2 (0.6.1) jwt (>= 2.0) omniauth (>= 1.1.1) omniauth-oauth2 (>= 1.5) @@ -247,7 +282,7 @@ GEM mime-types mimemagic (~> 0.3.0) terrapin (~> 0.6.0) - parallel (1.13.0) + parallel (1.14.0) parser (2.6.0.0) ast (~> 2.4.0) pg (0.21.0) @@ -270,18 +305,18 @@ GEM rack-test (1.1.0) rack (>= 1.0, < 3) rack-uri_sanitizer (0.0.2) - rails (5.2.2) - actioncable (= 5.2.2) - actionmailer (= 5.2.2) - actionpack (= 5.2.2) - actionview (= 5.2.2) - activejob (= 5.2.2) - activemodel (= 5.2.2) - activerecord (= 5.2.2) - activestorage (= 5.2.2) - activesupport (= 5.2.2) + rails (5.2.2.1) + actioncable (= 5.2.2.1) + actionmailer (= 5.2.2.1) + actionpack (= 5.2.2.1) + actionview (= 5.2.2.1) + activejob (= 5.2.2.1) + activemodel (= 5.2.2.1) + activerecord (= 5.2.2.1) + activestorage (= 5.2.2.1) + activesupport (= 5.2.2.1) bundler (>= 1.3.0) - railties (= 5.2.2) + railties (= 5.2.2.1) sprockets-rails (>= 2.0.0) rails-controller-testing (1.0.4) actionpack (>= 5.0.1.x) @@ -295,9 +330,9 @@ GEM rails-i18n (4.0.2) i18n (~> 0.6) rails (>= 4.0) - railties (5.2.2) - actionpack (= 5.2.2) - activesupport (= 5.2.2) + railties (5.2.2.1) + actionpack (= 5.2.2.1) + activesupport (= 5.2.2.1) method_source rake (>= 0.8.7) thor (>= 0.19.0, < 2.0) @@ -312,26 +347,27 @@ GEM request_store (1.4.1) rack (>= 1.4) rinku (2.0.4) - rotp (4.0.2) + rotp (4.1.0) addressable (~> 2.5) - rubocop (0.64.0) + rubocop (0.65.0) jaro_winkler (~> 1.5.1) parallel (~> 1.10) parser (>= 2.5, != 2.5.1.1) powerpack (~> 0.1) + psych (>= 3.1.0) rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.4.0) ruby-openid (2.7.0) ruby-progressbar (1.10.0) ruby_dep (1.5.0) - safe_yaml (1.0.4) + safe_yaml (1.0.5) sanitize (5.0.0) crass (~> 1.0.2) nokogiri (>= 1.8.0) nokogumbo (~> 2.0) - sassc (2.0.0) - ffi (~> 1.9.6) + sassc (2.0.1) + ffi (~> 1.9) rake sassc-rails (2.1.0) railties (>= 4.0.0) @@ -339,7 +375,7 @@ GEM sprockets (> 3.0) sprockets-rails tilt - secure_headers (6.0.0) + secure_headers (6.1.0) simplecov (0.16.1) docile (~> 1.1) json (>= 1.8, < 3) @@ -389,6 +425,7 @@ DEPENDENCIES aasm actionpack-page_caching active_record_union + activerecord-import annotate autoprefixer-rails (~> 8.6.3) better_errors @@ -401,6 +438,7 @@ DEPENDENCIES capybara (~> 2.13) coffee-rails (~> 4.2) composite_primary_keys (~> 11.1.0) + config coveralls dalli delayed_job_active_record @@ -442,7 +480,7 @@ DEPENDENCIES r2 (~> 0.2.7) rack-cors rack-uri_sanitizer - rails (= 5.2.2) + rails (= 5.2.2.1) rails-controller-testing rails-i18n (~> 4.0.0) record_tag_helper diff --git a/INSTALL.md b/INSTALL.md index b1fb1eafb..5b2652c3e 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -114,16 +114,6 @@ cd openstreetmap-website bundle install ``` -## Application setup - -We need to create the `config/application.yml` file from the example template. This contains various configuration options. - -``` -cp config/example.application.yml config/application.yml -``` - -You can customize your installation of The Rails Port by changing the values in `config/application.yml` - ## Database setup The Rails Port uses three databases - one for development, one for testing, and one for production. The database-specific configuration diff --git a/app/abilities/ability.rb b/app/abilities/ability.rb index 5e8ef997f..7e8e921a2 100644 --- a/app/abilities/ability.rb +++ b/app/abilities/ability.rb @@ -8,72 +8,79 @@ class Ability :changeset, :note, :new_note, :query], :browse can :show, :capability can :index, :change - can [:index, :feed, :show, :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, :map - can [:index, :create, :comment, :feed, :show, :search, :mine], Note can [:token, :request_token, :access_token, :test_request], :oauth can :show, :permission - 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 :index, Tracepoint - 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 - can [:index, :show], Node - can [:index, :show, :full, :ways_for_node], Way - can [:index, :show, :full, :relations_for_node, :relations_for_way, :relations_for_relation], Relation - can [:history, :version], OldNode - can [:history, :version], OldWay - can [:history, :version], OldRelation + + if Settings.status != "database_offline" + can [:index, :feed, :show, :download, :query], Changeset + can :index, ChangesetComment + can [:index, :rss, :show, :comments], DiaryEntry + can [:index, :create, :comment, :feed, :show, :search, :mine], Note + can [:index, :show], Redaction + can [:index, :show, :data, :georss, :picture, :icon], Trace + can :index, Tracepoint + 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 + can [:index, :show], Node + can [:index, :show, :full, :ways_for_node], Way + can [:index, :show, :full, :relations_for_node, :relations_for_way, :relations_for_relation], Relation + can [:history, :version], OldNode + can [:history, :version], OldWay + can [:history, :version], OldRelation + end if user can :welcome, :site - can [:index, :new, :create, :show, :edit, :update, :destroy], ClientApplication - can [:create, :edit, :comment, :subscribe, :unsubscribe], DiaryEntry - can [:new, :create, :reply, :show, :inbox, :outbox, :mark, :destroy], Message - can [:close, :reopen], Note can [:revoke, :authorize], :oauth - 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? - can [:create, :update, :upload, :close, :subscribe, :unsubscribe, :expand_bbox], Changeset - can :create, ChangesetComment - can [:create, :update, :delete], Node - can [:create, :update, :delete], Way - can [:create, :update, :delete], Relation - end + if Settings.status != "database_offline" + can [:index, :new, :create, :show, :edit, :update, :destroy], ClientApplication + can [:create, :edit, :comment, :subscribe, :unsubscribe], DiaryEntry + 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.moderator? - can [:destroy, :restore], ChangesetComment - can [:index, :show, :resolve, :ignore, :reopen], Issue - can :create, IssueComment - can :destroy, Note - can [:new, :create, :edit, :update, :destroy], Redaction - can [:new, :edit, :create, :update, :revoke], UserBlock if user.terms_agreed? - can :redact, OldNode - can :redact, OldWay - can :redact, OldRelation + can [:create, :update, :upload, :close, :subscribe, :unsubscribe, :expand_bbox], Changeset + can :create, ChangesetComment + can [:create, :update, :delete], Node + can [:create, :update, :delete], Way + can [:create, :update, :delete], Relation end - end - if user.administrator? - can [:hide, :hidecomment], [DiaryEntry, DiaryComment] - can [:index, :show, :resolve, :ignore, :reopen], Issue - can :create, IssueComment - can [:set_status, :delete, :index], User - can [:grant, :revoke], UserRole + if user.moderator? + can [:destroy, :restore], ChangesetComment + can [:index, :show, :resolve, :ignore, :reopen], Issue + can :create, IssueComment + can :destroy, Note + can [:new, :create, :edit, :update, :destroy], Redaction + can [:new, :edit, :create, :update, :revoke], UserBlock + + if user.terms_agreed? + can :redact, OldNode + can :redact, OldWay + can :redact, OldRelation + end + end + + if user.administrator? + can [:hide, :hidecomment], [DiaryEntry, DiaryComment] + can [:index, :show, :resolve, :ignore, :reopen], Issue + can :create, IssueComment + can [:set_status, :delete, :index], User + can [:grant, :revoke], UserRole + end end end diff --git a/app/abilities/capability.rb b/app/abilities/capability.rb index d8f51eefe..f4c24e97d 100644 --- a/app/abilities/capability.rb +++ b/app/abilities/capability.rb @@ -4,29 +4,31 @@ class Capability include CanCan::Ability 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 Settings.status != "database_offline" + 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? - 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) - can [:create, :update, :delete], Node if capability?(token, :allow_write_api) - can [:create, :update, :delete], Way if capability?(token, :allow_write_api) - can [:create, :update, :delete], Relation if capability?(token, :allow_write_api) - end - - if token&.user&.moderator? - can [:destroy, :restore], ChangesetComment if capability?(token, :allow_write_api) - can :destroy, Note if capability?(token, :allow_write_notes) if token&.user&.terms_agreed? - can :redact, OldNode if capability?(token, :allow_write_api) - can :redact, OldWay if capability?(token, :allow_write_api) - can :redact, OldRelation if capability?(token, :allow_write_api) + 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) + can [:create, :update, :delete], Node if capability?(token, :allow_write_api) + can [:create, :update, :delete], Way if capability?(token, :allow_write_api) + can [:create, :update, :delete], Relation if capability?(token, :allow_write_api) + end + + if token&.user&.moderator? + can [:destroy, :restore], ChangesetComment if capability?(token, :allow_write_api) + can :destroy, Note if capability?(token, :allow_write_notes) + if token&.user&.terms_agreed? + can :redact, OldNode if capability?(token, :allow_write_api) + can :redact, OldWay if capability?(token, :allow_write_api) + can :redact, OldRelation if capability?(token, :allow_write_api) + end end end end diff --git a/app/assets/images/banners/saveyourinternet.png b/app/assets/images/banners/saveyourinternet.png new file mode 100644 index 000000000..4263396a8 Binary files /dev/null and b/app/assets/images/banners/saveyourinternet.png differ diff --git a/app/assets/javascripts/embed.js.erb b/app/assets/javascripts/embed.js.erb index 36b23666a..ceb488f98 100644 --- a/app/assets/javascripts/embed.js.erb +++ b/app/assets/javascripts/embed.js.erb @@ -20,8 +20,8 @@ window.onload = function () { } var thunderforestOptions = { -<% if defined?(THUNDERFOREST_KEY) %> - apikey: <%= THUNDERFOREST_KEY.to_json %> +<% if Settings.key?(:thunderforest_key) %> + apikey: <%= Settings.thunderforest_key.to_json %> <% end %> }; diff --git a/app/assets/javascripts/osm.js.erb b/app/assets/javascripts/osm.js.erb index a9e1a475e..205dae0d1 100644 --- a/app/assets/javascripts/osm.js.erb +++ b/app/assets/javascripts/osm.js.erb @@ -1,24 +1,25 @@ -//= depend_on application.yml +//= depend_on settings.yml +//= depend_on settings.local.yml OSM = { <% if defined?(PIWIK) %> PIWIK: <%= PIWIK.to_json %>, <% end %> - MAX_REQUEST_AREA: <%= MAX_REQUEST_AREA.to_json %>, - SERVER_PROTOCOL: <%= SERVER_PROTOCOL.to_json %>, - SERVER_URL: <%= SERVER_URL.to_json %>, - API_VERSION: <%= API_VERSION.to_json %>, - STATUS: <%= STATUS.to_json %>, - MAX_NOTE_REQUEST_AREA: <%= MAX_NOTE_REQUEST_AREA.to_json %>, - OVERPASS_URL: <%= OVERPASS_URL.to_json %>, - NOMINATIM_URL: <%= NOMINATIM_URL.to_json %>, - GRAPHHOPPER_URL: <%= GRAPHHOPPER_URL.to_json %>, - FOSSGIS_OSRM_URL: <%= FOSSGIS_OSRM_URL.to_json %>, + MAX_REQUEST_AREA: <%= Settings.max_request_area.to_json %>, + SERVER_PROTOCOL: <%= Settings.server_protocol.to_json %>, + SERVER_URL: <%= Settings.server_url.to_json %>, + API_VERSION: <%= Settings.api_version.to_json %>, + STATUS: <%= Settings.status.to_json %>, + MAX_NOTE_REQUEST_AREA: <%= Settings.max_note_request_area.to_json %>, + OVERPASS_URL: <%= Settings.overpass_url.to_json %>, + NOMINATIM_URL: <%= Settings.nominatim_url.to_json %>, + GRAPHHOPPER_URL: <%= Settings.graphhopper_url.to_json %>, + FOSSGIS_OSRM_URL: <%= Settings.fossgis_osrm_url.to_json %>, DEFAULT_LOCALE: <%= I18n.default_locale.to_json %>, -<% if defined?(THUNDERFOREST_KEY) %> - THUNDERFOREST_KEY: <%= THUNDERFOREST_KEY.to_json %>, +<% if Settings.key?(:thunderforest_key) %> + THUNDERFOREST_KEY: <%= Settings.thunderforest_key.to_json %>, <% end %> MARKER_GREEN: <%= image_path("marker-green.png").to_json %>, @@ -212,7 +213,7 @@ OSM = { return 6372795 * 2 * Math.asin( Math.sqrt( - Math.pow(Math.sin(latdiff / 2), 2) + + Math.pow(Math.sin(latdiff / 2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(lngdiff / 2), 2) )); } diff --git a/app/controllers/api/amf_controller.rb b/app/controllers/api/amf_controller.rb index 2a878d248..0cf511d76 100644 --- a/app/controllers/api/amf_controller.rb +++ b/app/controllers/api/amf_controller.rb @@ -36,10 +36,9 @@ # * version conflict when POIs and ways are reverted module Api - class AmfController < ApplicationController + class AmfController < ApiController include Potlatch - skip_before_action :verify_authenticity_token before_action :check_api_writable # AMF Controller implements its own authentication and authorization checks @@ -131,7 +130,7 @@ module Api def amf_handle_error_with_timeout(call, rootobj, rootid) amf_handle_error(call, rootobj, rootid) do - OSM::Timer.timeout(API_TIMEOUT, OSM::APITimeoutError) do + OSM::Timer.timeout(Settings.api_timeout, OSM::APITimeoutError) do yield end end diff --git a/app/controllers/api/capabilities_controller.rb b/app/controllers/api/capabilities_controller.rb index 8337bc809..7f91557f8 100644 --- a/app/controllers/api/capabilities_controller.rb +++ b/app/controllers/api/capabilities_controller.rb @@ -1,8 +1,5 @@ module Api - class CapabilitiesController < ApplicationController - skip_before_action :verify_authenticity_token - before_action :api_deny_access_handler - + class CapabilitiesController < ApiController authorize_resource :class => false around_action :api_call_handle_error, :api_call_timeout diff --git a/app/controllers/api/changes_controller.rb b/app/controllers/api/changes_controller.rb index c9195e1d9..7170e1562 100644 --- a/app/controllers/api/changes_controller.rb +++ b/app/controllers/api/changes_controller.rb @@ -1,8 +1,5 @@ module Api - class ChangesController < ApplicationController - skip_before_action :verify_authenticity_token - before_action :api_deny_access_handler - + class ChangesController < ApiController authorize_resource :class => false before_action :check_api_readable diff --git a/app/controllers/api/changeset_comments_controller.rb b/app/controllers/api/changeset_comments_controller.rb index 6093f529e..21c854139 100644 --- a/app/controllers/api/changeset_comments_controller.rb +++ b/app/controllers/api/changeset_comments_controller.rb @@ -1,8 +1,6 @@ module Api - class ChangesetCommentsController < ApplicationController - skip_before_action :verify_authenticity_token + class ChangesetCommentsController < ApiController before_action :authorize - before_action :api_deny_access_handler authorize_resource @@ -41,7 +39,8 @@ module Api changeset.subscribers << current_user unless changeset.subscribers.exists?(current_user.id) # Return a copy of the updated changeset - render :xml => changeset.to_xml.to_s + @changeset = changeset + render "api/changesets/changeset" end ## @@ -60,7 +59,8 @@ module Api comment.update(:visible => false) # Return a copy of the updated changeset - render :xml => comment.changeset.to_xml.to_s + @changeset = comment.changeset + render "api/changesets/changeset" end ## @@ -79,7 +79,8 @@ module Api comment.update(:visible => true) # Return a copy of the updated changeset - render :xml => comment.changeset.to_xml.to_s + @changeset = comment.changeset + render "api/changesets/changeset" end end end diff --git a/app/controllers/api/changesets_controller.rb b/app/controllers/api/changesets_controller.rb index 853ee389f..fb6523f4e 100644 --- a/app/controllers/api/changesets_controller.rb +++ b/app/controllers/api/changesets_controller.rb @@ -1,20 +1,17 @@ # The ChangesetController is the RESTful interface to Changeset objects module Api - class ChangesetsController < ApplicationController + class ChangesetsController < ApiController layout "site" require "xml/libxml" - skip_before_action :verify_authenticity_token before_action :authorize, :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, :subscribe, :unsubscribe] - before_action(:only => [:index, :feed]) { |c| c.check_database_readable(true) } around_action :api_call_handle_error around_action :api_call_timeout, :except => [:upload] @@ -41,9 +38,9 @@ module Api # Return XML giving the basic info about the changeset. Does not # return anything about the nodes, ways and relations in the changeset. def show - changeset = Changeset.find(params[:id]) - - render :xml => changeset.to_xml(params[:include_discussion].presence).to_s + @changeset = Changeset.find(params[:id]) + @include_discussion = params[:include_discussion].presence + render "changeset" end ## @@ -104,7 +101,8 @@ module Api # save the larger bounding box and return the changeset, which # will include the bigger bounding box. cs.save! - render :xml => cs.to_xml.to_s + @changeset = cs + render "changeset" end ## @@ -219,18 +217,9 @@ module Api # sort and limit the changesets changesets = changesets.order("created_at DESC").limit(100) - # preload users, tags and comments - changesets = changesets.preload(:user, :changeset_tags, :comments) - - # create the results document - results = OSM::API.new.get_xml_doc - - # add all matching changesets to the XML results document - changesets.order("created_at DESC").limit(100).each do |cs| - results.root << cs.to_xml_node - end - - render :xml => results.to_s + # preload users, tags and comments, and render result + @changesets = changesets.preload(:user, :changeset_tags, :comments) + render "changesets" end ## @@ -245,12 +234,12 @@ module Api # request *must* be a PUT. assert_method :put - changeset = Changeset.find(params[:id]) + @changeset = Changeset.find(params[:id]) new_changeset = Changeset.from_xml(request.raw_post) - check_changeset_consistency(changeset, current_user) - changeset.update_from(new_changeset, current_user) - render :xml => changeset.to_xml.to_s + check_changeset_consistency(@changeset, current_user) + @changeset.update_from(new_changeset, current_user) + render "changeset" end ## @@ -270,7 +259,8 @@ module Api changeset.subscribers << current_user # Return a copy of the updated changeset - render :xml => changeset.to_xml.to_s + @changeset = changeset + render "changeset" end ## @@ -290,7 +280,8 @@ module Api changeset.subscribers.delete(current_user) # Return a copy of the updated changeset - render :xml => changeset.to_xml.to_s + @changeset = changeset + render "changeset" end private diff --git a/app/controllers/api/map_controller.rb b/app/controllers/api/map_controller.rb index 47c0aeb36..27d6f3667 100644 --- a/app/controllers/api/map_controller.rb +++ b/app/controllers/api/map_controller.rb @@ -1,8 +1,5 @@ module Api - class MapController < ApplicationController - skip_before_action :verify_authenticity_token - before_action :api_deny_access_handler - + class MapController < ApiController authorize_resource :class => false before_action :check_api_readable @@ -30,11 +27,11 @@ module Api return end - nodes = Node.bbox(bbox).where(:visible => true).includes(:node_tags).limit(MAX_NUMBER_OF_NODES + 1) + nodes = Node.bbox(bbox).where(:visible => true).includes(:node_tags).limit(Settings.max_number_of_nodes + 1) node_ids = nodes.collect(&:id) - if node_ids.length > MAX_NUMBER_OF_NODES - report_error("You requested too many nodes (limit is #{MAX_NUMBER_OF_NODES}). Either request a smaller area, or use planet.osm") + if node_ids.length > Settings.max_number_of_nodes + report_error("You requested too many nodes (limit is #{Settings.max_number_of_nodes}). Either request a smaller area, or use planet.osm") return end diff --git a/app/controllers/api/nodes_controller.rb b/app/controllers/api/nodes_controller.rb index 4e46b38d5..5218159c1 100644 --- a/app/controllers/api/nodes_controller.rb +++ b/app/controllers/api/nodes_controller.rb @@ -1,12 +1,10 @@ # The NodeController is the RESTful interface to Node objects module Api - class NodesController < ApplicationController + class NodesController < ApiController require "xml/libxml" - skip_before_action :verify_authenticity_token before_action :authorize, :only => [:create, :update, :delete] - before_action :api_deny_access_handler authorize_resource diff --git a/app/controllers/api/notes_controller.rb b/app/controllers/api/notes_controller.rb index d4ebef5d4..20a24ce99 100644 --- a/app/controllers/api/notes_controller.rb +++ b/app/controllers/api/notes_controller.rb @@ -1,12 +1,10 @@ module Api - class NotesController < ApplicationController + class NotesController < ApiController layout "site", :only => [:mine] - skip_before_action :verify_authenticity_token before_action :check_api_readable before_action :setup_user_auth, :only => [:create, :comment, :show] before_action :authorize, :only => [:close, :reopen, :destroy] - before_action :api_deny_access_handler authorize_resource @@ -37,7 +35,7 @@ module Api bbox.check_boundaries # Check the the bounding box is not too big - bbox.check_size(MAX_NOTE_REQUEST_AREA) + bbox.check_size(Settings.max_note_request_area) # Find the notes we want to return @notes = notes.bbox(bbox).order("updated_at DESC").limit(result_limit).preload(:comments) @@ -190,7 +188,7 @@ module Api bbox = BoundingBox.from_bbox_params(params) bbox.check_boundaries - bbox.check_size(MAX_NOTE_REQUEST_AREA) + bbox.check_size(Settings.max_note_request_area) notes = notes.bbox(bbox) end diff --git a/app/controllers/api/old_controller.rb b/app/controllers/api/old_controller.rb index 9a86bded5..fa2b5814e 100644 --- a/app/controllers/api/old_controller.rb +++ b/app/controllers/api/old_controller.rb @@ -2,12 +2,10 @@ # into one place. as it turns out, the API methods for historical # nodes, ways and relations are basically identical. module Api - class OldController < ApplicationController + class OldController < ApiController require "xml/libxml" - skip_before_action :verify_authenticity_token before_action :setup_user_auth, :only => [:history, :version] - before_action :api_deny_access_handler before_action :authorize, :only => [:redact] authorize_resource diff --git a/app/controllers/api/permissions_controller.rb b/app/controllers/api/permissions_controller.rb index b24aca776..9b168e04b 100644 --- a/app/controllers/api/permissions_controller.rb +++ b/app/controllers/api/permissions_controller.rb @@ -1,8 +1,5 @@ module Api - class PermissionsController < ApplicationController - skip_before_action :verify_authenticity_token - before_action :api_deny_access_handler - + class PermissionsController < ApiController authorize_resource :class => false before_action :check_api_readable diff --git a/app/controllers/api/relations_controller.rb b/app/controllers/api/relations_controller.rb index a0740b382..b7d990c3d 100644 --- a/app/controllers/api/relations_controller.rb +++ b/app/controllers/api/relations_controller.rb @@ -1,10 +1,8 @@ module Api - class RelationsController < ApplicationController + class RelationsController < ApiController require "xml/libxml" - skip_before_action :verify_authenticity_token before_action :authorize, :only => [:create, :update, :delete] - before_action :api_deny_access_handler authorize_resource diff --git a/app/controllers/api/search_controller.rb b/app/controllers/api/search_controller.rb index 0afbbf8e2..feb487ac0 100644 --- a/app/controllers/api/search_controller.rb +++ b/app/controllers/api/search_controller.rb @@ -1,9 +1,8 @@ module Api - class SearchController < ApplicationController + class SearchController < ApiController # Support searching for nodes, ways, or all # 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 diff --git a/app/controllers/api/swf_controller.rb b/app/controllers/api/swf_controller.rb index d48731b70..2f8a5392d 100644 --- a/app/controllers/api/swf_controller.rb +++ b/app/controllers/api/swf_controller.rb @@ -1,6 +1,5 @@ module Api - class SwfController < ApplicationController - skip_before_action :verify_authenticity_token + class SwfController < ApiController before_action :check_api_readable authorize_resource :class => false diff --git a/app/controllers/api/tracepoints_controller.rb b/app/controllers/api/tracepoints_controller.rb index 56cd36138..b22bcfaea 100644 --- a/app/controllers/api/tracepoints_controller.rb +++ b/app/controllers/api/tracepoints_controller.rb @@ -1,8 +1,5 @@ module Api - class TracepointsController < ApplicationController - skip_before_action :verify_authenticity_token - before_action :api_deny_access_handler - + class TracepointsController < ApiController authorize_resource before_action :check_api_readable @@ -19,7 +16,7 @@ module Api return end - offset = page * TRACEPOINTS_PER_PAGE + offset = page * Settings.tracepoints_per_page # Figure out the bbox # check boundary is sane and area within defined @@ -36,7 +33,7 @@ module Api # get all the points ordered_points = Tracepoint.bbox(bbox).joins(:trace).where(:gpx_files => { :visibility => %w[trackable identifiable] }).order("gpx_id DESC, trackid ASC, timestamp ASC") unordered_points = Tracepoint.bbox(bbox).joins(:trace).where(:gpx_files => { :visibility => %w[public private] }).order("gps_points.latitude", "gps_points.longitude", "gps_points.timestamp") - points = ordered_points.union_all(unordered_points).offset(offset).limit(TRACEPOINTS_PER_PAGE) + points = ordered_points.union_all(unordered_points).offset(offset).limit(Settings.tracepoints_per_page) doc = XML::Document.new doc.encoding = XML::Encoding::UTF_8 diff --git a/app/controllers/api/traces_controller.rb b/app/controllers/api/traces_controller.rb index 8401e78ae..47dd152a3 100644 --- a/app/controllers/api/traces_controller.rb +++ b/app/controllers/api/traces_controller.rb @@ -1,12 +1,10 @@ module Api - class TracesController < ApplicationController + class TracesController < ApiController layout "site", :except => :georss - skip_before_action :verify_authenticity_token before_action :authorize_web before_action :set_locale before_action :authorize - before_action :api_deny_access_handler authorize_resource @@ -163,7 +161,7 @@ module Api end def offline_redirect - redirect_to :action => :offline if STATUS == :gpx_offline + redirect_to :action => :offline if Settings.status == "gpx_offline" end end end diff --git a/app/controllers/api/user_preferences_controller.rb b/app/controllers/api/user_preferences_controller.rb index 82f6c6a4d..39e0dff30 100644 --- a/app/controllers/api/user_preferences_controller.rb +++ b/app/controllers/api/user_preferences_controller.rb @@ -1,7 +1,6 @@ # Update and read user preferences, which are arbitrayr key/val pairs module Api - class UserPreferencesController < ApplicationController - skip_before_action :verify_authenticity_token + class UserPreferencesController < ApiController before_action :authorize authorize_resource diff --git a/app/controllers/api/users_controller.rb b/app/controllers/api/users_controller.rb index 70ad93f65..f24d50cf1 100644 --- a/app/controllers/api/users_controller.rb +++ b/app/controllers/api/users_controller.rb @@ -1,11 +1,9 @@ module Api - class UsersController < ApplicationController + class UsersController < ApiController layout "site", :except => [:api_details] - skip_before_action :verify_authenticity_token before_action :disable_terms_redirect, :only => [:api_details] before_action :authorize, :only => [:api_details, :api_gpx_files] - before_action :api_deny_access_handler authorize_resource diff --git a/app/controllers/api/ways_controller.rb b/app/controllers/api/ways_controller.rb index 8684c5cfb..5e3e5e11a 100644 --- a/app/controllers/api/ways_controller.rb +++ b/app/controllers/api/ways_controller.rb @@ -1,10 +1,8 @@ module Api - class WaysController < ApplicationController + class WaysController < ApiController require "xml/libxml" - skip_before_action :verify_authenticity_token before_action :authorize, :only => [:create, :update, :delete] - before_action :api_deny_access_handler authorize_resource diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb new file mode 100644 index 000000000..579af27cf --- /dev/null +++ b/app/controllers/api_controller.rb @@ -0,0 +1,79 @@ +class ApiController < ApplicationController + skip_before_action :verify_authenticity_token + + private + + def authorize(realm = "Web Password", errormessage = "Couldn't authenticate you") + # make the current_user object from any auth sources we have + setup_user_auth + + # handle authenticate pass/fail + unless current_user + # no auth, the user does not exist or the password was wrong + response.headers["WWW-Authenticate"] = "Basic realm=\"#{realm}\"" + render :plain => errormessage, :status => :unauthorized + return false + end + end + + def deny_access(_exception) + if current_token + set_locale + report_error t("oauth.permissions.missing"), :forbidden + elsif current_user + head :forbidden + else + realm = "Web Password" + errormessage = "Couldn't authenticate you" + response.headers["WWW-Authenticate"] = "Basic realm=\"#{realm}\"" + render :plain => errormessage, :status => :unauthorized + end + end + + def gpx_status + status = database_status + status = "offline" if status == "online" && Settings.status == "gpx_offline" + status + end + + ## + # 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 + # try and setup using OAuth + unless Authenticator.new(self, [:token]).allow? + username, passwd = get_auth_data # parse from headers + # authenticate per-scheme + self.current_user = if username.nil? + nil # no authentication provided - perhaps first connect (client should retry after 401) + elsif username == "token" + User.authenticate(:token => passwd) # preferred - random token for user from db, passed in basic auth + else + User.authenticate(:username => username, :password => passwd) # basic auth + end + end + + # 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 + end + end + + # if the user hasn't seen the contributor terms then don't + # allow editing - they have to go to the web site and see + # (but can decline) the CTs to continue. + if !current_user.terms_seen && flash[:skip_terms].nil? + set_locale + report_error t("application.setup_user_auth.need_to_see_terms"), :forbidden + end + end + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 227e5198f..3ab09b63d 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -12,6 +12,8 @@ class ApplicationController < ActionController::Base attr_accessor :current_user helper_method :current_user + private + def authorize_web if session[:user] self.current_user = User.where(:id => session[:user]).where("status IN ('active', 'confirmed', 'suspended')").first @@ -52,7 +54,7 @@ class ApplicationController < ActionController::Base end def require_oauth - @oauth = current_user.access_token(OAUTH_KEY) if current_user && defined? OAUTH_KEY + @oauth = current_user.access_token(Settings.oauth_key) if current_user && Settings.key?(:oauth_key) end ## @@ -71,62 +73,8 @@ class ApplicationController < ActionController::Base end end - ## - # 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 - # try and setup using OAuth - unless Authenticator.new(self, [:token]).allow? - username, passwd = get_auth_data # parse from headers - # authenticate per-scheme - self.current_user = if username.nil? - nil # no authentication provided - perhaps first connect (client should retry after 401) - elsif username == "token" - User.authenticate(:token => passwd) # preferred - random token for user from db, passed in basic auth - else - User.authenticate(:username => username, :password => passwd) # basic auth - end - end - - # 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 - end - end - - # if the user hasn't seen the contributor terms then don't - # allow editing - they have to go to the web site and see - # (but can decline) the CTs to continue. - if !current_user.terms_seen && flash[:skip_terms].nil? - set_locale - report_error t("application.setup_user_auth.need_to_see_terms"), :forbidden - end - end - end - - def authorize(realm = "Web Password", errormessage = "Couldn't authenticate you") - # make the current_user object from any auth sources we have - setup_user_auth - - # handle authenticate pass/fail - unless current_user - # no auth, the user does not exist or the password was wrong - response.headers["WWW-Authenticate"] = "Basic realm=\"#{realm}\"" - render :plain => errormessage, :status => :unauthorized - return false - end - end - def check_database_readable(need_api = false) - if STATUS == :database_offline || (need_api && STATUS == :api_offline) + if Settings.status == "database_offline" || (need_api && Settings.status == "api_offline") if request.xhr? report_error "Database offline for maintenance", :service_unavailable else @@ -136,8 +84,8 @@ class ApplicationController < ActionController::Base end def check_database_writable(need_api = false) - if STATUS == :database_offline || STATUS == :database_readonly || - (need_api && (STATUS == :api_offline || STATUS == :api_readonly)) + if Settings.status == "database_offline" || Settings.status == "database_readonly" || + (need_api && (Settings.status == "api_offline" || Settings.status == "api_readonly")) if request.xhr? report_error "Database offline for maintenance", :service_unavailable else @@ -147,47 +95,41 @@ class ApplicationController < ActionController::Base end def check_api_readable - if api_status == :offline + if api_status == "offline" report_error "Database offline for maintenance", :service_unavailable false end end def check_api_writable - unless api_status == :online + unless api_status == "online" report_error "Database offline for maintenance", :service_unavailable false end end def database_status - if STATUS == :database_offline - :offline - elsif STATUS == :database_readonly - :readonly + if Settings.status == "database_offline" + "offline" + elsif Settings.status == "database_readonly" + "readonly" else - :online + "online" end end def api_status status = database_status - if status == :online - if STATUS == :api_offline - status = :offline - elsif STATUS == :api_readonly - status = :readonly + if status == "online" + if Settings.status == "api_offline" + status = "offline" + elsif Settings.status == "api_readonly" + status = "readonly" end end status end - def gpx_status - status = database_status - status = :offline if status == :online && STATUS == :gpx_offline - status - end - def require_public_data unless current_user.data_public? report_error "You must make your edits public to upload new data", :forbidden @@ -272,7 +214,7 @@ class ApplicationController < ActionController::Base ## # wrap an api call in a timeout def api_call_timeout - OSM::Timer.timeout(API_TIMEOUT, Timeout::Error) do + OSM::Timer.timeout(Settings.api_timeout, Timeout::Error) do yield end rescue Timeout::Error @@ -282,7 +224,7 @@ class ApplicationController < ActionController::Base ## # wrap a web page in a timeout def web_timeout - OSM::Timer.timeout(WEB_TIMEOUT, Timeout::Error) do + OSM::Timer.timeout(Settings.web_timeout, Timeout::Error) do yield end rescue ActionView::Template::Error => ex @@ -333,14 +275,14 @@ class ApplicationController < ActionController::Base append_content_security_policy_directives( :child_src => %w[http://127.0.0.1:8111 https://127.0.0.1:8112], :frame_src => %w[http://127.0.0.1:8111 https://127.0.0.1:8112], - :connect_src => [NOMINATIM_URL, OVERPASS_URL, FOSSGIS_OSRM_URL, GRAPHHOPPER_URL], + :connect_src => [Settings.nominatim_url, Settings.overpass_url, Settings.fossgis_osrm_url, Settings.graphhopper_url], :form_action => %w[render.openstreetmap.org], :style_src => %w['unsafe-inline'] ) - if STATUS == :database_offline || STATUS == :api_offline + if Settings.status == "database_offline" || Settings.status == "api_offline" flash.now[:warning] = t("layouts.osm_offline") - elsif STATUS == :database_readonly || STATUS == :api_readonly + elsif Settings.status == "database_readonly" || Settings.status == "api_readonly" flash.now[:warning] = t("layouts.osm_read_only") end @@ -357,7 +299,7 @@ class ApplicationController < ActionController::Base elsif current_user&.preferred_editor current_user.preferred_editor else - DEFAULT_EDITOR + Settings.default_editor end editor @@ -366,9 +308,9 @@ class ApplicationController < ActionController::Base helper_method :preferred_editor def update_totp - if defined?(TOTP_KEY) + if Settings.key?(:totp_key) cookies["_osm_totp_token"] = { - :value => ROTP::TOTP.new(TOTP_KEY, :interval => 3600).now, + :value => ROTP::TOTP.new(Settings.totp_key, :interval => 3600).now, :domain => "openstreetmap.org", :expires => 1.hour.from_now } @@ -395,15 +337,7 @@ class ApplicationController < ActionController::Base end end - def deny_access(exception) - if @api_deny_access_handling - api_deny_access(exception) - else - web_deny_access(exception) - end - end - - def web_deny_access(_exception) + def deny_access(_exception) if current_token set_locale report_error t("oauth.permissions.missing"), :forbidden @@ -423,28 +357,6 @@ class ApplicationController < ActionController::Base end end - def api_deny_access(_exception) - if current_token - set_locale - report_error t("oauth.permissions.missing"), :forbidden - elsif current_user - head :forbidden - else - realm = "Web Password" - errormessage = "Couldn't authenticate you" - response.headers["WWW-Authenticate"] = "Basic realm=\"#{realm}\"" - render :plain => errormessage, :status => :unauthorized - end - end - - attr_accessor :api_access_handling - - def api_deny_access_handler - @api_deny_access_handling = true - end - - private - # extract authorisation credentials from headers, returns user = nil if none def get_auth_data if request.env.key? "X-HTTP_AUTHORIZATION" # where mod_rewrite might have put it diff --git a/app/controllers/browse_controller.rb b/app/controllers/browse_controller.rb index 0fccbb506..ebdd2cd80 100644 --- a/app/controllers/browse_controller.rb +++ b/app/controllers/browse_controller.rb @@ -3,7 +3,7 @@ class BrowseController < ApplicationController before_action :authorize_web before_action :set_locale - before_action(:except => [:query]) { |c| c.check_database_readable(true) } + before_action -> { check_database_readable(true) } before_action :require_oauth around_action :web_timeout authorize_resource :class => false diff --git a/app/controllers/changeset_comments_controller.rb b/app/controllers/changeset_comments_controller.rb index 05b28eacf..4abffb90e 100644 --- a/app/controllers/changeset_comments_controller.rb +++ b/app/controllers/changeset_comments_controller.rb @@ -4,7 +4,7 @@ class ChangesetCommentsController < ApplicationController authorize_resource - before_action(:only => [:index]) { |c| c.check_database_readable(true) } + before_action -> { check_database_readable(true) } around_action :web_timeout ## diff --git a/app/controllers/changesets_controller.rb b/app/controllers/changesets_controller.rb index a69d0d57b..32d9fd733 100644 --- a/app/controllers/changesets_controller.rb +++ b/app/controllers/changesets_controller.rb @@ -7,10 +7,10 @@ class ChangesetsController < ApplicationController skip_before_action :verify_authenticity_token, :except => [:index] before_action :authorize_web before_action :set_locale + before_action -> { check_database_readable(true) }, :only => [:index, :feed] authorize_resource - before_action(:only => [:index, :feed]) { |c| c.check_database_readable(true) } around_action :web_timeout # Helper methods for checking consistency diff --git a/app/controllers/diary_entries_controller.rb b/app/controllers/diary_entries_controller.rb index 4a1da178a..fb1e7b702 100644 --- a/app/controllers/diary_entries_controller.rb +++ b/app/controllers/diary_entries_controller.rb @@ -3,11 +3,11 @@ class DiaryEntriesController < ApplicationController before_action :authorize_web before_action :set_locale + before_action :check_database_readable authorize_resource before_action :lookup_user, :only => [:show, :comments] - before_action :check_database_readable before_action :check_database_writable, :only => [:new, :edit, :comment, :hide, :hidecomment, :subscribe, :unsubscribe] before_action :allow_thirdparty_images, :only => [:new, :edit, :index, :show, :comments] @@ -158,7 +158,7 @@ class DiaryEntriesController < ApplicationController @entries = user.diary_entries @title = t("diary_entries.feed.user.title", :user => user.display_name) @description = t("diary_entries.feed.user.description", :user => user.display_name) - @link = url_for :action => "index", :display_name => user.display_name, :host => SERVER_URL, :protocol => SERVER_PROTOCOL + @link = url_for :action => "index", :display_name => user.display_name, :host => Settings.server_url, :protocol => Settings.server_protocol else head :not_found return @@ -170,11 +170,11 @@ class DiaryEntriesController < ApplicationController @entries = @entries.where(:language_code => params[:language]) @title = t("diary_entries.feed.language.title", :language_name => Language.find(params[:language]).english_name) @description = t("diary_entries.feed.language.description", :language_name => Language.find(params[:language]).english_name) - @link = url_for :action => "index", :language => params[:language], :host => SERVER_URL, :protocol => SERVER_PROTOCOL + @link = url_for :action => "index", :language => params[:language], :host => Settings.server_url, :protocol => Settings.server_protocol else @title = t("diary_entries.feed.all.title") @description = t("diary_entries.feed.all.description") - @link = url_for :action => "index", :host => SERVER_URL, :protocol => SERVER_PROTOCOL + @link = url_for :action => "index", :host => Settings.server_url, :protocol => Settings.server_protocol end end diff --git a/app/controllers/geocoder_controller.rb b/app/controllers/geocoder_controller.rb index d9b56147f..4a8f77650 100644 --- a/app/controllers/geocoder_controller.rb +++ b/app/controllers/geocoder_controller.rb @@ -15,7 +15,7 @@ class GeocoderController < ApplicationController if @params[:lat] && @params[:lon] @sources.push "latlon" @sources.push "osm_nominatim_reverse" - @sources.push "geonames_reverse" if defined?(GEONAMES_USERNAME) + @sources.push "geonames_reverse" if Settings.key?(:geonames_username) elsif @params[:query] if @params[:query].match?(/^\d{5}(-\d{4})?$/) @sources.push "osm_nominatim" @@ -26,7 +26,7 @@ class GeocoderController < ApplicationController @sources.push "osm_nominatim" else @sources.push "osm_nominatim" - @sources.push "geonames" if defined?(GEONAMES_USERNAME) + @sources.push "geonames" if Settings.key?(:geonames_username) end end @@ -93,7 +93,7 @@ class GeocoderController < ApplicationController if response.get_elements("geodata/error").empty? @results.push(:lat => response.text("geodata/latt"), :lon => response.text("geodata/longt"), - :zoom => POSTCODE_ZOOM, + :zoom => Settings.postcode_zoom, :name => query.upcase) end @@ -118,7 +118,7 @@ class GeocoderController < ApplicationController exclude = "&exclude_place_ids=#{params[:exclude]}" if params[:exclude] # ask nominatim - response = fetch_xml("#{NOMINATIM_URL}search?format=xml&extratags=1&q=#{escape_query(query)}#{viewbox}#{exclude}&accept-language=#{http_accept_language.user_preferred_languages.join(',')}") + response = fetch_xml("#{Settings.nominatim_url}search?format=xml&extratags=1&q=#{escape_query(query)}#{viewbox}#{exclude}&accept-language=#{http_accept_language.user_preferred_languages.join(',')}") # extract the results from the response results = response.elements["searchresults"] @@ -182,7 +182,7 @@ class GeocoderController < ApplicationController @results = [] # ask geonames.org - response = fetch_xml("http://api.geonames.org/search?q=#{escape_query(query)}&lang=#{lang}&maxRows=20&username=#{GEONAMES_USERNAME}") + response = fetch_xml("http://api.geonames.org/search?q=#{escape_query(query)}&lang=#{lang}&maxRows=20&username=#{Settings.geonames_username}") # parse the response response.elements.each("geonames/geoname") do |geoname| @@ -192,7 +192,7 @@ class GeocoderController < ApplicationController country = geoname.text("countryName") @results.push(:lat => lat, :lon => lon, - :zoom => GEONAMES_ZOOM, + :zoom => Settings.geonames_zoom, :name => name, :suffix => ", #{country}") end @@ -213,7 +213,7 @@ class GeocoderController < ApplicationController @results = [] # ask nominatim - response = fetch_xml("#{NOMINATIM_URL}reverse?lat=#{lat}&lon=#{lon}&zoom=#{zoom}&accept-language=#{http_accept_language.user_preferred_languages.join(',')}") + response = fetch_xml("#{Settings.nominatim_url}reverse?lat=#{lat}&lon=#{lon}&zoom=#{zoom}&accept-language=#{http_accept_language.user_preferred_languages.join(',')}") # parse the response response.elements.each("reversegeocode/result") do |result| @@ -247,7 +247,7 @@ class GeocoderController < ApplicationController @results = [] # ask geonames.org - response = fetch_xml("http://api.geonames.org/countrySubdivision?lat=#{lat}&lng=#{lon}&lang=#{lang}&username=#{GEONAMES_USERNAME}") + response = fetch_xml("http://api.geonames.org/countrySubdivision?lat=#{lat}&lng=#{lon}&lang=#{lang}&username=#{Settings.geonames_username}") # parse the response response.elements.each("geonames/countrySubdivision") do |geoname| @@ -255,7 +255,7 @@ class GeocoderController < ApplicationController country = geoname.text("countryName") @results.push(:lat => lat, :lon => lon, - :zoom => GEONAMES_ZOOM, + :zoom => Settings.geonames_zoom, :name => name, :suffix => ", #{country}") end diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index dce0099e5..5aa5aba70 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -26,7 +26,7 @@ class MessagesController < ApplicationController @message.sender = current_user @message.sent_on = Time.now.getutc - if current_user.sent_messages.where("sent_on >= ?", Time.now.getutc - 1.hour).count >= MAX_MESSAGES_PER_HOUR + if current_user.sent_messages.where("sent_on >= ?", Time.now.getutc - 1.hour).count >= Settings.max_messages_per_hour flash[:error] = t ".limit_exceeded" render :action => "new" elsif @message.save diff --git a/app/controllers/oauth_controller.rb b/app/controllers/oauth_controller.rb index 225fc0677..babd27c53 100644 --- a/app/controllers/oauth_controller.rb +++ b/app/controllers/oauth_controller.rb @@ -39,7 +39,7 @@ class OauthController < ApplicationController end def oauth1_authorize - override_content_security_policy_directives(:form_action => []) if CSP_ENFORCE || defined?(CSP_REPORT_URL) + override_content_security_policy_directives(:form_action => []) if Settings.csp_enforce || Settings.key?(:csp_report_url) if @token.invalidated? @message = t "oauth.authorize_failure.invalid" diff --git a/app/controllers/site_controller.rb b/app/controllers/site_controller.rb index 5833a1e04..471e9f3c5 100644 --- a/app/controllers/site_controller.rb +++ b/app/controllers/site_controller.rb @@ -12,7 +12,7 @@ class SiteController < ApplicationController authorize_resource :class => false def index - session[:location] ||= OSM.ip_location(request.env["REMOTE_ADDR"]) unless STATUS == :database_readonly || STATUS == :database_offline + session[:location] ||= OSM.ip_location(request.env["REMOTE_ADDR"]) unless Settings.status == "database_readonly" || Settings.status == "database_offline" end def permalink diff --git a/app/controllers/traces_controller.rb b/app/controllers/traces_controller.rb index b488d717a..334aa2aa6 100644 --- a/app/controllers/traces_controller.rb +++ b/app/controllers/traces_controller.rb @@ -3,10 +3,10 @@ class TracesController < ApplicationController before_action :authorize_web before_action :set_locale + before_action :check_database_readable authorize_resource - before_action :check_database_readable before_action :check_database_writable, :only => [:new, :create, :edit, :delete] before_action :offline_warning, :only => [:mine, :show] before_action :offline_redirect, :only => [:new, :create, :edit, :delete, :data] @@ -121,7 +121,7 @@ class TracesController < ApplicationController flash[:notice] = t ".trace_uploaded" flash[:warning] = t ".traces_waiting", :count => current_user.traces.where(:inserted => false).count if current_user.traces.where(:inserted => false).count > 4 - TraceImporterJob.perform_later(@trace) if TRACE_USE_JOB_QUEUE + TraceImporterJob.perform_later(@trace) if Settings.trace_use_job_queue redirect_to :action => :index, :display_name => current_user.display_name else flash[:error] = t("traces.create.upload_failed") if @trace.valid? @@ -205,7 +205,7 @@ class TracesController < ApplicationController trace.visible = false trace.save flash[:notice] = t ".scheduled_for_deletion" - TraceDestroyerJob.perform_later(trace) if TRACE_USE_JOB_QUEUE + TraceDestroyerJob.perform_later(trace) if Settings.trace_use_job_queue redirect_to :action => :index, :display_name => trace.user.display_name end rescue ActiveRecord::RecordNotFound @@ -323,11 +323,11 @@ class TracesController < ApplicationController end def offline_warning - flash.now[:warning] = t "traces.offline_warning.message" if STATUS == :gpx_offline + flash.now[:warning] = t "traces.offline_warning.message" if Settings.status == "gpx_offline" end def offline_redirect - redirect_to :action => :offline if STATUS == :gpx_offline + redirect_to :action => :offline if Settings.status == "gpx_offline" end def default_visibility diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index fa5b22a98..9b97fa0a1 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -5,18 +5,18 @@ class UsersController < ApplicationController before_action :disable_terms_redirect, :only => [:terms, :save, :logout] before_action :authorize_web before_action :set_locale + before_action :check_database_readable authorize_resource before_action :require_self, :only => [:account] - before_action :check_database_readable, :except => [:login] before_action :check_database_writable, :only => [:new, :account, :confirm, :confirm_email, :lost_password, :reset_password, :go_public, :make_friend, :remove_friend] before_action :require_cookies, :only => [:new, :login, :confirm] before_action :lookup_user_by_name, :only => [:set_status, :delete] before_action :allow_thirdparty_images, :only => [:show, :account] def terms - @legale = params[:legale] || OSM.ip_to_country(request.remote_ip) || DEFAULT_LEGALE + @legale = params[:legale] || OSM.ip_to_country(request.remote_ip) || Settings.default_legale @text = OSM.legal_text_for_country(@legale) if request.xhr? @@ -332,7 +332,7 @@ class UsersController < ApplicationController flash[:error] = t "users.confirm_resend.failure", :name => params[:display_name] else Notifier.signup_confirm(user, user.tokens.create).deliver_later - flash[:notice] = t("users.confirm_resend.success", :email => user.email, :sender => SUPPORT_EMAIL).html_safe + flash[:notice] = t("users.confirm_resend.success", :email => user.email, :sender => Settings.support_email).html_safe end redirect_to :action => "login" @@ -521,7 +521,7 @@ class UsersController < ApplicationController when "active", "confirmed" then successful_login(user, request.env["omniauth.params"]["referer"]) when "suspended" then - failed_login t("users.login.account is suspended", :webmaster => "mailto:#{SUPPORT_EMAIL}").html_safe + failed_login t("users.login.account is suspended", :webmaster => "mailto:#{Settings.support_email}").html_safe else failed_login t("users.login.auth failure") end @@ -549,7 +549,7 @@ class UsersController < ApplicationController elsif user = User.authenticate(:username => username, :password => password, :pending => true) unconfirmed_login(user) elsif User.authenticate(:username => username, :password => password, :suspended => true) - failed_login t("users.login.account is suspended", :webmaster => "mailto:#{SUPPORT_EMAIL}").html_safe, username + failed_login t("users.login.account is suspended", :webmaster => "mailto:#{Settings.support_email}").html_safe, username else failed_login t("users.login.auth failure"), username end diff --git a/app/helpers/notifier_helper.rb b/app/helpers/notifier_helper.rb index a696a3d9c..1c2e5e654 100644 --- a/app/helpers/notifier_helper.rb +++ b/app/helpers/notifier_helper.rb @@ -12,7 +12,7 @@ module NotifierHelper # the but Outlook only on the :style => "text-decoration: none" ), - user_url(display_name, :host => SERVER_URL), + user_url(display_name, :host => Settings.server_url), :target => "_blank", :rel => "noopener", :style => "text-decoration: none; color: #222" diff --git a/app/jobs/trace_destroyer_job.rb b/app/jobs/trace_destroyer_job.rb index e2a050288..66b777b2c 100644 --- a/app/jobs/trace_destroyer_job.rb +++ b/app/jobs/trace_destroyer_job.rb @@ -1,5 +1,5 @@ class TraceDestroyerJob < ApplicationJob - queue_as :default + queue_as :traces def perform(trace) trace.destroy diff --git a/app/jobs/trace_importer_job.rb b/app/jobs/trace_importer_job.rb index d41de5836..6b8943aa2 100644 --- a/app/jobs/trace_importer_job.rb +++ b/app/jobs/trace_importer_job.rb @@ -1,5 +1,5 @@ class TraceImporterJob < ApplicationJob - queue_as :default + queue_as :traces def perform(trace) gpx = trace.import diff --git a/app/mailers/notifier.rb b/app/mailers/notifier.rb index 4b53c66f6..e705efb00 100644 --- a/app/mailers/notifier.rb +++ b/app/mailers/notifier.rb @@ -1,6 +1,6 @@ class Notifier < ActionMailer::Base - default :from => EMAIL_FROM, - :return_path => EMAIL_RETURN_PATH, + default :from => Settings.email_from, + :return_path => Settings.email_return_path, :auto_submitted => "auto-generated" helper :application before_action :set_shared_template_vars @@ -196,14 +196,14 @@ class Notifier < ActionMailer::Base end def from_address(name, type, id, digest, user_id = nil) - if Object.const_defined?(:MESSAGES_DOMAIN) && domain = MESSAGES_DOMAIN + if Settings.key?(:messages_domain) && domain = Settings.messages_domain if user_id "#{name} <#{type}-#{id}-#{user_id}-#{digest[0, 6]}@#{domain}>" else "#{name} <#{type}-#{id}-#{digest[0, 6]}@#{domain}>" end else - EMAIL_FROM + Settings.email_from end end end diff --git a/app/models/changeset.rb b/app/models/changeset.rb index 5cdfeb994..3ca719f6c 100644 --- a/app/models/changeset.rb +++ b/app/models/changeset.rb @@ -196,67 +196,6 @@ class Changeset < ActiveRecord::Base end end - def to_xml(include_discussion = false) - doc = OSM::API.new.get_xml_doc - doc.root << to_xml_node(nil, include_discussion) - doc - end - - def to_xml_node(user_display_name_cache = nil, include_discussion = false) - el1 = XML::Node.new "changeset" - el1["id"] = id.to_s - - user_display_name_cache = {} if user_display_name_cache.nil? - - if user_display_name_cache&.key?(user_id) - # use the cache if available - elsif user.data_public? - user_display_name_cache[user_id] = user.display_name - else - user_display_name_cache[user_id] = nil - end - - el1["user"] = user_display_name_cache[user_id] unless user_display_name_cache[user_id].nil? - el1["uid"] = user_id.to_s if user.data_public? - - tags.each do |k, v| - el2 = XML::Node.new("tag") - el2["k"] = k.to_s - el2["v"] = v.to_s - el1 << el2 - end - - el1["created_at"] = created_at.xmlschema - el1["closed_at"] = closed_at.xmlschema unless is_open? - el1["open"] = is_open?.to_s - - bbox.to_unscaled.add_bounds_to(el1, "_") if bbox.complete? - - el1["comments_count"] = comments.length.to_s - el1["changes_count"] = num_changes.to_s - - if include_discussion - el2 = XML::Node.new("discussion") - comments.includes(:author).each do |comment| - el3 = XML::Node.new("comment") - el3["date"] = comment.created_at.xmlschema - el3["uid"] = comment.author.id.to_s if comment.author.data_public? - el3["user"] = comment.author.display_name.to_s if comment.author.data_public? - el4 = XML::Node.new("text") - el4.content = comment.body.to_s - el3 << el4 - el2 << el3 - end - el1 << el2 - end - - # NOTE: changesets don't include the XML of the changes within them, - # they are just structures for tagging. to get the osmChange of a - # changeset, see the download method of the controller. - - el1 - end - ## # update this instance from another instance given and the user who is # doing the updating. note that this method is not for updating the diff --git a/app/models/client_application.rb b/app/models/client_application.rb index 5dafaaa5c..ae95e2908 100644 --- a/app/models/client_application.rb +++ b/app/models/client_application.rb @@ -67,7 +67,7 @@ class ClientApplication < ActiveRecord::Base end def oauth_server - @oauth_server ||= OAuth::Server.new("https://" + SERVER_URL) + @oauth_server ||= OAuth::Server.new("https://" + Settings.server_url) end def credentials diff --git a/app/models/request_token.rb b/app/models/request_token.rb index ed0cc3ae4..f7c9501b5 100644 --- a/app/models/request_token.rb +++ b/app/models/request_token.rb @@ -77,6 +77,6 @@ class RequestToken < OauthToken end def oauth10? - (defined? OAUTH_10_SUPPORT) && OAUTH_10_SUPPORT && callback_url.blank? + Settings.key?(:oauth_10_support) && Settings.oauth_10_support && callback_url.blank? end end diff --git a/app/models/trace.rb b/app/models/trace.rb index d2c715245..0e8763328 100644 --- a/app/models/trace.rb +++ b/app/models/trace.rb @@ -110,15 +110,15 @@ class Trace < ActiveRecord::Base end def large_picture_name - "#{GPX_IMAGE_DIR}/#{id}.gif" + "#{Settings.gpx_image_dir}/#{id}.gif" end def icon_picture_name - "#{GPX_IMAGE_DIR}/#{id}_icon.gif" + "#{Settings.gpx_image_dir}/#{id}_icon.gif" end def trace_name - "#{GPX_TRACE_DIR}/#{id}.gpx" + "#{Settings.gpx_trace_dir}/#{id}.gpx" end def mime_type @@ -289,21 +289,34 @@ class Trace < ActiveRecord::Base # If there are any existing points for this trace then delete them Tracepoint.where(:gpx_id => id).delete_all - gpx.points do |point| - if first - f_lat = point.latitude - f_lon = point.longitude - first = false + gpx.points.each_slice(1_000) do |points| + # Gather the trace points together for a bulk import + tracepoints = [] + + points.each do |point| + if first + f_lat = point.latitude + f_lon = point.longitude + first = false + end + + tp = Tracepoint.new + tp.lat = point.latitude + tp.lon = point.longitude + tp.altitude = point.altitude + tp.timestamp = point.timestamp + tp.gpx_id = id + tp.trackid = point.segment + tracepoints << tp end - tp = Tracepoint.new - tp.lat = point.latitude - tp.lon = point.longitude - tp.altitude = point.altitude - tp.timestamp = point.timestamp - tp.gpx_id = id - tp.trackid = point.segment - tp.save! + # Run the before_save and before_create callbacks, and then import them in bulk with activerecord-import + tracepoints.each do |tp| + tp.run_callbacks(:save) { false } + tp.run_callbacks(:create) { false } + end + + Tracepoint.import!(tracepoints) end if gpx.actual_points.positive? diff --git a/app/models/user.rb b/app/models/user.rb index fba429338..9f1310843 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -201,7 +201,7 @@ class User < ActiveRecord::Base @preferred_languages = nil end - def nearby(radius = NEARBY_RADIUS, num = NEARBY_USERS) + def nearby(radius = Settings.nearby_radius, num = Settings.nearby_users) if home_lon && home_lat gc = OSM::GreatCircle.new(home_lat, home_lon) sql_for_area = QuadTile.sql_for_area(gc.bounds(radius), "home_") @@ -300,7 +300,7 @@ class User < ActiveRecord::Base ## # perform a spam check on a user def spam_check - update(:status => "suspended") if status == "active" && spam_score > SPAM_THRESHOLD + update(:status => "suspended") if status == "active" && spam_score > Settings.spam_threshold end ## diff --git a/app/models/user_block.rb b/app/models/user_block.rb index 02af385a7..27bc40498 100644 --- a/app/models/user_block.rb +++ b/app/models/user_block.rb @@ -32,7 +32,7 @@ class UserBlock < ActiveRecord::Base belongs_to :creator, :class_name => "User", :foreign_key => :creator_id belongs_to :revoker, :class_name => "User", :foreign_key => :revoker_id - PERIODS = USER_BLOCK_PERIODS + PERIODS = Settings.user_block_periods ## # scope to match active blocks diff --git a/app/models/way.rb b/app/models/way.rb index c95a12122..6573b9805 100644 --- a/app/models/way.rb +++ b/app/models/way.rb @@ -206,7 +206,7 @@ class Way < ActiveRecord::Base def preconditions_ok?(old_nodes = []) return false if nds.empty? - raise OSM::APITooManyWayNodesError.new(id, nds.length, MAX_NUMBER_OF_WAY_NODES) if nds.length > MAX_NUMBER_OF_WAY_NODES + raise OSM::APITooManyWayNodesError.new(id, nds.length, Settings.max_number_of_way_nodes) if nds.length > Settings.max_number_of_way_nodes # check only the new nodes, for efficiency - old nodes having been checked last time and can't # be deleted when they're in-use. diff --git a/app/views/api/capabilities/show.builder b/app/views/api/capabilities/show.builder index 3fa79058b..682373898 100644 --- a/app/views/api/capabilities/show.builder +++ b/app/views/api/capabilities/show.builder @@ -1,20 +1,20 @@ 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) + api.version(:minimum => Settings.api_version, :maximum => Settings.api_version) + api.area(:maximum => Settings.max_request_area) + api.note_area(:maximum => Settings.max_note_request_area) + api.tracepoints(:per_page => Settings.tracepoints_per_page) + api.waynodes(:maximum => Settings.max_number_of_way_nodes) + api.changesets(:maximum_elements => Changeset::MAX_ELEMENTS) + api.timeout(:seconds => Settings.api_timeout) + api.status(:database => @database_status, + :api => @api_status, + :gpx => @gpx_status) end osm.policy do |policy| policy.imagery do |imagery| - IMAGERY_BLACKLIST.each do |url_regex| + Settings.imagery_blacklist.each do |url_regex| imagery.blacklist(:regex => url_regex.to_s) end end diff --git a/app/views/api/changesets/_changeset.builder b/app/views/api/changesets/_changeset.builder new file mode 100644 index 000000000..47c494d9b --- /dev/null +++ b/app/views/api/changesets/_changeset.builder @@ -0,0 +1,43 @@ +# basic attributes + +attrs = { + "id" => changeset.id, + "created_at" => changeset.created_at.xmlschema, + "open" => changeset.is_open?, + "comments_count" => changeset.comments.length, + "changes_count" => changeset.num_changes +} +attrs["closed_at"] = changeset.closed_at unless changeset.is_open? +changeset.bbox.to_unscaled.add_bounds_to(attrs, "_") if changeset.bbox.complete? + +# user attributes + +if changeset.user.data_public? + attrs["uid"] = changeset.user_id + attrs["user"] = changeset.user.display_name +end + +xml.changeset(attrs) do |changeset_xml_node| + changeset.tags.each do |k, v| + changeset_xml_node.tag(:k => k, :v => v) + end + + # include discussion if requested + + if @include_discussion + changeset_xml_node.discussion do |discussion_xml_node| + changeset.comments.includes(:author).each do |comment| + cattrs = { + "date" => comment.created_at.xmlschema + } + if comment.author.data_public? + cattrs["uid"] = comment.author.id + cattrs["user"] = comment.author.display_name + end + discussion_xml_node.comment(cattrs) do |comment_xml_node| + comment_xml_node.text(comment.body) + end + end + end + end +end diff --git a/app/views/api/changesets/changeset.builder b/app/views/api/changesets/changeset.builder new file mode 100644 index 000000000..e8da4006f --- /dev/null +++ b/app/views/api/changesets/changeset.builder @@ -0,0 +1,7 @@ +xml.instruct! :xml, :version => "1.0" + +# basic attributes + +xml.osm(OSM::API.new.xml_root_attributes) do |osm| + osm << render(:partial => "api/changesets/changeset.builder", :locals => { :changeset => @changeset }) +end diff --git a/app/views/api/changesets/changesets.builder b/app/views/api/changesets/changesets.builder new file mode 100644 index 000000000..da434f1f4 --- /dev/null +++ b/app/views/api/changesets/changesets.builder @@ -0,0 +1,9 @@ +xml.instruct! :xml, :version => "1.0" + +# basic attributes + +xml.osm(OSM::API.new.xml_root_attributes) do |osm| + @changesets.each do |changeset| + osm << render(:partial => "api/changesets/changeset.builder", :locals => { :changeset => changeset }) + end +end diff --git a/app/views/layouts/_head.html.erb b/app/views/layouts/_head.html.erb index 8c6b246d8..86d4665cf 100644 --- a/app/views/layouts/_head.html.erb +++ b/app/views/layouts/_head.html.erb @@ -25,8 +25,8 @@ <%= tag("meta", { :name => "msapplication-TileImage", :content => image_path("mstile-144x144.png") }) %> <%= tag("meta", { :name => "theme-color", :content => "#ffffff" }) %> <%= canonical_tag %> - <% if defined?(PUBLISHER_URL) -%> - <%= tag("link", { :rel => "publisher", :href => PUBLISHER_URL }) %> + <% if Settings.key?(:publisher_url) -%> + <%= tag("link", { :rel => "publisher", :href => Settings.publisher_url }) %> <% end -%> <%= tag("link", { :rel => "search", :type => "application/opensearchdescription+xml", :title => "OpenStreetMap Search", :href => asset_path("osm.xml") }) %> <%= tag("meta", { :name => "description", :content => "OpenStreetMap is the free wiki world map." }) %> diff --git a/app/views/layouts/_header.html.erb b/app/views/layouts/_header.html.erb index 946f95feb..a9919f7d2 100644 --- a/app/views/layouts/_header.html.erb +++ b/app/views/layouts/_header.html.erb @@ -54,7 +54,7 @@