diff --git a/README.markdown b/README.markdown index 6dce964..0a4adc9 100644 --- a/README.markdown +++ b/README.markdown @@ -525,6 +525,13 @@ DatabaseCleaner.allow_production = true DatabaseCleaner.allow_remote_database_url = true ``` +In Ruby, a URL whitelist can be specified. When specified, DatabaseCleaner will only allow `DATABASE_URL` to be equal +to one of the values specified in the url whitelist like so: + +```ruby +DatabaseCleaner.url_whitelist = ['postgres://postgres@localhost', 'postgres://foo@bar'] +``` + ## Debugging In rare cases DatabaseCleaner will encounter errors that it will log. By default it uses STDOUT set to the ERROR level but you can configure this to use whatever Logger you desire. diff --git a/lib/database_cleaner.rb b/lib/database_cleaner.rb index 1174bda..07843e9 100644 --- a/lib/database_cleaner.rb +++ b/lib/database_cleaner.rb @@ -3,7 +3,7 @@ require 'database_cleaner/configuration' module DatabaseCleaner class << self - attr_accessor :allow_remote_database_url, :allow_production + attr_accessor :allow_remote_database_url, :allow_production, :url_whitelist def can_detect_orm? DatabaseCleaner::Base.autodetect_orm diff --git a/lib/database_cleaner/safeguard.rb b/lib/database_cleaner/safeguard.rb index b885391..51205d9 100644 --- a/lib/database_cleaner/safeguard.rb +++ b/lib/database_cleaner/safeguard.rb @@ -12,8 +12,35 @@ module DatabaseCleaner super("ENV['#{env}'] is set to production. Please refer to https://github.com/DatabaseCleaner/database_cleaner#safeguards") end end + + class NotWhitelistedUrl < Error + def initialize + super("ENV['DATABASE_URL'] is set to a URL that is not on the whitelist. Please refer to https://github.com/DatabaseCleaner/database_cleaner#safeguards") + end + end end + class WhitelistedUrl + def run + raise Error::NotWhitelistedUrl if !skip? && given? + end + + private + + def given? + !whitelisted?(ENV['DATABASE_URL']) + end + + def whitelisted?(url) + DatabaseCleaner.url_whitelist.include?(url) + end + + def skip? + !DatabaseCleaner.url_whitelist + end + end + + class RemoteDatabaseUrl LOCAL = %w(localhost 127.0.0.1) @@ -33,7 +60,8 @@ module DatabaseCleaner def skip? ENV['DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL'] || - DatabaseCleaner.allow_remote_database_url + DatabaseCleaner.allow_remote_database_url || + DatabaseCleaner.url_whitelist end end @@ -62,7 +90,8 @@ module DatabaseCleaner CHECKS = [ RemoteDatabaseUrl, - Production + Production, + WhitelistedUrl ] def run