Rename HTTP Feature Policy to Permissions Policy

HTTP Feature-Policy has been renamed to Permissions-Policy:
* Original issue: https://github.com/w3c/webappsec-permissions-policy/issues/359
* PR: https://github.com/w3c/webappsec-permissions-policy/pull/379
* Doc: https://w3c.github.io/webappsec-permissions-policy/

Mozilla documentation has been updated on July 2020:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy
This commit is contained in:
Julien Grillot 2020-11-14 13:13:54 +01:00
parent 19850107cd
commit 90e710d767
15 changed files with 82 additions and 82 deletions

View File

@ -29,7 +29,7 @@ module ActionController
autoload :DefaultHeaders
autoload :EtagWithTemplateDigest
autoload :EtagWithFlash
autoload :FeaturePolicy
autoload :PermissionsPolicy
autoload :Flash
autoload :Head
autoload :Helpers

View File

@ -226,7 +226,7 @@ module ActionController
FormBuilder,
RequestForgeryProtection,
ContentSecurityPolicy,
FeaturePolicy,
PermissionsPolicy,
Streaming,
DataStreaming,
HttpAuthentication::Basic::ControllerMethods,

View File

@ -1,11 +1,11 @@
# frozen_string_literal: true
module ActionController #:nodoc:
# HTTP Feature Policy is a web standard for defining a mechanism to
# allow and deny the use of browser features in its own context, and
# HTTP Permissions Policy is a web standard for defining a mechanism to
# allow and deny the use of browser permissions in its own context, and
# in content within any <iframe> elements in the document.
#
# Full details of HTTP Feature Policy specification and guidelines can
# Full details of HTTP Permissions Policy specification and guidelines can
# be found at MDN:
#
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy
@ -13,7 +13,7 @@ module ActionController #:nodoc:
# Examples of usage:
#
# # Global policy
# Rails.application.config.feature_policy do |f|
# Rails.application.config.permissions_policy do |f|
# f.camera :none
# f.gyroscope :none
# f.microphone :none
@ -24,20 +24,20 @@ module ActionController #:nodoc:
#
# # Controller level policy
# class PagesController < ApplicationController
# feature_policy do |p|
# permissions_policy do |p|
# p.geolocation "https://example.com"
# end
# end
module FeaturePolicy
module PermissionsPolicy
extend ActiveSupport::Concern
module ClassMethods
def feature_policy(**options, &block)
def permissions_policy(**options, &block)
before_action(options) do
if block_given?
policy = request.feature_policy.clone
policy = request.permissions_policy.clone
yield policy
request.feature_policy = policy
request.permissions_policy = policy
end
end
end

View File

@ -46,7 +46,7 @@ module ActionDispatch
eager_autoload do
autoload_under "http" do
autoload :ContentSecurityPolicy
autoload :FeaturePolicy
autoload :PermissionsPolicy
autoload :Request
autoload :Response
end

View File

