forked from instructure/canvas-lms
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Never try to load things from CDN that won't be there
fixes: CNVS-22486 there are 2 specific things that this fixes: 1.) the 403 error trying to load favicon.ico from the CDN 2.) if a school has custom js, on the mobile login screen, it calls include_account_js(raw:true) which would try to load: https://du11hjcvx0uqb.cloudfront.net/optimized/vendor/jquery-1.7.2.js?1439243240 this fixes both of those cases but it will more generally fix it so we never try to load a file that is un-revved or outside of /dist/brandable_css from the CDN (since they won't be there) test plan: with CDN enabled: * open any page, the favicon should load and not have a 403 in console * on a domain with new styles turned off, and from an account that has a custom js override file, go to the mobile login page (you can do this in desktop safari by picking Develop->User Agent->iPhone) and make sure jquery is loaded before their custom js loads Change-Id: I877a8ef10a0b612fe7e43f47147e8148e7f98ff3 Reviewed-on: https://gerrit.instructure.com/60690 Tested-by: Jenkins Reviewed-by: Jacob Fugal <[email protected]> QA-Review: August Thornton <[email protected]> Product-Review: Rob Orton <[email protected]>
- Loading branch information
Showing
9 changed files
with
244 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 0 additions & 67 deletions
67
config/initializers/make_rails_asset_helpers_use_gulp_filenames.rb
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# This is where we monkeypatch rails to look at the rev-manifest.json file we make in `gulp rev` | ||
# instead of doing it's normal cache busting stuff on the url. | ||
# eg: instead of '/images/whatever.png?12345', we want '/dist/images/whatever-<md5 of file>.png'. | ||
# There is a different method that needs to be monkeypatched for rails 3 vs rails 4 | ||
if CANVAS_RAILS3 | ||
module ActionView | ||
module Helpers | ||
module AssetTagHelper | ||
class AssetPaths | ||
private | ||
|
||
# Rails 3 expects us to override 'rewrite_asset_path' if we want to do something other than the | ||
# default "/images/whatever.png?12345". | ||
def rewrite_asset_path_with_rev_manifest(source, dir, options = nil) | ||
# our brandable_css stylesheets are already fingerprinted, we don't need to do anything to them | ||
return source if source =~ /^\/dist\/brandable_css/ | ||
|
||
key = (source[0] == '/') ? source : "#{dir}/#{source}" | ||
Canvas::Cdn::RevManifest.url_for(key) || rewrite_asset_path_without_rev_manifest(source, dir, options) | ||
end | ||
alias_method_chain :rewrite_asset_path, :rev_manifest | ||
|
||
end | ||
end | ||
end | ||
end | ||
else | ||
require 'action_view/helpers/asset_url_helper' | ||
module ActionView | ||
module Helpers | ||
module AssetUrlHelper | ||
|
||
# Rails 4 leaves us 'path_to_asset' to override instead. | ||
def path_to_asset_with_rev_manifest(source, options = {}) | ||
original_path = path_to_asset_without_rev_manifest(source, options) | ||
revved_url = Canvas::Cdn::RevManifest.url_for(original_path) | ||
if revved_url | ||
File.join(compute_asset_host(revved_url, options).to_s, revved_url) | ||
else | ||
original_path | ||
end | ||
end | ||
alias_method_chain :path_to_asset, :rev_manifest | ||
|
||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
require 'set' | ||
|
||
# An interface to the manifest file created by `gulp rev` | ||
module Canvas | ||
module Cdn | ||
module RevManifest | ||
class << self | ||
delegate :include?, to: :revved_urls | ||
|
||
def manifest | ||
load_data_if_needed | ||
@manifest | ||
end | ||
|
||
def revved_urls | ||
load_data_if_needed | ||
@revved_urls | ||
end | ||
|
||
def url_for(source) | ||
# remove the leading slash if there is one | ||
source = source.sub(/^\//, '') | ||
fingerprinted = manifest[source] | ||
"/dist/#{fingerprinted}" if fingerprinted | ||
end | ||
|
||
private | ||
def load_data_if_needed | ||
# don't look this up every request in prduction | ||
return if ActionController::Base.perform_caching && defined? @manifest | ||
file = Rails.root.join('public', 'dist', 'rev-manifest.json') | ||
if file.exist? | ||
Rails.logger.debug "reading rev-manifest.json" | ||
@manifest = JSON.parse(file.read).freeze | ||
elsif Rails.env.production? | ||
raise "you need to run `gulp rev` first" | ||
else | ||
@manifest = {}.freeze | ||
end | ||
@revved_urls = Set.new(@manifest.values.map{|s| "/dist/#{s}" }).freeze | ||
end | ||
|
||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
require File.expand_path(File.dirname(__FILE__) + '/common') | ||
|
||
describe "brandableCss JS integration specs" do | ||
include_context "in-process server selenium tests" | ||
|
||
EXAMPLE_CDN_HOST = 'https://somecdn.example.com' | ||
|
||
it "sets ENV.asset_host correctly" do | ||
Canvas::Cdn.config.expects(:host).at_least_once.returns(EXAMPLE_CDN_HOST) | ||
get "/login/canvas" | ||
expect(driver.execute_script("return ENV.ASSET_HOST")).to eq(EXAMPLE_CDN_HOST) | ||
end | ||
|
||
it "loads css from handlebars correctly" do | ||
admin_logged_in | ||
get "/accounts/#{Account.default.id}/permissions?account_roles=1" | ||
|
||
css_bundle = 'jst/roles/rolesOverrideIndex' | ||
fingerprint = BrandableCSS.fingerprint_for(css_bundle, 'legacy_normal_contrast') | ||
css_url = "#{Canvas::Cdn.config.host}/dist/brandable_css/legacy_normal_contrast/#{css_bundle}-#{fingerprint}.css" | ||
expect(fj("head link[rel='stylesheet'][data-loaded-by-brandableCss][href*='#{css_bundle}']")['href']).to match(css_url) | ||
|
||
driver.execute_script("window.ENV.ASSET_HOST = '#{EXAMPLE_CDN_HOST}'") | ||
EXAMPLE_CSS_BUNDLE = 'jst/some/css/bundle-12345.css' | ||
require_exec('compiled/util/brandableCss', "brandableCss.loadStylesheet('#{EXAMPLE_CSS_BUNDLE}')") | ||
css_url = "#{EXAMPLE_CDN_HOST}/dist/brandable_css/legacy_normal_contrast/#{EXAMPLE_CSS_BUNDLE}.css" | ||
expect(fj("head link[rel='stylesheet'][data-loaded-by-brandableCss][href*='jst/some/css/bundle']")['href']).to eq(css_url) | ||
end | ||
|
||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
# Why are these in spec/selenium? | ||
# =============================== | ||
# Although these tests don't use selenium at all, they need to be have assets | ||
# compiled in order to work. eg: `gulp rev` and `brandable_css` need to run first. | ||
# By putting them in spec/selenium, our build server will run them with the rest | ||
# of the browser specs, after it has compiled assets. | ||
|
||
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') | ||
|
||
RE_SHORT_MD5 = /\A[a-f0-9]{10}\z/ # 10 chars of an MD5 | ||
|
||
EXAMPLE_CDN_HOST = 'https://somecdn.example.com' | ||
|
||
describe 'Stuff related to how we load stuff from CDN and use brandable_css' do | ||
|
||
describe BrandableCSS do | ||
|
||
describe 'fingerprint_for' do | ||
|
||
it 'finds the right fingerprints for normal bundles, plugins & handlebars' do | ||
sample_bundles = { | ||
'bundles/common' => true, | ||
'plugins/analytics/analytics' => true, # to test that it works with plugins | ||
'jst/tinymce/EquationEditorView' => false # to test that it works with handlebars-loaded css | ||
} | ||
sample_bundles.each do |bundle_name, bundle_loads_variables| | ||
fingerprints = BrandableCSS.variants.map do |variant| | ||
fingerprint = BrandableCSS.fingerprint_for(bundle_name, variant) | ||
expect(fingerprint).to match(RE_SHORT_MD5) | ||
fingerprint | ||
end | ||
|
||
expect(fingerprints.length).to eq(4), 'We have 4 variants' | ||
msg = 'make sure the conbined results match the result of all_fingerprints_for' | ||
expect(fingerprints).to eq(BrandableCSS.all_fingerprints_for(bundle_name).values), msg | ||
|
||
msg = "all variants should outupt the same css if a bundle doesn't pull in | ||
the variables file. If it does, there should be some that are different" | ||
expect(fingerprints.uniq.length).to(bundle_loads_variables ? (be > 1) : eq(1), msg) | ||
end | ||
end | ||
end | ||
end | ||
|
||
|
||
def check_css(bundle_name) | ||
fingerprint = BrandableCSS.fingerprint_for(bundle_name, 'legacy_normal_contrast') | ||
expect(fingerprint).to match(RE_SHORT_MD5) | ||
assert_tag(tag: 'link', attributes: { | ||
rel: 'stylesheet', | ||
href: "#{EXAMPLE_CDN_HOST}/dist/brandable_css/legacy_normal_contrast/#{bundle_name}-#{fingerprint}.css" | ||
}) | ||
end | ||
|
||
def check_asset(tag, asset_path) | ||
revved_path = Canvas::Cdn::RevManifest.url_for(asset_path) | ||
expect(revved_path).to be_present | ||
attributes = {} | ||
attributes[(tag == 'link') ? :href : :src] = "#{EXAMPLE_CDN_HOST}#{revved_path}" | ||
assert_tag(tag: tag, attributes: attributes) | ||
end | ||
|
||
describe 'urls for script tag and stylesheets on actual pages', :type => :request do | ||
|
||
it 'has the right stuff on the login page' do | ||
Canvas::Cdn.config.expects(:host).at_least_once.returns(EXAMPLE_CDN_HOST) | ||
get '/login/canvas' | ||
|
||
['bundles/common', 'bundles/login'].each { |bundle| check_css(bundle) } | ||
['images/favicon-yellow.ico', 'images/apple-touch-icon.png'].each { |i| check_asset('link', i) } | ||
js_base_url = ENV['USE_OPTIMIZED_JS'] == 'true' ? '/optimized' : '/javascripts' | ||
['vendor/require.js', 'compiled/bundles/login.js'].each { |s| check_asset('script', "#{js_base_url}/#{s}") } | ||
end | ||
|
||
it "loads custom js 'raw' on mobile login screen" do | ||
js_url = 'https://example.com/path/to/some/file.js' | ||
Account.default.settings[:global_includes] = true | ||
Account.default.settings[:global_javascript] = js_url | ||
Account.default.save! | ||
|
||
get '/login/canvas', {}, { 'HTTP_USER_AGENT' => 'iphone' } | ||
# match /optimized/vendor/jquery-1.7.2.js?1440111591 or /optimized/vendor/jquery-1.7.2.js | ||
assert_tag(tag: 'script', attributes: { src: /^\/optimized\/vendor\/jquery-1.7.2.js(\?\d+)*$/}) | ||
assert_tag(tag: 'script', attributes: { src: js_url}) | ||
end | ||
end | ||
end |