radiant-enabler-extension 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ pkg/*
@@ -0,0 +1,15 @@
1
+ = Enabler
2
+
3
+ Enabler can enable and disable a site remotely. Here's how it works:
4
+
5
+ 1. You setup an API key for your site in `Radiant::Config['application.api_key']` such as `1eukshp8c4rchbkoep9d4ntbekp4208`
6
+ 2. Then you post to `yoursite.com/admin/disable/1eukshp8c4rchbkoep9d4ntbekp4208?message=Site%20is%20down.`
7
+ 3. The site will return all requests with a message such as `Site is down.`
8
+
9
+ To re-enable a site (the default state) you can post to `yoursite.com/admin/enable/1eukshp8c4rchbkoep9d4ntbekp4208`
10
+
11
+ Each time you post to enable or disable the cache is cleared. The messages displayed to a visitor when a site is disabled are cached for 24 hours, so your application won't be bogged down by requests.
12
+
13
+ So that your sites don't reveal whether or not this extension is installed, if you post an invalid api key it will respond with the usual Radiant response for any url. Responding to an invalid key with a 403 (as you might expect from this) would allow someone to scan your site for this url and a 403 response. To avoid that, it'll just render your FileNotFound page.
14
+
15
+ Built by [Saturn Flyer](http://www.saturnflyer.com)
@@ -0,0 +1,136 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gem|
4
+ gem.name = "radiant-enabler-extension"
5
+ gem.summary = %Q{Enabler Extension for Radiant CMS}
6
+ gem.description = %Q{Post to a Radiant CMS site to enable or disable it.}
7
+ gem.email = "jim@saturnflyer.com"
8
+ gem.homepage = "http://github.com/saturnflyer/radiant-enabler-extension"
9
+ gem.authors = ["Jim Gay"]
10
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
11
+ end
12
+ rescue LoadError
13
+ puts "Jeweler (or a dependency) not available."
14
+ end
15
+
16
+ # In rails 1.2, plugins aren't available in the path until they're loaded.
17
+ # Check to see if the rspec plugin is installed first and require
18
+ # it if it is. If not, use the gem version.
19
+
20
+ # Determine where the RSpec plugin is by loading the boot
21
+ unless defined? RADIANT_ROOT
22
+ ENV["RAILS_ENV"] = "test"
23
+ case
24
+ when ENV["RADIANT_ENV_FILE"]
25
+ require File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
26
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
27
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
28
+ else
29
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
30
+ end
31
+ end
32
+
33
+ require 'rake'
34
+ require 'rake/rdoctask'
35
+ require 'rake/testtask'
36
+
37
+ rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
38
+ $LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
39
+ require 'spec/rake/spectask'
40
+ require 'cucumber'
41
+ require 'cucumber/rake/task'
42
+
43
+ # Cleanup the RADIANT_ROOT constant so specs will load the environment
44
+ Object.send(:remove_const, :RADIANT_ROOT)
45
+
46
+ extension_root = File.expand_path(File.dirname(__FILE__))
47
+
48
+ task :default => :spec
49
+ task :stats => "spec:statsetup"
50
+
51
+ desc "Run all specs in spec directory"
52
+ Spec::Rake::SpecTask.new(:spec) do |t|
53
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
54
+ t.spec_files = FileList['spec/**/*_spec.rb']
55
+ end
56
+
57
+ task :features => 'spec:integration'
58
+
59
+ namespace :spec do
60
+ desc "Run all specs in spec directory with RCov"
61
+ Spec::Rake::SpecTask.new(:rcov) do |t|
62
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
63
+ t.spec_files = FileList['spec/**/*_spec.rb']
64
+ t.rcov = true
65
+ t.rcov_opts = ['--exclude', 'spec', '--rails']
66
+ end
67
+
68
+ desc "Print Specdoc for all specs"
69
+ Spec::Rake::SpecTask.new(:doc) do |t|
70
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
71
+ t.spec_files = FileList['spec/**/*_spec.rb']
72
+ end
73
+
74
+ [:models, :controllers, :views, :helpers].each do |sub|
75
+ desc "Run the specs under spec/#{sub}"
76
+ Spec::Rake::SpecTask.new(sub) do |t|
77
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
78
+ t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
79
+ end
80
+ end
81
+
82
+ desc "Run the Cucumber features"
83
+ Cucumber::Rake::Task.new(:integration) do |t|
84
+ t.fork = true
85
+ t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'pretty')]
86
+ # t.feature_pattern = "#{extension_root}/features/**/*.feature"
87
+ t.profile = "default"
88
+ end
89
+
90
+ # Setup specs for stats
91
+ task :statsetup do
92
+ require 'code_statistics'
93
+ ::STATS_DIRECTORIES << %w(Model\ specs spec/models)
94
+ ::STATS_DIRECTORIES << %w(View\ specs spec/views)
95
+ ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
96
+ ::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
97
+ ::CodeStatistics::TEST_TYPES << "Model specs"
98
+ ::CodeStatistics::TEST_TYPES << "View specs"
99
+ ::CodeStatistics::TEST_TYPES << "Controller specs"
100
+ ::CodeStatistics::TEST_TYPES << "Helper specs"
101
+ ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
102
+ end
103
+
104
+ namespace :db do
105
+ namespace :fixtures do
106
+ desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
107
+ task :load => :environment do
108
+ require 'active_record/fixtures'
109
+ ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
110
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
111
+ Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ desc 'Generate documentation for the enabler extension.'
119
+ Rake::RDocTask.new(:rdoc) do |rdoc|
120
+ rdoc.rdoc_dir = 'rdoc'
121
+ rdoc.title = 'EnablerExtension'
122
+ rdoc.options << '--line-numbers' << '--inline-source'
123
+ rdoc.rdoc_files.include('README')
124
+ rdoc.rdoc_files.include('lib/**/*.rb')
125
+ end
126
+
127
+ # For extensions that are in transition
128
+ desc 'Test the enabler extension.'
129
+ Rake::TestTask.new(:test) do |t|
130
+ t.libs << 'lib'
131
+ t.pattern = 'test/**/*_test.rb'
132
+ t.verbose = true
133
+ end
134
+
135
+ # Load any custom rakefiles for extension
136
+ Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,32 @@
1
+ require 'cgi'
2
+ class Admin::EnablerController < ApplicationController
3
+ no_login_required
4
+ skip_before_filter :validate_authenticity
5
+
6
+ def enable
7
+ if Radiant::Config['application.api_key'] == params[:api_key] && request.post?
8
+ Radiant::Config['application.enabled?'] = true
9
+ Radiant::Cache.clear
10
+ respond_to do |format|
11
+ format.any { head :ok }
12
+ end
13
+ else
14
+ Page.find_by_url(request.request_uri).process(request, response)
15
+ end
16
+ end
17
+
18
+ def disable
19
+ if Radiant::Config['application.api_key'] == params[:api_key] && request.post?
20
+ Radiant::Config['application.enabled?'] = false
21
+ if params[:message]
22
+ Radiant::Config['application.disabled_message'] = CGI.unescape(params[:message])
23
+ end
24
+ Radiant::Cache.clear
25
+ respond_to do |format|
26
+ format.any { head :ok }
27
+ end
28
+ else
29
+ Page.find_by_url(request.request_uri).process(request, response)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,6 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ map.namespace :admin do |admin|
3
+ admin.enable_application 'enable/:api_key', :controller => 'enabler', :action => 'enable'
4
+ admin.disable_application 'disable/:api_key', :controller => 'enabler', :action => 'disable'
5
+ end
6
+ end
@@ -0,0 +1 @@
1
+ default: --format progress features --tags ~@proposed,~@in_progress
@@ -0,0 +1,26 @@
1
+ # Uncomment this if you reference any of your controllers in activate
2
+ # require_dependency 'application_controller'
3
+
4
+ class EnablerExtension < Radiant::Extension
5
+ version "#{File.read(File.expand_path(File.dirname(__FILE__)) + '/VERSION')}"
6
+ description "Keeps your site going"
7
+ url "http://www.saturnflyer.com"
8
+
9
+ def activate
10
+ Radiant::Config['application.enabled?'] = true if Radiant::Config['application.enabled?'].nil?
11
+ if Radiant::Config['application.disabled_message'].nil?
12
+ Radiant::Config['application.disabled_message'] = "Sorry, but this site has been disabled."
13
+ end
14
+ SiteController.class_eval {
15
+ before_filter :filter_by_application_status
16
+
17
+ def filter_by_application_status
18
+ unless Radiant::Config['application.enabled?']
19
+ expires_in 24.hours, :public => true, :private => false
20
+ headers['ETag'] = ''
21
+ render :text => Radiant::Config['application.disabled_message'] and return
22
+ end
23
+ end
24
+ }
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ # Sets up the Rails environment for Cucumber
2
+ ENV["RAILS_ENV"] = "test"
3
+ # Extension root
4
+ extension_env = File.expand_path(File.dirname(__FILE__) + '/../../../../../config/environment')
5
+ require extension_env+'.rb'
6
+
7
+ Dir.glob(File.join(RADIANT_ROOT, "features", "**", "*.rb")).each {|step| require step}
8
+
9
+ Cucumber::Rails::World.class_eval do
10
+ include Dataset
11
+ datasets_directory "#{RADIANT_ROOT}/spec/datasets"
12
+ Dataset::Resolver.default = Dataset::DirectoryResolver.new("#{RADIANT_ROOT}/spec/datasets", File.dirname(__FILE__) + '/../../spec/datasets', File.dirname(__FILE__) + '/../datasets')
13
+ self.datasets_database_dump_path = "#{Rails.root}/tmp/dataset"
14
+
15
+ # dataset :enabler
16
+ end
@@ -0,0 +1,14 @@
1
+ def path_to(page_name)
2
+ case page_name
3
+
4
+ when /the homepage/i
5
+ root_path
6
+
7
+ when /login/i
8
+ login_path
9
+ # Add more page name => path mappings here
10
+
11
+ else
12
+ raise "Can't find mapping from \"#{page_name}\" to a path."
13
+ end
14
+ end
File without changes
@@ -0,0 +1,36 @@
1
+ namespace :radiant do
2
+ namespace :extensions do
3
+ namespace :enabler do
4
+
5
+ desc "Runs the migration of the Enabler extension"
6
+ task :migrate => :environment do
7
+ require 'radiant/extension_migrator'
8
+ if ENV["VERSION"]
9
+ EnablerExtension.migrator.migrate(ENV["VERSION"].to_i)
10
+ else
11
+ EnablerExtension.migrator.migrate
12
+ end
13
+ end
14
+
15
+ desc "Copies public assets of the Enabler to the instance public/ directory."
16
+ task :update => :environment do
17
+ is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
18
+ puts "Copying assets from EnablerExtension"
19
+ Dir[EnablerExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
20
+ path = file.sub(EnablerExtension.root, '')
21
+ directory = File.dirname(path)
22
+ mkdir_p RAILS_ROOT + directory, :verbose => false
23
+ cp file, RAILS_ROOT + path, :verbose => false
24
+ end
25
+ unless EnablerExtension.root.starts_with? RAILS_ROOT # don't need to copy vendored tasks
26
+ puts "Copying rake tasks from EnablerExtension"
27
+ local_tasks_path = File.join(RAILS_ROOT, %w(lib tasks))
28
+ mkdir_p local_tasks_path, :verbose => false
29
+ Dir[File.join EnablerExtension.root, %w(lib tasks *.rake)].each do |file|
30
+ cp file, local_tasks_path, :verbose => false
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,58 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{radiant-enabler-extension}
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jim Gay"]
12
+ s.date = %q{2010-04-26}
13
+ s.description = %q{Post to a Radiant CMS site to enable or disable it.}
14
+ s.email = %q{jim@saturnflyer.com}
15
+ s.extra_rdoc_files = [
16
+ "README.md"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "README.md",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "app/controllers/admin/enabler_controller.rb",
24
+ "config/routes.rb",
25
+ "cucumber.yml",
26
+ "enabler_extension.rb",
27
+ "features/support/env.rb",
28
+ "features/support/paths.rb",
29
+ "lib/radiant-enabler-extension.rb",
30
+ "lib/tasks/enabler_extension_tasks.rake",
31
+ "radiant-enabler-extension.gemspec",
32
+ "spec/controllers/admin/enabler_controller_spec.rb",
33
+ "spec/controllers/site_controller_spec.rb",
34
+ "spec/spec.opts",
35
+ "spec/spec_helper.rb"
36
+ ]
37
+ s.homepage = %q{http://github.com/saturnflyer/radiant-enabler-extension}
38
+ s.rdoc_options = ["--charset=UTF-8"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = %q{1.3.6}
41
+ s.summary = %q{Enabler Extension for Radiant CMS}
42
+ s.test_files = [
43
+ "spec/controllers/admin/enabler_controller_spec.rb",
44
+ "spec/controllers/site_controller_spec.rb",
45
+ "spec/spec_helper.rb"
46
+ ]
47
+
48
+ if s.respond_to? :specification_version then
49
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
50
+ s.specification_version = 3
51
+
52
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
53
+ else
54
+ end
55
+ else
56
+ end
57
+ end
58
+
@@ -0,0 +1,62 @@
1
+ require 'cgi'
2
+ require File.dirname(__FILE__) + '/../../spec_helper'
3
+
4
+ describe Admin::EnablerController do
5
+ dataset :pages, :file_not_found
6
+ before do
7
+ Radiant::Config['application.api_key'] = '12345'
8
+ Radiant::Config['application.enabled?'] = true
9
+ end
10
+ context "with a valid api key" do
11
+ context "for the disable action" do
12
+ it "should set the Radiant::Config['application.enabled?'] to false" do
13
+ Radiant::Config['application.enabled?'] = 'true'
14
+ post :disable, :api_key => '12345'
15
+ Radiant::Config['application.enabled?'].should == false
16
+ end
17
+ it "should set the disabled message with the message parameter" do
18
+ post :disable, :api_key => '12345', :message => 'Site%20is%20down.'
19
+ Radiant::Config['application.disabled_message'].should == 'Site is down.'
20
+ end
21
+ it "should respond to with a 200 code" do
22
+ post :disable, :api_key => '12345'
23
+ response.code.should == '200'
24
+ end
25
+ context "with a disabled message" do
26
+ it "should unescape the message string" do
27
+ post :disable, :api_key => '12345', :message => "This+is+the+message+about+the+site+%26+it%27s+downtime%21"
28
+ Radiant::Config['application.disabled_message'].should == "This is the message about the site & it's downtime!"
29
+ end
30
+ end
31
+ end
32
+ context "for the enable action" do
33
+ it "should set the Radiant::Config['application.enabled?'] to true" do
34
+ Radiant::Config['application.enabled?'] = false
35
+ Radiant::Config['application.enabled?'].should == false
36
+ post :enable, :api_key => '12345'
37
+ Radiant::Config['application.enabled?'].should == true
38
+ end
39
+ it "should respond to with a 200 code" do
40
+ post :enable, :api_key => '12345'
41
+ response.code.should == '200'
42
+ end
43
+ end
44
+ end
45
+ context "with an invalid api key" do
46
+ before do
47
+ pages(:file_not_found).part('body').update_attribute(:content, 'Oops! We could not find that page.')
48
+ end
49
+ it "should render the response from the page found for the given url" do
50
+ post :enable, :api_key => 'abcde'
51
+ pages(:file_not_found).process(request, response) # only passes after this ...?
52
+ response.body.should == 'Oops! We could not find that page.'
53
+ end
54
+ context "with a disable message" do
55
+ it "should render the response from the page found for the given url" do
56
+ post :disable, :api_key => 'abcde', :message => 'Site%20is%20down'
57
+ pages(:file_not_found).process(request, response) # only passes after this ...?
58
+ response.body.should == 'Oops! We could not find that page.'
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,12 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe SiteController do
4
+ context "when the site is disabled" do
5
+ it "should return text with the disabled message" do
6
+ Radiant::Config['application.enabled?'] = false
7
+ Radiant::Config['application.disabled_message'] = 'Site is down.'
8
+ get :show_page, :url => '/any'
9
+ response.body.should match('Site is down')
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,6 @@
1
+ --colour
2
+ --format
3
+ progress
4
+ --loadby
5
+ mtime
6
+ --reverse
@@ -0,0 +1,36 @@
1
+ unless defined? RADIANT_ROOT
2
+ ENV["RAILS_ENV"] = "test"
3
+ case
4
+ when ENV["RADIANT_ENV_FILE"]
5
+ require ENV["RADIANT_ENV_FILE"]
6
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
7
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../../")}/config/environment"
8
+ else
9
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../")}/config/environment"
10
+ end
11
+ end
12
+ require "#{RADIANT_ROOT}/spec/spec_helper"
13
+
14
+ Dataset::Resolver.default << (File.dirname(__FILE__) + "/datasets")
15
+
16
+ if File.directory?(File.dirname(__FILE__) + "/matchers")
17
+ Dir[File.dirname(__FILE__) + "/matchers/*.rb"].each {|file| require file }
18
+ end
19
+
20
+ Spec::Runner.configure do |config|
21
+ # config.use_transactional_fixtures = true
22
+ # config.use_instantiated_fixtures = false
23
+ # config.fixture_path = RAILS_ROOT + '/spec/fixtures'
24
+
25
+ # You can declare fixtures for each behaviour like this:
26
+ # describe "...." do
27
+ # fixtures :table_a, :table_b
28
+ #
29
+ # Alternatively, if you prefer to declare them only once, you can
30
+ # do so here, like so ...
31
+ #
32
+ # config.global_fixtures = :table_a, :table_b
33
+ #
34
+ # If you declare global fixtures, be aware that they will be declared
35
+ # for all of your examples, even those that don't use them.
36
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: radiant-enabler-extension
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Jim Gay
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-26 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Post to a Radiant CMS site to enable or disable it.
22
+ email: jim@saturnflyer.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - README.md
29
+ files:
30
+ - .gitignore
31
+ - README.md
32
+ - Rakefile
33
+ - VERSION
34
+ - app/controllers/admin/enabler_controller.rb
35
+ - config/routes.rb
36
+ - cucumber.yml
37
+ - enabler_extension.rb
38
+ - features/support/env.rb
39
+ - features/support/paths.rb
40
+ - lib/radiant-enabler-extension.rb
41
+ - lib/tasks/enabler_extension_tasks.rake
42
+ - radiant-enabler-extension.gemspec
43
+ - spec/controllers/admin/enabler_controller_spec.rb
44
+ - spec/controllers/site_controller_spec.rb
45
+ - spec/spec.opts
46
+ - spec/spec_helper.rb
47
+ has_rdoc: true
48
+ homepage: http://github.com/saturnflyer/radiant-enabler-extension
49
+ licenses: []
50
+
51
+ post_install_message:
52
+ rdoc_options:
53
+ - --charset=UTF-8
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 1.3.6
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Enabler Extension for Radiant CMS
77
+ test_files:
78
+ - spec/controllers/admin/enabler_controller_spec.rb
79
+ - spec/controllers/site_controller_spec.rb
80
+ - spec/spec_helper.rb