@ -3,10 +3,10 @@
require "active_support/core_ext/object/deep_dup"
module ActionDispatch #:nodoc:
class FeaturePolicy
class PermissionsPolicy
class Middleware
CONTENT_TYPE = "Content-Type"
POLICY = "Feature-Policy"
POLICY = "Permissions-Policy"
def initialize(app)
@app = app
@ -19,7 +19,7 @@ module ActionDispatch #:nodoc:
return response unless html_response?(headers)
return response if policy_present?(headers)
if policy = request.feature_policy
if policy = request.permissions_policy
headers[POLICY] = policy.build(request.controller_instance)
end
@ -47,13 +47,13 @@ module ActionDispatch #:nodoc:
end
module Request
POLICY = "action_dispatch.feature_policy"
POLICY = "action_dispatch.permissions_policy"
def feature_policy
def permissions_policy
get_header(POLICY)
end
def feature_policy=(policy)
def permissions_policy=(policy)
set_header(POLICY, policy)
end
end
@ -63,8 +63,8 @@ module ActionDispatch #:nodoc:
none: "'none'",
}.freeze
# List of available features can be found at
# https://github.com/WICG/feature-policy/blob/master/features.md#policy-controlled-features
# List of available permissions can be found at
# https://github.com/w3c/webappsec-permissions-policy/blob/master/features.md#policy-controlled-features
DIRECTIVES = {
accelerometer: "accelerometer",
ambient_light_sensor: "ambient-light-sensor",
@ -121,14 +121,14 @@ module ActionDispatch #:nodoc:
when String, Proc
source
else
raise ArgumentError, "Invalid HTTP feature policy source: #{source.inspect}"
raise ArgumentError, "Invalid HTTP permissions policy source: #{source.inspect}"
end
end
end
def apply_mapping(source)
MAPPINGS.fetch(source) do
raise ArgumentError, "Unknown HTTP feature policy source mapping: #{source.inspect}"
raise ArgumentError, "Unknown HTTP permissions policy source mapping: #{source.inspect}"
end
end
@ -156,12 +156,12 @@ module ActionDispatch #:nodoc:
source.to_s
when Proc
if context.nil?
raise RuntimeError, "Missing context for the dynamic feature policy source: #{source.inspect}"
raise RuntimeError, "Missing context for the dynamic permissions policy source: #{source.inspect}"
else
context.instance_exec(&source)
end
else
raise RuntimeError, "Unexpected feature policy source: #{source.inspect}"
raise RuntimeError, "Unexpected permissions policy source: #{source.inspect}"
end
end
end

View File

@ -23,7 +23,7 @@ module ActionDispatch
include ActionDispatch::Http::FilterParameters
include ActionDispatch::Http::URL
include ActionDispatch::ContentSecurityPolicy::Request
include ActionDispatch::FeaturePolicy::Request
include ActionDispatch::PermissionsPolicy::Request
include Rack::Request::Env
autoload :Session, "action_dispatch/request/session"

View File

@ -2,9 +2,9 @@
require "abstract_unit"
class FeaturePolicyTest < ActiveSupport::TestCase
class PermissionsPolicyTest < ActiveSupport::TestCase
def setup
@policy = ActionDispatch::FeaturePolicy.new
@policy = ActionDispatch::PermissionsPolicy.new
end
def test_mappings
@ -37,22 +37,22 @@ class FeaturePolicyTest < ActiveSupport::TestCase
@policy.vr [:non_existent]
end
assert_equal "Invalid HTTP feature policy source: [:non_existent]", exception.message
assert_equal "Invalid HTTP permissions policy source: [:non_existent]", exception.message
end
end
class FeaturePolicyIntegrationTest < ActionDispatch::IntegrationTest
class PermissionsPolicyIntegrationTest < ActionDispatch::IntegrationTest
class PolicyController < ActionController::Base
feature_policy only: :index do |f|
permissions_policy only: :index do |f|
f.gyroscope :none
end
feature_policy only: :sample_controller do |f|
permissions_policy only: :sample_controller do |f|
f.gyroscope nil
f.usb :self
end
feature_policy only: :multiple_directives do |f|
permissions_policy only: :multiple_directives do |f|
f.gyroscope nil
f.usb :self
f.autoplay "https://example.com"
@ -74,14 +74,14 @@ class FeaturePolicyIntegrationTest < ActionDispatch::IntegrationTest
ROUTES = ActionDispatch::Routing::RouteSet.new
ROUTES.draw do
scope module: "feature_policy_integration_test" do
scope module: "permissions_policy_integration_test" do
get "/", to: "policy#index"
get "/sample_controller", to: "policy#sample_controller"
get "/multiple_directives", to: "policy#multiple_directives"
end
end
POLICY = ActionDispatch::FeaturePolicy.new do |p|
POLICY = ActionDispatch::PermissionsPolicy.new do |p|
p.gyroscope :self
end
@ -91,7 +91,7 @@ class FeaturePolicyIntegrationTest < ActionDispatch::IntegrationTest
end
def call(env)
env["action_dispatch.feature_policy"] = POLICY
env["action_dispatch.permissions_policy"] = POLICY
env["action_dispatch.show_exceptions"] = false
@app.call(env)
@ -100,24 +100,24 @@ class FeaturePolicyIntegrationTest < ActionDispatch::IntegrationTest
APP = build_app(ROUTES) do |middleware|
middleware.use PolicyConfigMiddleware
middleware.use ActionDispatch::FeaturePolicy::Middleware
middleware.use ActionDispatch::PermissionsPolicy::Middleware
end
def app
APP
end
def test_generates_feature_policy_header
def test_generates_permissions_policy_header
get "/"
assert_policy "gyroscope 'none'"
end
def test_generates_per_controller_feature_policy_header
def test_generates_per_controller_permissions_policy_header
get "/sample_controller"
assert_policy "usb 'self'"
end
def test_generates_multiple_directives_feature_policy_header
def test_generates_multiple_directives_permissions_policy_header
get "/multiple_directives"
assert_policy "usb 'self'; autoplay https://example.com; payment https://secure.example.com"
end
@ -127,16 +127,16 @@ class FeaturePolicyIntegrationTest < ActionDispatch::IntegrationTest
Rails.application.env_config
end
def feature_policy
env_config["action_dispatch.feature_policy"]
def permissions_policy
env_config["action_dispatch.permissions_policy"]
end
def feature_policy=(policy)
env_config["action_dispatch.feature_policy"] = policy
def permissions_policy=(policy)
env_config["action_dispatch.permissions_policy"] = policy
end
def assert_policy(expected)
assert_response :success
assert_equal expected, response.headers["Feature-Policy"]
assert_equal expected, response.headers["Permissions-Policy"]
end
end

View File

@ -286,7 +286,7 @@ module Rails
"action_dispatch.content_security_policy_report_only" => config.content_security_policy_report_only,
"action_dispatch.content_security_policy_nonce_generator" => config.content_security_policy_nonce_generator,
"action_dispatch.content_security_policy_nonce_directives" => config.content_security_policy_nonce_directives,
"action_dispatch.feature_policy" => config.feature_policy,
"action_dispatch.permissions_policy" => config.permissions_policy,
)
end
end

