Thibaut Courouble %!s(int64=7) %!d(string=hai) anos
pai
achega
7d3c6bd970

+ 1 - 0
Gemfile

@@ -11,6 +11,7 @@ group :app do
   gem 'rack'
   gem 'sinatra'
   gem 'sinatra-contrib'
+  gem 'rack-ssl-enforcer'
   gem 'thin'
   gem 'sprockets'
   gem 'sprockets-helpers'

+ 2 - 0
Gemfile.lock

@@ -63,6 +63,7 @@ GEM
     rack (2.0.5)
     rack-protection (2.0.4)
       rack
+    rack-ssl-enforcer (0.2.9)
     rack-test (1.1.0)
       rack (>= 1.0, < 3)
     rake (12.3.1)
@@ -140,6 +141,7 @@ DEPENDENCIES
   progress_bar
   pry (~> 0.11.0)
   rack
+  rack-ssl-enforcer
   rack-test
   rake
   rr

+ 1 - 1
assets/javascripts/lib/page.coffee

@@ -190,7 +190,7 @@ isSameOrigin = (url) ->
 
 updateCanonicalLink = ->
   @canonicalLink ||= document.head.querySelector('link[rel="canonical"]')
-  @canonicalLink.setAttribute('href', "http://#{location.host}#{location.pathname}")
+  @canonicalLink.setAttribute('href', "https://#{location.host}#{location.pathname}")
 
 trackers = []
 

+ 0 - 11
assets/javascripts/templates/pages/root_tmpl.coffee.erb

@@ -72,14 +72,3 @@ app.templates.androidWarning = """
     <p>To install DevDocs on your phone, visit <a href="https://devdocs.io" target="_blank" rel="noopener">devdocs.io</a> in Chrome and select "Add to home screen" in the menu.
   </div>
 """
-
-app.templates.httpWarning = """
-  <div class="_intro"><div class="_intro-message">
-    <h2 class="_intro-title">Hi there!</h2>
-    <p>DevDocs is migrating to HTTPS.
-    <p>Please update your bookmarks to point to <a href="https://devdocs.io">https://devdocs.io</a>.
-    <p>When using the HTTPS version, your preferences will carry over automatically, but your offline data will be reset. Simply re-download documentation in the <a href="https://devdocs.io/offline">Offline area</a>, and you'll be all set to use DevDocs securely offline.
-    <p>Sorry for the inconvenience. This migration is needed because browsers are removing support for certain DOM APIs that power DevDocs's offline mode over non-secure origins.
-    <p>Thanks for using DevDocs, and happy coding!
-  </div></div>
-"""

+ 0 - 4
assets/javascripts/views/content/root_page.coffee

@@ -19,10 +19,6 @@ class app.views.RootPage extends app.View
     else
       'intro'
 
-    # temporary
-    if location.host is 'devdocs.io' and location.protocol is 'http:'
-      tmpl = 'httpWarning'
-
     @append @tmpl(tmpl)
     return
 

+ 2 - 0
lib/app.rb

@@ -12,6 +12,8 @@ class App < Sinatra::Application
   Rack::Mime::MIME_TYPES['.webapp'] = 'application/x-web-app-manifest+json'
 
   configure do
+    use Rack::SslEnforcer, only_environments: ['production', 'test'], hsts: false, force_secure_cookies: false
+
     set :sentry_dsn, ENV['SENTRY_DSN']
     set :protection, except: [:frame_options, :xss_header]
 

+ 31 - 21
test/app_test.rb

@@ -11,6 +11,16 @@ class AppTest < MiniTest::Spec
     App
   end
 
+  before do
+    current_session.env('HTTPS', 'on')
+  end
+
+  it 'redirects to HTTPS' do
+    get 'http://example.com/test?q=1', {}, 'HTTPS' => 'off'
+    assert last_response.redirect?
+    assert_equal 'https://example.com/test?q=1', last_response['Location']
+  end
+
   describe "/" do
     it "works" do
       get '/'
@@ -20,13 +30,13 @@ class AppTest < MiniTest::Spec
     it "redirects to /#q= when there is a 'q' query param" do
       get '/search', q: 'foo'
       assert last_response.redirect?
-      assert_equal 'http://example.org/#q=foo', last_response['Location']
+      assert_equal 'https://example.org/#q=foo', last_response['Location']
     end
 
     it "redirects without the query string" do
       get '/', foo: 'bar'
       assert last_response.redirect?
-      assert_equal 'http://example.org/', last_response['Location']
+      assert_equal 'https://example.org/', last_response['Location']
     end
 
     it "sets default size" do
@@ -52,7 +62,7 @@ class AppTest < MiniTest::Spec
       %w(offline about news help).each do |page|
         get "/#{page}", {}, 'HTTP_USER_AGENT' => MODERN_BROWSER
         assert last_response.redirect?
-        assert_equal "http://example.org/#/#{page}", last_response['Location']
+        assert_equal "https://example.org/#/#{page}", last_response['Location']
       end
     end
 
@@ -61,7 +71,7 @@ class AppTest < MiniTest::Spec
         set_cookie('foo=bar')
         get "/#{page}", {}, 'HTTP_USER_AGENT' => MODERN_BROWSER
         assert last_response.redirect?
-        assert_equal 'http://example.org/', last_response['Location']
+        assert_equal 'https://example.org/', last_response['Location']
         assert last_response['Set-Cookie'].start_with?("initial_path=%2F#{page}; path=/; expires=")
       end
     end
