Merge branch 'cas'

This commit is contained in:
Eric Allen 2010-01-14 09:46:20 -08:00
commit 761810cf7f
17 changed files with 269 additions and 16 deletions

View file

@ -28,6 +28,7 @@ class ApplicationController < ActionController::Base
layout proc{ |controller| controller.mobile? ? "mobile" : "standard" } layout proc{ |controller| controller.mobile? ? "mobile" : "standard" }
exempt_from_layout /\.js\.erb$/ exempt_from_layout /\.js\.erb$/
before_filter :set_session_expiration before_filter :set_session_expiration
before_filter :set_time_zone before_filter :set_time_zone
@ -217,6 +218,22 @@ class ApplicationController < ActionController::Base
self.class.openid_enabled? self.class.openid_enabled?
end end
def self.cas_enabled?
Tracks::Config.cas_enabled?
end
def cas_enabled?
self.class.cas_enabled?
end
def self.prefered_auth?
Tracks::Config.prefered_auth?
end
def prefered_auth?
self.class.prefered_auth?
end
private private
def parse_date_per_user_prefs( s ) def parse_date_per_user_prefs( s )
@ -259,6 +276,8 @@ class ApplicationController < ActionController::Base
def set_time_zone def set_time_zone
Time.zone = current_user.prefs.time_zone if logged_in? Time.zone = current_user.prefs.time_zone if logged_in?
locale = params[:locale] || 'en-US'
I18n.locale = locale
end end
def set_zindex_counter def set_zindex_counter

View file

@ -6,12 +6,32 @@ class LoginController < ApplicationController
skip_before_filter :login_required skip_before_filter :login_required
before_filter :login_optional before_filter :login_optional
before_filter :get_current_user before_filter :get_current_user
if ( SITE_CONFIG['authentication_schemes'].include? 'cas')
# This will allow the user to view the index page without authentication
# but will process CAS authentication data if the user already
# has an SSO session open.
if defined? CASClient
# Only require sub-library if gem is installed and loaded
require 'casclient/frameworks/rails/filter'
before_filter CASClient::Frameworks::Rails::GatewayFilter, :only => :login_cas
# This requires the user to be authenticated for viewing all other pages.
before_filter CASClient::Frameworks::Rails::Filter, :only => [:login_cas ]
end
end
def login def login
if cas_enabled?
@username = session[:cas_user]
@login_url = CASClient::Frameworks::Rails::Filter.login_url(self)
end
if openid_enabled? && using_open_id? if openid_enabled? && using_open_id?
login_openid login_openid
elsif cas_enabled? && session[:cas_user]
login_cas
else else
@page_title = "TRACKS::Login" @page_title = "TRACKS::Login"
cookies[:preferred_auth] = prefered_auth? unless cookies[:preferred_auth]
case request.method case request.method
when :post when :post
if @user = User.authenticate(params['user_login'], params['user_password']) if @user = User.authenticate(params['user_login'], params['user_password'])
@ -49,9 +69,13 @@ class LoginController < ApplicationController
@user.forget_me if logged_in? @user.forget_me if logged_in?
cookies.delete :auth_token cookies.delete :auth_token
session['user_id'] = nil session['user_id'] = nil
reset_session if ( SITE_CONFIG['authentication_schemes'].include? 'cas') && session[:cas_user]
notify :notice, "You have been logged out of Tracks." CASClient::Frameworks::Rails::Filter.logout(self)
redirect_to_login else
reset_session
notify :notice, "You have been logged out of Tracks."
redirect_to_login
end
end end
def check_expiry def check_expiry
@ -73,6 +97,33 @@ class LoginController < ApplicationController
respond_to do |format| respond_to do |format|
format.js format.js
end end
end
def login_cas
# If checkbox on login page checked, we don't expire the session after 1 hour
# of inactivity and we remember this user for future browser sessions
session['noexpiry'] ||= params['user_noexpiry']
if session[:cas_user]
if @user = User.find_by_login(session[:cas_user])
session['user_id'] = @user.id
msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire."
notify :notice, "Login successful: session #{msg}"
cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year, :secure => SITE_CONFIG['secure_cookies'] }
unless should_expire_sessions?
@user.remember_me
cookies[:auth_token] = { :value => @user.remember_token, :expires => @user.remember_token_expires_at, :secure => SITE_CONFIG['secure_cookies'] }
end
#redirect_back_or_home
else
notify :warning, "Sorry, no user by that CAS username exists (#{session[:cas_user]})"
redirect_to signup_url ; return
end
else
notify :warning, result.message
end
redirect_back_or_home
end end
private private
@ -114,4 +165,6 @@ class LoginController < ApplicationController
end end
end end
end end
end end

