Merge pull request #17 from ninech/johanv-9-public_areas_2nd_attempt

Add some changes to #13
This commit is contained in:
Raffael Schmid 2014-09-23 14:07:52 +02:00
commit 264bb292f0
7 changed files with 95 additions and 46 deletions

View File

@ -19,8 +19,12 @@ We use [CASino](http://casino.rbcas.com) as CAS server, but it might work with o
### 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).
If your installation has no public areas ("Authentication required") and you are not logged in, you will be
redirected to the CAS-login page. The default login page will still work when you access it directly
(http://example.com/path-to-redmine/login).
If your installation is not "Authentication required", the login page will show a link that lets you login
with CAS.
### Single Sign Out, Single Logout

View File

@ -0,0 +1,5 @@
<% if Setting.plugin_redmine_cas[:enabled] %>
<p style="text-align:center;">
<strong><%= link_to("Login with CAS", :controller => "account", :action => "cas") %></strong>
</p>
<% end %>

3
config/routes.rb Normal file
View File

@ -0,0 +1,3 @@
RedmineApp::Application.routes.draw do
get 'cas', :to => 'account#cas'
end

View File

@ -3,6 +3,8 @@ require 'redmine_cas'
require 'redmine_cas/application_controller_patch'
require 'redmine_cas/account_controller_patch'
require_dependency 'redmine_cas_hook_listener'
Redmine::Plugin.register :redmine_cas do
name 'Redmine CAS'
author 'Nils Caspar (Nine Internet Solutions AG)'

View File

@ -15,6 +15,75 @@ module RedmineCAS
logout_user
CASClient::Frameworks::Rails::Filter.logout(self, home_url)
end
def cas
return redirect_to_action('login') unless RedmineCAS.enabled?
if User.current.logged?
# User already logged in.
redirect_to_ref_or_default
return
end
if CASClient::Frameworks::Rails::Filter.filter(self)
user = User.find_by_login(session[:cas_user])
# Auto-create user if possible
if user.nil? && RedmineCAS.autocreate_users?
user = User.new
user.login = session[:cas_user]
user.assign_attributes(RedmineCAS.user_extra_attributes_from_session(session))
return cas_user_not_created(user) if !user.save
user.reload
end
return cas_user_not_found if user.nil?
return cas_account_pending unless user.active?
user.update_attribute(:last_login_on, Time.now)
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_ref_or_default
end
end
def redirect_to_ref_or_default
default_url = url_for(params.merge(:ticket => nil))
if params.has_key?(:ref)
# do some basic validation on ref, to prevent a malicious link to redirect
# to another site.
new_url = params[:ref]
if /http(s)?:\/\/|@/ =~ new_url
# evil referrer!
redirect_to default_url
else
redirect_to request.base_url + params[:ref]
end
else
redirect_to default_url
end
end
def cas_account_pending
render_403 :message => l(:notice_account_pending)
end
def cas_user_not_found
render_403 :message => l(:redmine_cas_user_not_found, :user => session[:cas_user])
end
def cas_user_not_created(user)
logger.error "Could not auto-create user: #{user.errors.full_messages.to_sentence}"
render_403 :message => l(:redmine_cas_user_not_created, :user => session[:cas_user])
end
end
end
end

View File

@ -14,9 +14,12 @@ module RedmineCAS
def require_login_with_cas
return require_login_without_cas unless RedmineCAS.enabled?
if !User.current.logged?
referrer = request.fullpath;
respond_to do |format|
format.html { login_with_cas }
format.atom { login_with_cas }
# pass referer to cas action, to work around this problem:
# https://github.com/ninech/redmine_cas/pull/13#issuecomment-53697288
format.html { redirect_to :controller => 'account', :action => 'cas', :ref => referrer }
format.atom { redirect_to :controller => 'account', :action => 'cas', :ref => referrer }
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"' }
@ -26,36 +29,6 @@ module RedmineCAS
true
end
def login_with_cas
if CASClient::Frameworks::Rails::Filter.filter(self)
user = User.find_by_login(session[:cas_user])
# Auto-create user if possible
if user.nil? && RedmineCAS.autocreate_users?
user = User.new
user.login = session[:cas_user]
user.assign_attributes(RedmineCAS.user_extra_attributes_from_session(session))
return cas_user_not_created(user) if !user.save
user.reload
end
return cas_user_not_found if user.nil?
return cas_account_pending unless user.active?
user.update_attribute(:last_login_on, Time.now)
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 verify_authenticity_token_with_cas
if cas_logout_request?
logger.info 'CAS logout request detected: Skipping validation of authenticity token'
@ -68,18 +41,6 @@ module RedmineCAS
request.post? && params.has_key?('logoutRequest')
end
def cas_account_pending
render_403 :message => l(:notice_account_pending)
end
def cas_user_not_found
render_403 :message => l(:redmine_cas_user_not_found, :user => session[:cas_user])
end
def cas_user_not_created(user)
logger.error "Could not auto-create user: #{user.errors.full_messages.to_sentence}"
render_403 :message => l(:redmine_cas_user_not_created, :user => session[:cas_user])
end
end
end
end

View File

@ -0,0 +1,5 @@
module RedmineCAS
class RedmineCASHookListener < Redmine::Hook::ViewListener
render_on :view_account_login_top, :partial => 'redmine_cas/cas_login_link'
end
end