View File

@ -73,7 +73,7 @@ module Rails
@autoloader = :classic
@disable_sandbox = false
@add_autoload_paths_to_load_path = true
@feature_policy = nil
@permissions_policy = nil
@rake_eager_load = false
end
@ -325,11 +325,11 @@ module Rails
end
end
def feature_policy(&block)
def permissions_policy(&block)
if block_given?
@feature_policy = ActionDispatch::FeaturePolicy.new(&block)
@permissions_policy = ActionDispatch::PermissionsPolicy.new(&block)
else
@feature_policy
@permissions_policy
end
end

View File

@ -69,7 +69,7 @@ module Rails
unless config.api_only
middleware.use ::ActionDispatch::ContentSecurityPolicy::Middleware
middleware.use ::ActionDispatch::FeaturePolicy::Middleware
middleware.use ::ActionDispatch::PermissionsPolicy::Middleware
end
middleware.use ::Rack::Head

View File

@ -138,7 +138,7 @@ module Rails
rack_cors_config_exist = File.exist?("config/initializers/cors.rb")
assets_config_exist = File.exist?("config/initializers/assets.rb")
csp_config_exist = File.exist?("config/initializers/content_security_policy.rb")
feature_policy_config_exist = File.exist?("config/initializers/feature_policy.rb")
permissions_policy_config_exist = File.exist?("config/initializers/permissions_policy.rb")
@config_target_version = Rails.application.config.loaded_config_version || "5.0"
@ -174,8 +174,8 @@ module Rails
remove_file "config/initializers/content_security_policy.rb"
end
unless feature_policy_config_exist
remove_file "config/initializers/feature_policy.rb"
unless permissions_policy_config_exist
remove_file "config/initializers/permissions_policy.rb"
end
end
end
@ -527,7 +527,7 @@ module Rails
if options[:api]
remove_file "config/initializers/cookies_serializer.rb"
remove_file "config/initializers/content_security_policy.rb"
remove_file "config/initializers/feature_policy.rb"
remove_file "config/initializers/permissions_policy.rb"
end
end

View File

@ -1,7 +1,7 @@
# Define an application-wide HTTP feature policy. For further
# Define an application-wide HTTP permissions policy. For further
# information see https://developers.google.com/web/updates/2018/06/feature-policy
#
# Rails.application.config.feature_policy do |f|
# Rails.application.config.permissions_policy do |f|
# f.camera :none
# f.gyroscope :none
# f.microphone :none

View File

@ -46,7 +46,7 @@ module ApplicationTests
"ActionDispatch::Session::CookieStore",
"ActionDispatch::Flash",
"ActionDispatch::ContentSecurityPolicy::Middleware",
"ActionDispatch::FeaturePolicy::Middleware",
"ActionDispatch::PermissionsPolicy::Middleware",
"Rack::Head",
"Rack::ConditionalGet",
"Rack::ETag",

View File