View file

@ -27,6 +27,13 @@ class UsersController < ApplicationController
# GET /users/new # GET /users/new
def new def new
@auth_types = []
unless session[:cas_user]
Tracks::Config.auth_schemes.each {|auth| @auth_types << [auth,auth]}
else
@auth_types << ['cas','cas']
end
if User.no_users_yet? if User.no_users_yet?
@page_title = "TRACKS::Sign up as the admin user" @page_title = "TRACKS::Sign up as the admin user"
@heading = "Welcome to TRACKS. To get started, please create an admin account:" @heading = "Welcome to TRACKS. To get started, please create an admin account:"
@ -66,6 +73,13 @@ class UsersController < ApplicationController
end end
user = User.new(params['user']) user = User.new(params['user'])
if Tracks::Config.auth_schemes.include?('cas')
if user.auth_type.eql? "cas"
user.crypted_password = "cas"
end
end
unless user.valid? unless user.valid?
session['new_user'] = user session['new_user'] = user
redirect_to :action => 'new' redirect_to :action => 'new'
@ -94,6 +108,9 @@ class UsersController < ApplicationController
return return
end end
user = User.new(params[:request]) user = User.new(params[:request])
if Tracks::Config.auth_schemes.include?('cas') && session[:cas_user]
user.auth_type = "cas" #if they area cas user
end
user.password_confirmation = params[:request][:password] user.password_confirmation = params[:request][:password]
if user.save if user.save
render :text => "User created.", :status => 200 render :text => "User created.", :status => 200
@ -203,4 +220,4 @@ class UsersController < ApplicationController
return true return true
end end
end end

View file

@ -153,6 +153,9 @@ class User < ActiveRecord::Base
if Tracks::Config.auth_schemes.include?('ldap') if Tracks::Config.auth_schemes.include?('ldap')
return candidate if candidate.auth_type == 'ldap' && SimpleLdapAuthenticator.valid?(login, pass) return candidate if candidate.auth_type == 'ldap' && SimpleLdapAuthenticator.valid?(login, pass)
end end
if Tracks::Config.auth_schemes.include?('cas') && candidate.auth_type.eql?("cas")
return candidate #because we can not auth them with out thier real password we have to settle for this
end
return nil return nil
end end

View file

@ -54,7 +54,7 @@
<div id="minilinks"> <div id="minilinks">
<%= link_to("Toggle notes", "#", {:accesskey => "S", :title => "Toggle all notes", :id => "toggle-notes-nav"}) %> <%= link_to("Toggle notes", "#", {:accesskey => "S", :title => "Toggle all notes", :id => "toggle-notes-nav"}) %>
&nbsp;|&nbsp; &nbsp;|&nbsp;
<%= link_to "Logout (#{current_user.display_name}) »", logout_path %> <%= link_to "Logout (#{current_user.display_name}) »", logout_path %> <p>
</div> </div>
<div id="navcontainer"> <div id="navcontainer">
<ul class="sf-menu"> <ul class="sf-menu">

View file

