Skip to content
This repository has been archived by the owner on Aug 20, 2021. It is now read-only.

Commit

Permalink
Initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
pencil committed Mar 29, 2013
0 parents commit 5de2935
Show file tree
Hide file tree
Showing 9 changed files with 870 additions and 0 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gem 'rubycas-client', '~> 2.3.10.rc1'
674 changes: 674 additions & 0 deletions LICENSE.txt

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Redmine CAS plugin

Plugin to CASify your Redmine installation.

## Compatibilty

Tested with Redmine 2.2.3, but should be working fine with Redmine 2.x and possibly 1.x.

## Installation

1. Download or clone this repository and place it in the Redmine plugin directory
2. Restart your webserver
3. Open Redmine and check if the plugin is visible under Administration > Plugins
4. Follow the "Configure" link and set the parameters
5. Party

## Notes

### Usage

This plugin was made for redmine installations without public areas ("Authentication required").
The default login page will still work when you access it directly (http://example.com/path-to-redmine/login).

### Single Sign Out, Single Logout

Session need to be stored in the database to make Single Sign Out work.
You can achieve this with a tiny plugin: [redmine_activerecord_session_store](https://github.com/pencil/redmine_activerecord_session_store)

## Copyright

Copyright (c) 2013 Nine Internet Solutions AG. See LICENSE.txt for further details.
14 changes: 14 additions & 0 deletions app/views/redmine_cas/_settings.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<p>
<%= label_tag "settings[enabled]", l(:redmine_cas_settings_enabled_label) %>
<%= check_box_tag "settings[enabled]", 1, @settings[:enabled] %>
</p>
<p>
<%= label_tag "settings[cas_url]", l(:redmine_cas_settings_cas_url_label) %>
<%= text_field_tag "settings[cas_url]", @settings[:cas_url], :size => 50 %>
<em class="info"><%= l(:redmine_cas_settings_cas_url_helptext).html_safe %></em>
</p>
<p>
<%= label_tag "settings[attributes_mapping]", l(:redmine_cas_settings_attributes_mapping_label) %>
<%= text_field_tag "settings[attributes_mapping]", @settings[:attributes_mapping], :size => 50 %>
<em class="info"><%= l(:redmine_cas_settings_attributes_mapping_helptext, :attribute_names => User.attribute_names.join(', ')).html_safe %></em>
</p>
7 changes: 7 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
en:
redmine_cas_settings_enabled_label: 'Enabled'
redmine_cas_settings_cas_url_label: 'CAS server URL'
redmine_cas_settings_cas_url_helptext: 'Base URL to your CAS server.'
redmine_cas_settings_attributes_mapping_label: 'Attributes mapping'
redmine_cas_settings_attributes_mapping_helptext: 'This is how the plugin maps extended attributes from the CAS server to the redmine model.<br /><code>attribute_name_in_redmine=attribute_name_in_cas_response</code><br />Separate entries with <code>&amp;</code> (query-string).<br />Example: <code>firstname=first_name&amp;lastname=last_name&amp;mail=email</code><br />Valid attribute names: <code>%{attribute_names}</code>'
rbcas_cas_user_not_found: '"%{user}" was authenticated but needs to be created in Redmine first.'
27 changes: 27 additions & 0 deletions init.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require 'redmine'
require 'redmine_cas'
require 'redmine_cas/application_controller_patch'
require 'redmine_cas/account_controller_patch'

Redmine::Plugin.register :redmine_cas do
name 'Redmine CAS'
author 'Nils Caspar (Nine Internet Solutions AG)'
description 'Plugin to CASify your Redmine installation.'
version '1.0.0'
url 'https://github.com/ninech/redmine_cas'
author_url 'http://www.nine.ch/'

settings :default => {
'enabled' => false,
'cas_url' => 'https://',
'attributes_mapping' => 'firstname=first_name&lastname=last_name&mail=email'
}, :partial => 'redmine_cas/settings'

Rails.configuration.to_prepare do
ApplicationController.send(:include, RedmineCAS::ApplicationControllerPatch)
AccountController.send(:include, RedmineCAS::AccountControllerPatch)
end
ActionDispatch::Callbacks.before do
RedmineCAS.setup!
end
end
40 changes: 40 additions & 0 deletions lib/redmine_cas.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'casclient'
require 'casclient/frameworks/rails/filter'

module RedmineCAS
extend self

def setting(name)
Setting.plugin_redmine_cas[name]
end

def enabled?
setting(:enabled)
end

def setup!
return unless enabled?
CASClient::Frameworks::Rails::Filter.configure(
:cas_base_url => setting(:cas_url),
:logger => Rails.logger,
:enable_single_sign_out => single_sign_out_enabled?
)
end

def single_sign_out_enabled?
ActiveRecord::Base.connection.table_exists?(:sessions)
end

def user_extra_attributes_from_session(session)
attrs = {}
map = Rack::Utils.parse_nested_query setting(:attributes_mapping)
extra_attributes = session[:cas_extra_attributes] || {}
map.each_pair do |key_redmine, key_cas|
value = extra_attributes[key_cas]
if User.attribute_method?(key_redmine) && value
attrs[key_redmine] = (value.is_a? Array) ? value.first : value
end
end
attrs
end
end
20 changes: 20 additions & 0 deletions lib/redmine_cas/account_controller_patch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
require 'redmine_cas'

module RedmineCAS
module AccountControllerPatch
def self.included(base)
base.send(:include, InstanceMethods)
base.class_eval do
alias_method_chain :logout, :cas
end
end

module InstanceMethods
def logout_with_cas
return logout_without_cas unless RedmineCAS.enabled?
logout_user
CASClient::Frameworks::Rails::Filter.logout(self, home_url)
end
end
end
end
56 changes: 56 additions & 0 deletions lib/redmine_cas/application_controller_patch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
require 'redmine_cas'

module RedmineCAS
module ApplicationControllerPatch
def self.included(base)
base.send(:include, InstanceMethods)
base.class_eval do
alias_method_chain :require_login, :cas
end
end

module InstanceMethods
def require_login_with_cas
return require_login_without_cas unless RedmineCAS.enabled?
if !User.current.logged?
respond_to do |format|
format.html { login_with_cas }
format.atom { login_with_cas }
format.xml { head :unauthorized, 'WWW-Authenticate' => 'Basic realm="Redmine API"' }
format.js { head :unauthorized, 'WWW-Authenticate' => 'Basic realm="Redmine API"' }
format.json { head :unauthorized, 'WWW-Authenticate' => 'Basic realm="Redmine API"' }
end
return false
end
true
end

def login_with_cas
if CASClient::Frameworks::Rails::Filter.filter(self)
user = User.find_by_login(session[:cas_user])
return cas_user_not_found if user.nil?
return cas_account_pending unless user.active?
user.update_attributes(RedmineCAS.user_extra_attributes_from_session(session))
if RedmineCAS.single_sign_out_enabled?
# logged_user= would start a new session and break single sign-out
User.current = user
start_user_session(user)
else
self.logged_user = user
end
redirect_to url_for(params.merge(ticket: nil))
else
# CASClient called redirect_to
end
end

def cas_account_pending
render_403 :message => l(:notice_account_pending)
end

def cas_user_not_found
render_403 :message => l(:rbcas_cas_user_not_found, :user => session[:cas_user])
end
end
end
end

0 comments on commit 5de2935

Please sign in to comment.