@ -4,7 +4,7 @@ require "isolation/abstract_unit"
require "rack/test"
module ApplicationTests
class FeaturePolicyTest < ActiveSupport::TestCase
class PermissionsPolicyTest < ActiveSupport::TestCase
include ActiveSupport::Testing::Isolation
include Rack::Test::Methods
@ -16,7 +16,7 @@ module ApplicationTests
teardown_app
end
test "feature policy is not enabled by default" do
test "permissions policy is not enabled by default" do
controller :pages, <<-RUBY
class PagesController < ApplicationController
def index
@ -34,10 +34,10 @@ module ApplicationTests
app("development")
get "/"
assert_nil last_response.headers["Feature-Policy"]
assert_nil last_response.headers["Permissions-Policy"]
end
test "global feature policy in an initializer" do
test "global permissions policy in an initializer" do
controller :pages, <<-RUBY
class PagesController < ApplicationController
def index
@ -46,8 +46,8 @@ module ApplicationTests
end
RUBY
app_file "config/initializers/feature_policy.rb", <<-RUBY
Rails.application.config.feature_policy do |p|
app_file "config/initializers/permissions_policy.rb", <<-RUBY
Rails.application.config.permissions_policy do |p|
p.geolocation :none
end
RUBY
@ -64,10 +64,10 @@ module ApplicationTests
assert_policy "geolocation 'none'"
end
test "override feature policy using same directive in a controller" do
test "override permissions policy using same directive in a controller" do
controller :pages, <<-RUBY
class PagesController < ApplicationController
feature_policy do |p|
permissions_policy do |p|
p.geolocation "https://example.com"
end
@ -77,8 +77,8 @@ module ApplicationTests
end
RUBY
app_file "config/initializers/feature_policy.rb", <<-RUBY
Rails.application.config.feature_policy do |p|
app_file "config/initializers/permissions_policy.rb", <<-RUBY
Rails.application.config.permissions_policy do |p|
p.geolocation :none
end
RUBY
@ -95,10 +95,10 @@ module ApplicationTests
assert_policy "geolocation https://example.com"
end
test "override feature policy by unsetting a directive in a controller" do
test "override permissions policy by unsetting a directive in a controller" do
controller :pages, <<-RUBY
class PagesController < ApplicationController
feature_policy do |p|
permissions_policy do |p|
p.geolocation nil
end
@ -108,8 +108,8 @@ module ApplicationTests
end
RUBY
app_file "config/initializers/feature_policy.rb", <<-RUBY
Rails.application.config.feature_policy do |p|
app_file "config/initializers/permissions_policy.rb", <<-RUBY
Rails.application.config.permissions_policy do |p|
p.geolocation :none
end
RUBY
@ -124,13 +124,13 @@ module ApplicationTests
get "/"
assert_equal 200, last_response.status
assert_nil last_response.headers["Feature-Policy"]
assert_nil last_response.headers["Permissions-Policy"]
end
test "override feature policy using different directives in a controller" do
test "override permissions policy using different directives in a controller" do
controller :pages, <<-RUBY
class PagesController < ApplicationController
feature_policy do |p|
permissions_policy do |p|
p.geolocation nil
p.payment "https://secure.example.com"
p.autoplay :none
@ -142,8 +142,8 @@ module ApplicationTests
end
RUBY
app_file "config/initializers/feature_policy.rb", <<-RUBY
Rails.application.config.feature_policy do |p|
app_file "config/initializers/permissions_policy.rb", <<-RUBY
Rails.application.config.permissions_policy do |p|
p.geolocation :none
end
RUBY
@ -160,9 +160,9 @@ module ApplicationTests
assert_policy "payment https://secure.example.com; autoplay 'none'"
end
test "global feature policy added to rack app" do
app_file "config/initializers/feature_policy.rb", <<-RUBY
Rails.application.config.feature_policy do |p|
test "global permissions policy added to rack app" do
app_file "config/initializers/permissions_policy.rb", <<-RUBY
Rails.application.config.permissions_policy do |p|
p.payment :none
end
RUBY
@ -185,7 +185,7 @@ module ApplicationTests
private
def assert_policy(expected)
assert_equal 200, last_response.status
assert_equal expected, last_response.headers["Feature-Policy"]
assert_equal expected, last_response.headers["Permissions-Policy"]
end
end
end

View File

@ -96,7 +96,7 @@ class ApiAppGeneratorTest < Rails::Generators::TestCase
assert_no_file "config/initializers/cookies_serializer.rb"
assert_no_file "config/initializers/assets.rb"
assert_no_file "config/initializers/content_security_policy.rb"
assert_no_file "config/initializers/feature_policy.rb"
assert_no_file "config/initializers/permissions_policy.rb"
end
def test_app_update_does_not_generate_unnecessary_bin_files
@ -172,7 +172,7 @@ class ApiAppGeneratorTest < Rails::Generators::TestCase
config/initializers/assets.rb
config/initializers/cookies_serializer.rb
config/initializers/content_security_policy.rb
config/initializers/feature_policy.rb
config/initializers/permissions_policy.rb
lib/assets
test/helpers
tmp/cache/assets