@ -1,6 +1,7 @@
<% auth_schemes = Tracks::Config.auth_schemes <% auth_schemes = Tracks::Config.auth_schemes
show_database_form = auth_schemes.include?('database') show_database_form = auth_schemes.include?('database')
show_openid_form = auth_schemes.include?('open_id') show_openid_form = auth_schemes.include?('open_id')
show_cas_form = auth_schemes.include?('cas')
-%> -%>
<div title="Account login" id="loginform" class="form"> <div title="Account login" id="loginform" class="form">
@ -8,9 +9,8 @@
<%= render_flash %> <%= render_flash %>
<h3>Please log in to use Tracks:</h3> <h3>Please log in to use Tracks:</h3>
<% if show_database_form %> <% if show_database_form %>
<div id="database_auth_form" style="display:block"> <div id="database_auth_form" style="display:<%=(@prefered_auth.eql?('database')) ? "block" : "none"%>">
<% form_tag :action=> 'login' do %> <% form_tag :action=> 'login' do %>
<table> <table>
<tr> <tr>
@ -35,7 +35,7 @@
<% end %> <% end %>
<% if show_openid_form %> <% if show_openid_form %>
<div id="openid_auth_form" style="display:none"> <div id="openid_auth_form" style="display:<%=(@prefered_auth.eql?('openid')) ? "block" : "none"%>">
<% form_tag :action=> 'login' do %> <% form_tag :action=> 'login' do %>
<table> <table>
<tr> <tr>
@ -54,24 +54,48 @@
<% end %> <% end %>
</div> </div>
<% end %> <% end %>
<% if show_cas_form %>
<div id="cas_auth_form" style="display:<%=(@prefered_auth.eql?('cas')) ? "block" : "none"%>">
<table>
<tr>
<td>
<% if @username && @user%>
<p>Hello, <%= @username %>! You are authenticated.</p>
<% elsif @username %>
<p>Hello, <%= @username %>! You do not have an account on Tracks.
<%if SITE_CONFIG['open_signups']%>
If you like to request on please go here to <%= link_to "Request Account" , signup_url %>
<%end%>
</p>
<% else %>
<p><%= link_to("CAS Login", login_cas_url) %> </p>
<% end %>
</td>
</tr>
</table>
</div>
<% end %>
</div> </div>
<% if show_openid_form %><p id="alternate_auth_openid" class="alternate_auth">or, <a href="#" onclick="Login.showOpenid();return false;">login with an OpenId</a></p><% end %> <% if show_openid_form %><p id="alternate_auth_openid" class="alternate_auth">or, <a href="#" onclick="Login.showOpenid();return false;">login with an OpenId</a></p><% end %>
<% if show_database_form %><p id="alternate_auth_database" class="alternate_auth">or, <a href="#" onclick="Login.showDatabase();return false;">go back to the standard login</a></p><% end %> <% if show_database_form %><p id="alternate_auth_database" class="alternate_auth">or, <a href="#" onclick="Login.showDatabase();return false;">go back to the standard login</a></p><% end %>
<% if show_cas_form %><p id="alternate_auth_cas" class="alternate_auth">or, <a href="#" onclick="Login.showCAS();return false;">go to the CAS</a></p><% end %>
<script type="text/javascript"> <script type="text/javascript">
function showPreferredAuth() { function showPreferredAuth() {
var preferredAuth = $.cookie('preferred_auth'); var preferredAuth = $.cookie('preferred_auth');
var casEnabled = <%= show_cas_form ? 'true' : 'false' %>;
var databaseEnabled = <%= show_database_form ? 'true' : 'false' %>; var databaseEnabled = <%= show_database_form ? 'true' : 'false' %>;
var openidEnabled = <%= show_openid_form ? 'true' : 'false' %>; var openidEnabled = <%= show_openid_form ? 'true' : 'false' %>;
if (preferredAuth && preferredAuth == 'openid' && openidEnabled) { if (preferredAuth && preferredAuth == 'openid' && openidEnabled) {
Login.showOpenid(); Login.showOpenid();
} }
else if (databaseEnabled) { else if (preferredAuth && preferredAuth == 'database' && databaseEnabled) {
Login.showDatabase(); Login.showDatabase();
} }
else if (openidEnabled) { else if (preferredAuth && preferredAuth == 'cas' && casEnabled) {
Login.showOpenid(); Login.showCAS();
} }
} }
$(document).ready(showPreferredAuth); $(document).ready(showPreferredAuth);
@ -81,7 +105,8 @@ var Login = {
$('#database_auth_form').hide(); $('#database_auth_form').hide();
$('#openid_auth_form').show(); $('#openid_auth_form').show();
$('#alternate_auth_openid').hide(); $('#alternate_auth_openid').hide();
$('#alternate_auth_database').show(); $('#alternate_auth_database').show(); ;
$('#alternate_auth_cas').show();
$('#openid_url').focus(); $('#openid_url').focus();
$('#openid_url').select(); $('#openid_url').select();
$.cookie('preferred_auth', 'openid'); $.cookie('preferred_auth', 'openid');
@ -92,10 +117,21 @@ var Login = {
$('#database_auth_form').show(); $('#database_auth_form').show();
$('#alternate_auth_database').hide(); $('#alternate_auth_database').hide();
$('#alternate_auth_openid').show(); $('#alternate_auth_openid').show();
$('#alternate_auth_cas').show();
$('#user_login').focus(); $('#user_login').focus();
$('#user_login').select(); $('#user_login').select();
$.cookie('preferred_auth', 'database'); $.cookie('preferred_auth', 'database');
},
showCAS: function(container) {
$('#database_auth_form').hide();
$('#openid_auth_form').hide();
$('#cas_auth_form').show();
$('#alternate_auth_cas').hide();
$('#alternate_auth_openid').show();
$('#alternate_auth_database').show();
$.cookie('preferred_auth', 'cas');
} }
} }
</script> </script>

