Skip to content

Commit

Permalink
Rename HTTP Feature Policy to Permissions Policy
Browse files Browse the repository at this point in the history
HTTP Feature-Policy has been renamed to Permissions-Policy:
* Original issue: w3c/webappsec-permissions-policy#359
* PR: w3c/webappsec-permissions-policy#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
  • Loading branch information
Bahanix authored and fxn committed Nov 18, 2020
1 parent f2c01f2 commit c06f9a1
Show file tree
Hide file tree
Showing 15 changed files with 82 additions and 82 deletions.
2 changes: 1 addition & 1 deletion actionpack/lib/action_controller.rb
Expand Up @@ -29,7 +29,7 @@ module ActionController
autoload :DefaultHeaders
autoload :EtagWithTemplateDigest
autoload :EtagWithFlash
autoload :FeaturePolicy
autoload :PermissionsPolicy
autoload :Flash
autoload :Head
autoload :Helpers
Expand Down
2 changes: 1 addition & 1 deletion actionpack/lib/action_controller/base.rb
Expand Up @@ -226,7 +226,7 @@ def self.without_modules(*modules)
FormBuilder,
RequestForgeryProtection,
ContentSecurityPolicy,
FeaturePolicy,
PermissionsPolicy,
Streaming,
DataStreaming,
HttpAuthentication::Basic::ControllerMethods,
Expand Down
@@ -1,19 +1,19 @@
# 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
#
# 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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion actionpack/lib/action_dispatch.rb
Expand Up @@ -46,7 +46,7 @@ class MissingController < NameError
eager_autoload do
autoload_under "http" do
autoload :ContentSecurityPolicy
autoload :FeaturePolicy
autoload :PermissionsPolicy
autoload :Request
autoload :Response
end
Expand Down
Expand Up @@ -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
Expand All @@ -19,7 +19,7 @@ def call(env)
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

Expand Down Expand Up @@ -47,13 +47,13 @@ def policy_empty?(policy)
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
Expand All @@ -63,8 +63,8 @@ def feature_policy=(policy)
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",
Expand Down Expand Up @@ -121,14 +121,14 @@ def apply_mappings(sources)
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

Expand Down Expand Up @@ -156,12 +156,12 @@ def resolve_source(source, context)
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
Expand Down
2 changes: 1 addition & 1 deletion actionpack/lib/action_dispatch/http/request.rb
Expand Up @@ -23,7 +23,7 @@ class Request
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"
Expand Down
Expand Up @@ -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
Expand Down Expand Up @@ -37,22 +37,22 @@ def test_invalid_directive_source
@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"
Expand All @@ -74,14 +74,14 @@ def multiple_directives

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

Expand All @@ -91,7 +91,7 @@ def initialize(app)
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)
Expand All @@ -100,24 +100,24 @@ def call(env)

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
Expand All @@ -127,16 +127,16 @@ def env_config
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
2 changes: 1 addition & 1 deletion railties/lib/rails/application.rb
Expand Up @@ -286,7 +286,7 @@ def env_config
"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
Expand Down
8 changes: 4 additions & 4 deletions railties/lib/rails/application/configuration.rb
Expand Up @@ -73,7 +73,7 @@ def initialize(*)
@autoloader = :classic
@disable_sandbox = false
@add_autoload_paths_to_load_path = true
@feature_policy = nil
@permissions_policy = nil
@rake_eager_load = false
end

Expand Down Expand Up @@ -325,11 +325,11 @@ def content_security_policy(&block)
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

Expand Down
2 changes: 1 addition & 1 deletion railties/lib/rails/application/default_middleware_stack.rb
Expand Up @@ -69,7 +69,7 @@ def build_stack

unless config.api_only
middleware.use ::ActionDispatch::ContentSecurityPolicy::Middleware
middleware.use ::ActionDispatch::FeaturePolicy::Middleware
middleware.use ::ActionDispatch::PermissionsPolicy::Middleware
end

middleware.use ::Rack::Head
Expand Down
8 changes: 4 additions & 4 deletions railties/lib/rails/generators/rails/app/app_generator.rb
Expand Up @@ -138,7 +138,7 @@ def config_when_updating
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"

Expand Down Expand Up @@ -174,8 +174,8 @@ def config_when_updating
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
Expand Down Expand Up @@ -527,7 +527,7 @@ def delete_non_api_initializers_if_api_option
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

Expand Down
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion railties/test/application/middleware_test.rb
Expand Up @@ -46,7 +46,7 @@ def app
"ActionDispatch::Session::CookieStore",
"ActionDispatch::Flash",
"ActionDispatch::ContentSecurityPolicy::Middleware",
"ActionDispatch::FeaturePolicy::Middleware",
"ActionDispatch::PermissionsPolicy::Middleware",
"Rack::Head",
"Rack::ConditionalGet",
"Rack::ETag",
Expand Down

0 comments on commit c06f9a1

Please sign in to comment.