Permalink
Browse files

Monkeypatch Redmine to login/logout through CAS

  • Loading branch information...
nackd committed Oct 20, 2010
1 parent 3ea568a commit c9320c0b7d0f0ebf356331a974decf4cb82791e7
Showing with 134 additions and 4 deletions.
  1. +1 −0 .gitignore
  2. +10 −0 config/cas.yml.example
  3. +14 −0 config/initializers/cas.rb
  4. +16 −4 init.rb
  5. +46 −0 lib/cas_account_controller_patch.rb
  6. +47 −0 lib/cas_application_controller_patch.rb
View
@@ -0,0 +1 @@
+/config/cas.yml
View
@@ -0,0 +1,10 @@
+development:
+ enabled: true
+ url: http://tomcat-apps.emergya.info/cas/
+
+test:
+ enabled: false
+
+production:
+ enabled: true
+ url: http://tomcat-apps.emergya.info/cas/
View
@@ -0,0 +1,14 @@
+# Load CAS authentication configuration
+
+CAS_CONFIG = YAML.load_file("#{File.dirname(__FILE__)}/../cas.yml")[RAILS_ENV]
+
+if CAS_CONFIG['enabled']
+ # Basic CAS client configuration
+ require 'casclient'
+ require 'casclient/frameworks/rails/filter'
+
+ CASClient::Frameworks::Rails::Filter.configure(
+ :cas_base_url => CAS_CONFIG['url'],
+ :enable_single_sign_out => true
+ )
+end
View
20 init.rb
@@ -1,6 +1,18 @@
-# This file makes it possible to install RubyCAS-Client as a Rails plugin.
+# Run initializers
+# Needs to be atop requires because some of them need to be run after initialization
+Dir["#{File.dirname(__FILE__)}/config/initializers/**/*.rb"].sort.each do |initializer|
+ require initializer
+end
-$: << File.expand_path(File.dirname(__FILE__))+'/lib'
+require 'redmine'
+require 'cas_account_controller_patch'
+require 'cas_application_controller_patch'
-require 'casclient'
-require 'casclient/frameworks/rails/filter'
+Redmine::Plugin.register :redmine_cas do
+ name 'CAS Web Authentication'
+ author 'José M. Prieto (Emergya)'
+ description 'CAS single sign-on authentication via CAS web interface'
+ version '0.1'
+ #TODO url 'http://example.com/path/to/plugin'
+ author_url 'http://www.emergya.es'
+end
@@ -0,0 +1,46 @@
+require 'casclient'
+require 'casclient/frameworks/rails/filter'
+require 'account_controller'
+require 'dispatcher'
+
+# Patches Redmine's AccountController dinamically. Manages login and logout
+# through CAS.
+module CasAccountControllerPatch
+ def self.included(base) # :nodoc:
+ base.send(:include, InstanceMethods)
+
+ base.class_eval do
+ unloadable # Mark as unloadable so it is reloaded in development
+
+ alias_method_chain :login, :cas
+ alias_method_chain :logout, :cas
+ end
+ end
+
+ module InstanceMethods
+ def login_with_cas
+ if CAS_CONFIG['enabled']
+ if params[:ticket]
+ redirect_back_or_default :controller => 'my', :action => 'page'
+ else
+ CASClient::Frameworks::Rails::Filter::redirect_to_cas_for_authentication(self)
+ end
+ else
+ login_without_cas
+ end
+ end
+
+ def logout_with_cas
+ if CAS_CONFIG['enabled']
+ self.logged_user = nil
+ CASClient::Frameworks::Rails::Filter::logout(self, home_url)
+ else
+ logout_without_cas
+ end
+ end
+ end
+end
+
+Dispatcher.to_prepare do
+ AccountController.send(:include, CasAccountControllerPatch)
+end
@@ -0,0 +1,47 @@
+require 'casclient'
+require 'casclient/frameworks/rails/filter'
+require 'application_controller'
+require 'dispatcher'
+
+# Patches Redmine's ApplicationController dinamically. Prepends a CAS gatewaying
+# filter.
+module CasApplicationControllerPatch
+ def self.included(base) # :nodoc:
+ base.send(:include, InstanceMethods)
+
+ base.class_eval do
+ unloadable # Mark as unloadable so it is reloaded in development
+
+ prepend_before_filter :cas_filter, :set_user_id
+ end
+ end
+
+ module InstanceMethods
+ def cas_filter
+ if CAS_CONFIG['enabled'] and !['atom', 'xml', 'json'].include?request.format
+ if params[:controller] != 'account'
+ CASClient::Frameworks::Rails::GatewayFilter.filter(self)
+ else
+ CASClient::Frameworks::Rails::Filter.filter(self)
+ end
+ else
+ true
+ end
+ end
+
+ def set_user_id
+ if CAS_CONFIG['enabled']
+ user = User.find_by_login session[:cas_user]
+ if user and session[:user_id] != user.id
+ session[:user_id] = user.id
+ call_hook(:controller_account_success_authentication_after, {:user => user })
+ end
+ end
+ true
+ end
+ end
+end
+
+Dispatcher.to_prepare do
+ ApplicationController.send(:include, CasApplicationControllerPatch)
+end

0 comments on commit c9320c0

Please sign in to comment.