View file

@ -8,11 +8,22 @@
<h3><%= @heading -%></h3> <h3><%= @heading -%></h3>
<table> <table>
<%if Tracks::Config.auth_schemes.include?('cas') && session[:cas_user]%>
<tr>
<td><label for="user_login">With your CAS username:</label></td>
<td> "<%= session[:cas_user]%>" </td>
<td>
<%= hidden_field "user", "login", :value => session[:cas_user] %>
<%= hidden_field "user", "password", :value => session[:cas_user] %>
<%= hidden_field "user", "password_confirmation", :value => session[:cas_user] %>
<%= hidden_field"user", "auth_type", :value => "cas" %></td>
</tr>
<%else%>
<tr> <tr>
<td><label for="user_login">Desired login:</label></td> <td><label for="user_login">Desired login:</label></td>
<td> <%= text_field "user", "login", :size => 20 %></td> <td> <%= text_field "user", "login", :size => 20 %></td>
</tr> </tr>
<tr> <tr>
<td><label for="user_password">Choose password:</label></td> <td><label for="user_password">Choose password:</label></td>
<td><%= password_field "user", "password", :size => 20 %></td> <td><%= password_field "user", "password", :size => 20 %></td>
</tr> </tr>
@ -20,6 +31,11 @@
<td><label for="user_password_confirmation">Confirm password:</label></td> <td><label for="user_password_confirmation">Confirm password:</label></td>
<td><%= password_field "user", "password_confirmation", :size => 20 %></td> <td><%= password_field "user", "password_confirmation", :size => 20 %></td>
</tr> </tr>
<tr>
<td><label for="user_auth_type">Authentication Type:</label></td>
<td><%= select("user", "auth_type", @auth_types, { :include_blank => false })%></td>
</tr>
<%end%>
<tr> <tr>
<td></td> <td></td>
<td><input type="submit" id="signup" value="Signup &#187;" class="primary" /></td> <td><input type="submit" id="signup" value="Signup &#187;" class="primary" /></td>

View file

@ -61,6 +61,10 @@ Rails::Initializer.run do |config|
config.action_view.sanitized_allowed_protocols = 'onenote', 'message' config.action_view.sanitized_allowed_protocols = 'onenote', 'message'
# See Rails::Configuration for more options # See Rails::Configuration for more options
if ( SITE_CONFIG['authentication_schemes'].include? 'cas')
#requires rubycas-client gem to be installed
config.gem "rubycas-client", :lib => 'casclient'
end
end end
# Add new inflection rules using the following format # Add new inflection rules using the following format
@ -96,6 +100,17 @@ if ( SITE_CONFIG['authentication_schemes'].include? 'open_id')
OpenID::Util.logger = RAILS_DEFAULT_LOGGER OpenID::Util.logger = RAILS_DEFAULT_LOGGER
end end
if ( SITE_CONFIG['authentication_schemes'].include? 'cas')
#requires rubycas-client gem to be installed
if defined? CASClient
require 'casclient/frameworks/rails/filter'
CASClient::Frameworks::Rails::Filter.configure(
:cas_base_url => SITE_CONFIG['cas_server'] ,
:cas_server_logout => SITE_CONFIG['cas_server_logout']
)
end
end
tracks_version='1.8devel' tracks_version='1.8devel'
# comment out next two lines if you do not want (or can not) the date of the # comment out next two lines if you do not want (or can not) the date of the
# last git commit in the footer # last git commit in the footer

View file

