diff --git a/saas/lib/fizzy/saas/authorization.rb b/saas/lib/fizzy/saas/authorization.rb new file mode 100644 index 000000000..53117d98e --- /dev/null +++ b/saas/lib/fizzy/saas/authorization.rb @@ -0,0 +1,28 @@ +module Fizzy + module Saas + module Authorization + module Controller + extend ActiveSupport::Concern + + included do + before_action :ensure_only_employees_can_access_non_production_remote_environments, if: :authenticated? + end + + private + def ensure_only_employees_can_access_non_production_remote_environments + head :forbidden if Rails.env.staging? && !Current.identity.employee? + end + end + + module Identity + extend ActiveSupport::Concern + + EMPLOYEE_DOMAINS = ["@37signals.com", "@basecamp.com"].freeze + + def employee? + email_address.end_with?(*EMPLOYEE_DOMAINS) + end + end + end + end +end diff --git a/saas/lib/fizzy/saas/engine.rb b/saas/lib/fizzy/saas/engine.rb index 4da208a72..d9414b0cf 100644 --- a/saas/lib/fizzy/saas/engine.rb +++ b/saas/lib/fizzy/saas/engine.rb @@ -1,5 +1,6 @@ require_relative "transaction_pinning" require_relative "signup" +require_relative "authorization" require_relative "../../rails_ext/active_record_tasks_database_tasks.rb" module Fizzy @@ -112,6 +113,9 @@ module Fizzy ::Object.send(:remove_const, const_name) if ::Object.const_defined?(const_name) ::Object.const_set const_name, Subscription.const_get(short_name, false) end + + ::Authorization.include Fizzy::Saas::Authorization::Controller + ::Identity.include Fizzy::Saas::Authorization::Identity end end end diff --git a/saas/test/controllers/non_production_remote_access_test.rb b/saas/test/controllers/non_production_remote_access_test.rb new file mode 100644 index 000000000..40a9520d8 --- /dev/null +++ b/saas/test/controllers/non_production_remote_access_test.rb @@ -0,0 +1,56 @@ +require "test_helper" + +class NonProductionRemoteAccessTest < ActionDispatch::IntegrationTest + test "employee can access in staging environment" do + assert_predicate identities(:david), :employee? + + sign_in_as :david + + Rails.stubs(:env).returns(ActiveSupport::EnvironmentInquirer.new("staging")) + get cards_path + assert_response :success + end + + test "non-employee cannot access in staging environment" do + identities(:jz).update!(email_address: "david@example.com") + assert_not_predicate identities(:jz), :employee? + + sign_in_as :jz + + Rails.stubs(:env).returns(ActiveSupport::EnvironmentInquirer.new("staging")) + get cards_path + assert_response :forbidden + end + + test "non-employee can access in production environment" do + identities(:jz).update!(email_address: "david@example.com") + assert_not_predicate identities(:jz), :employee? + + sign_in_as :jz + + Rails.stubs(:env).returns(ActiveSupport::EnvironmentInquirer.new("production")) + get cards_path + assert_response :success + end + + test "non-employee can access in beta environment" do + identities(:jz).update!(email_address: "david@example.com") + assert_not_predicate identities(:jz), :employee? + + sign_in_as :jz + + Rails.stubs(:env).returns(ActiveSupport::EnvironmentInquirer.new("beta")) + get cards_path + assert_response :success + end + + test "non-employee can access in local environment" do + identities(:jz).update!(email_address: "david@example.com") + assert_not_predicate identities(:jz), :employee? + + sign_in_as :jz + + get cards_path + assert_response :success + end +end diff --git a/saas/test/models/identity_test.rb b/saas/test/models/identity_test.rb new file mode 100644 index 000000000..81e3b82c1 --- /dev/null +++ b/saas/test/models/identity_test.rb @@ -0,0 +1,18 @@ +require "test_helper" + +class Fizzy::Saas::IdentityTest < ActiveSupport::TestCase + test "#employee? returns true for 37signals.com domains" do + identity = Identity.new(email_address: "mike@37signals.com") + assert_predicate identity, :employee? + end + + test "#employee? returns true for basecamp.com domains" do + identity = Identity.new(email_address: "mike@basecamp.com") + assert_predicate identity, :employee? + end + + test "#employee? returns false for other domains" do + identity = Identity.new(email_address: "mike@example.com") + assert_not_predicate identity, :employee? + end +end