@@ -71,11 +81,11 @@ class AppTest < MiniTest::Spec
     it "redirects to /#q=" do
       get '/search'
       assert last_response.redirect?
-      assert_equal 'http://example.org/#q=', last_response['Location']
+      assert_equal 'https://example.org/#q=', last_response['Location']
 
       get '/search', q: 'foo'
       assert last_response.redirect?
-      assert_equal 'http://example.org/#q=foo', last_response['Location']
+      assert_equal 'https://example.org/#q=foo', last_response['Location']
     end
   end
 
@@ -148,7 +158,7 @@ class AppTest < MiniTest::Spec
       set_cookie('docs=html~5')
       get '/html~5/', {}, 'HTTP_USER_AGENT' => MODERN_BROWSER
       assert last_response.redirect?
-      assert_equal 'http://example.org/', last_response['Location']
+      assert_equal 'https://example.org/', last_response['Location']
       assert last_response['Set-Cookie'].start_with?("initial_path=%2Fhtml%7E5%2F; path=/; expires=")
     end
 
@@ -161,13 +171,13 @@ class AppTest < MiniTest::Spec
       set_cookie('docs=html~5')
       get '/html/', {}, 'HTTP_USER_AGENT' => MODERN_BROWSER
       assert last_response.redirect?
-      assert_equal 'http://example.org/', last_response['Location']
+      assert_equal 'https://example.org/', last_response['Location']
       assert last_response['Set-Cookie'].start_with?("initial_path=%2Fhtml%2F; path=/; expires=")
     end
 
     it "renders when the doc exists and is enabled, and the request is from Googlebot" do
       set_cookie('docs=html')
-      get '/html/', {}, 'HTTP_USER_AGENT' => 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
+      get '/html/', {}, 'HTTP_USER_AGENT' => 'Mozilla/5.0 (compatible; Googlebot/2.1; +https://www.google.com/bot.html)'
       assert last_response.ok?
     end
 
@@ -187,17 +197,17 @@ class AppTest < MiniTest::Spec
     it "redirects with trailing slash" do
       get '/html'
       assert last_response.redirect?
-      assert_equal 'http://example.org/html/', last_response['Location']
+      assert_equal 'https://example.org/html/', last_response['Location']
 
       get '/html', bar: 'baz'
       assert last_response.redirect?
-      assert_equal 'http://example.org/html/?bar=baz', last_response['Location']
+      assert_equal 'https://example.org/html/?bar=baz', last_response['Location']
     end
 
     it "redirects old docs" do
       get '/iojs/'
       assert last_response.redirect?
-      assert_equal 'http://example.org/node/', last_response['Location']
+      assert_equal 'https://example.org/node/', last_response['Location']
     end
   end
 
@@ -232,17 +242,17 @@ class AppTest < MiniTest::Spec
     it "redirects with trailing slash" do
       get '/css-foo'
       assert last_response.redirect?
-      assert_equal 'http://example.org/css-foo/', last_response['Location']
+      assert_equal 'https://example.org/css-foo/', last_response['Location']
 
       get '/css-foo', bar: 'baz'
       assert last_response.redirect?
-      assert_equal 'http://example.org/css-foo/?bar=baz', last_response['Location']
+      assert_equal 'https://example.org/css-foo/?bar=baz', last_response['Location']
     end
 
     it "redirects old docs" do
       get '/yii1-foo/'
       assert last_response.redirect?
-      assert_equal 'http://example.org/yii~1.1-foo/', last_response['Location']
+      assert_equal 'https://example.org/yii~1.1-foo/', last_response['Location']
     end
   end
 
@@ -263,17 +273,17 @@ class AppTest < MiniTest::Spec
     it "redirects without trailing slash" do
       get '/css/foo/'
       assert last_response.redirect?
-      assert_equal 'http://example.org/css/foo', last_response['Location']
+      assert_equal 'https://example.org/css/foo', last_response['Location']
 
       get '/css/foo/', bar: 'baz'
       assert last_response.redirect?
-      assert_equal 'http://example.org/css/foo?bar=baz', last_response['Location']
+      assert_equal 'https://example.org/css/foo?bar=baz', last_response['Location']
     end
 
     it "redirects old docs" do
       get '/python2/foo'
       assert last_response.redirect?
-      assert_equal 'http://example.org/python~2.7/foo', last_response['Location']
+      assert_equal 'https://example.org/python~2.7/foo', last_response['Location']
     end
   end
 
@@ -281,7 +291,7 @@ class AppTest < MiniTest::Spec
     it "returns to the asset path" do
       get '/docs.json'
       assert last_response.redirect?
-      assert_equal 'http://example.org/assets/docs.json', last_response['Location']
+      assert_equal 'https://example.org/assets/docs.json', last_response['Location']
     end
   end
 
@@ -289,7 +299,7 @@ class AppTest < MiniTest::Spec
     it "returns to the asset path" do
       get '/application.js'
       assert last_response.redirect?
-      assert_equal 'http://example.org/assets/application.js', last_response['Location']
+      assert_equal 'https://example.org/assets/application.js', last_response['Location']
     end
   end
 
@@ -297,7 +307,7 @@ class AppTest < MiniTest::Spec
     it "returns to the asset path" do
       get '/application.css'
       assert last_response.redirect?
-      assert_equal 'http://example.org/assets/application.css', last_response['Location']
+      assert_equal 'https://example.org/assets/application.css', last_response['Location']
     end
   end