@ -1,6 +1,7 @@
ActionController::Routing::Routes.draw do |map| ActionController::Routing::Routes.draw do |map|
map.with_options :controller => 'login' do |login| map.with_options :controller => 'login' do |login|
login.login 'login', :action => 'login' login.login 'login', :action => 'login'
login.login_cas 'login_cas', :action => 'login_cas'
login.formatted_login 'login.:format', :action => 'login' login.formatted_login 'login.:format', :action => 'login'
login.logout 'logout', :action => 'logout' login.logout 'logout', :action => 'logout'
login.formatted_logout 'logout.:format', :action => 'logout' login.formatted_logout 'logout.:format', :action => 'logout'

View file

@ -9,6 +9,17 @@ authentication_schemes:
- "database" - "database"
# - "ldap" # - "ldap"
# - "open_id" # - "open_id"
# - "cas"
#set the prefered authentication scheme to display first on the login page
#prefered_auth: database
# Uncomment if using cas
#cas_server: "https://cas.demo.edu/cas"
#cas_server_logout: "https://cas.demo.edu/cas/logout"
# You''ll probably want to change this to the time zone of the computer where Tracks is running # You''ll probably want to change this to the time zone of the computer where Tracks is running

View file

@ -11,5 +11,17 @@ module Tracks
def self.openid_enabled? def self.openid_enabled?
auth_schemes.include?('open_id') auth_schemes.include?('open_id')
end end
def self.cas_enabled?
auth_schemes.include?('cas')
end
def self.prefered_auth?
if SITE_CONFIG['prefered_auth']
SITE_CONFIG['prefered_auth']
else
auth_schemes.first
end
end
end end
end end

View file

@ -131,3 +131,21 @@ anothercontext:
user_id: 4 user_id: 4
created_at: <%= today %> created_at: <%= today %>
updated_at: <%= today %> updated_at: <%= today %>
inbox:
id: 15
name: Inbox
position: 1
hide: false
user_id: 5
created_at: <%= today %>
updated_at: <%= today %>
anothercontext:
id: 16
name: anothercontext
position: 2
hide: false
user_id: 5
created_at: <%= today %>
updated_at: <%= today %>

View file

@ -53,4 +53,22 @@ sms_user_prefs:
verbose_action_descriptors: false verbose_action_descriptors: false
show_project_on_todo_done: true show_project_on_todo_done: true
sms_email: 5555555555@tmomail.net sms_email: 5555555555@tmomail.net
sms_context_id: 13 sms_context_id: 13
other_user_prefs:
id: 4
user_id: 5
staleness_starts: 7
date_format: "%d/%m/%Y"
title_date_format: "%A, %d %B %Y"
show_number_completed: 5
show_completed_projects_in_sidebar: true
show_hidden_contexts_in_sidebar: true
show_hidden_projects_in_sidebar: true
admin_email: butshesagirl@rousette.org.uk
week_starts: 1
due_style: 0
refresh: 0
time_zone: "Los_Angeles"
verbose_action_descriptors: false
show_project_on_todo_done: true

View file

@ -37,4 +37,14 @@ sms_user:
is_admin: false is_admin: false
first_name: SMS first_name: SMS
last_name: Tester last_name: Tester
auth_type: database auth_type: database
ldap_user:
id: 5
login: john
crypted_password: test
token: <%= Digest::SHA1.hexdigest("internationalSun Feb 19 14:42:45 GMT 20060.408173979260027") %>
is_admin: false
first_name: International
last_name: Harvester
auth_type: CAS

View file

@ -0,0 +1,7 @@
open :controller => 'login'
type "username", username
type "password", password
click "//input[@value='Login']"
wait_for_page_to_load "30000"
click "signup"
wait_for_page_to_load "30000"

View file

@ -0,0 +1,11 @@
open :controller => 'login'
click "link=Login"
wait_for_page_to_load "30000"
type "username", username
type "password", password
click "//input[@value='Login']"
wait_for_page_to_load "30000"
click "link=Request Account"
wait_for_page_to_load "30000"
click "signup"
wait_for_page_to_load "30000"

View file

@ -0,0 +1,6 @@
open :controller => 'login'
click "link=Login"
wait_for_page_to_load "30000"
type "username", username
type "password", password
click "//input[@value='Login']"