+ if current_user&.languages&.empty? && !http_accept_language.user_preferred_languages.empty?
+ current_user.languages = http_accept_language.user_preferred_languages
+ current_user.save
+ end
+
+ I18n.locale = Locale.available.preferred(preferred_languages)
+
+ response.headers["Vary"] = "Accept-Language"
+ response.headers["Content-Language"] = I18n.locale.to_s
+ end
+
+ ##
+ # wrap a web page in a timeout
+ def web_timeout(&)
+ raise Timeout::Error if Settings.web_timeout.negative?
+
+ Timeout.timeout(Settings.web_timeout, &)
+ rescue ActionView::Template::Error => e
+ e = e.cause
+
+ if e.is_a?(Timeout::Error) ||
+ (e.is_a?(ActiveRecord::StatementInvalid) && e.message.include?("execution expired"))
+ respond_to_timeout
+ else
+ raise
+ end
+ rescue Timeout::Error
+ respond_to_timeout
+ end
+
+ def respond_to_timeout
+ ActiveRecord::Base.connection.raw_connection.cancel
+ render :action => "timeout", :status => :gateway_timeout
+ end
+
+ ##
+ # Unfortunately if a PUT or POST request that has a body fails to
+ # read it then Apache will sometimes fail to return the response it
+ # is given to the client properly, instead erroring:
+ #
+ # https://issues.apache.org/bugzilla/show_bug.cgi?id=44782
+ #
+ # To work round this we call rewind on the body here, which is added
+ # as a filter, to force it to be fetched from Apache into a file.
+ def fetch_body
+ request.body.rewind
+ end
+
+ def map_layout
+ policy = request.content_security_policy.clone
+
+ policy.connect_src(*policy.connect_src, "http://127.0.0.1:8111", Settings.nominatim_url, Settings.overpass_url, Settings.fossgis_osrm_url, Settings.graphhopper_url, Settings.fossgis_valhalla_url)
+ policy.form_action(*policy.form_action, "render.openstreetmap.org")
+ policy.style_src(*policy.style_src, :unsafe_inline)
+
+ request.content_security_policy = policy
+
+ case Settings.status
+ when "database_offline", "api_offline"
+ flash.now[:warning] = t("layouts.osm_offline")
+ when "database_readonly", "api_readonly"
+ flash.now[:warning] = t("layouts.osm_read_only")
+ end
+
+ request.xhr? ? "xhr" : "map"
+ end
+
+ def preferred_editor
+ if params[:editor]
+ params[:editor]
+ elsif current_user&.preferred_editor
+ current_user.preferred_editor
+ else
+ Settings.default_editor
+ end
+ end
+
+ def preferred_color_scheme(subject)
+ if current_user
+ current_user.preferences.find_by(:k => "#{subject}.color_scheme")&.v || "auto"
+ else
+ "auto"
+ end
+ end
+
+ helper_method :preferred_editor, :preferred_color_scheme
+
+ def update_totp
+ if Settings.key?(:totp_key)
+ cookies["_osm_totp_token"] = {
+ :value => ROTP::TOTP.new(Settings.totp_key, :interval => 3600).now,
+ :domain => "openstreetmap.org",
+ :expires => 1.hour.from_now
+ }
+ end
+ end
+
+ def current_ability
+ Ability.new(current_user)
+ end
+
+ def deny_access(_exception)
+ if doorkeeper_token
+ set_locale
+ report_error t("oauth.permissions.missing"), :forbidden
+ elsif current_user
+ set_locale
+ respond_to do |format|
+ format.html { redirect_to :controller => "/errors", :action => "forbidden" }
+ format.any { report_error t("application.permission_denied"), :forbidden }