bcms_cas 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +92 -0
- data/app/models/cas_user.rb +20 -0
- data/app/portlets/helpers/login_portlet_helper.rb +15 -0
- data/db/migrate/20091002162550_add_cas_user_group.rb +9 -0
- data/lib/bcms_cas/routes.rb +7 -0
- data/lib/bcms_cas.rb +2 -0
- data/lib/cas/authentication.rb +67 -0
- data/lib/cas/utils.rb +72 -0
- data/rails/init.rb +3 -0
- data/test/performance/browsing_test.rb +9 -0
- data/test/test_helper.rb +38 -0
- data/test/unit/cas/cas_authentication_test.rb +108 -0
- data/test/unit/cas_user_test.rb +35 -0
- data/test/unit/cas_utils_test.rb +83 -0
- data/test/unit/helpers/login_portlet_helper_test.rb +10 -0
- metadata +68 -0
data/README.markdown
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# Central Authentication Server Module
|
2
|
+
|
3
|
+
This module allows BrowserCMS to integrate with a Central Authentication Server (CAS) to allow users to log in to a BrowserCMS site,
|
4
|
+
using credentials stored in an external system. This module requires an existing CAS server to be running (See http://code.google.com/p/rubycas-server/)
|
5
|
+
as an example of a server.
|
6
|
+
|
7
|
+
This module will allow user to login to the public area of the CMS, using the Login Form Portlet. It does not handle users that need to
|
8
|
+
log into the CMS administrative area. It also handles single logout by redirecting the user to cas /logout service.
|
9
|
+
|
10
|
+
## A. Instructions
|
11
|
+
Here are the necessary steps to install this module.
|
12
|
+
|
13
|
+
1. Configure your CAS server and test that you can login directly via their /login page.
|
14
|
+
2. Install the rubycas-client gem (See B below)
|
15
|
+
3. Install the bcms_cas module, and configure it to point to your CAS server (see C below).
|
16
|
+
4. Migrate the database to add the CAS Group (See D below)
|
17
|
+
5. Alter the Login Form Portlet to submit to the CAS server. (See E below)
|
18
|
+
|
19
|
+
## B. Installing RubyCAS-Client
|
20
|
+
This project depends on RubyCAS-client (http://code.google.com/p/rubycas-client/). RubyCAS-Client is a standard Rails PluginGem, and the instructions
|
21
|
+
for installing in into a Rails project can be found on their website. The following command will probably work though:
|
22
|
+
|
23
|
+
gem install rubycas-client
|
24
|
+
|
25
|
+
This will add the latest version of a gem. The bcms_cas module will require the necessary files, so you do not need to
|
26
|
+
make any configuration changes in your rails project.
|
27
|
+
|
28
|
+
## C. Installing/Configuring the Module
|
29
|
+
To install a BrowserCMS module follow the instructions here http://www.browsercms.org/doc/guides/html/installing_modules.html .
|
30
|
+
After that you will need to configure the rubycas-client to point to the correct CAS server, along with any other
|
31
|
+
configuration options you need. Add the following to your config/initializers/browsercms.rb:
|
32
|
+
|
33
|
+
|
34
|
+
CASClient::Frameworks::Rails::Filter.configure(
|
35
|
+
:cas_base_url => "https://cas.yourdomainname.org",
|
36
|
+
:extra_attributes_session_key => :cas_extra_attributes
|
37
|
+
)
|
38
|
+
|
39
|
+
Make sure your SITE_DOMAIN variable in production/development is correctly set to the right top level domain. This will be needed
|
40
|
+
to allow redirects between the servers to happen correctly (it requires Absolute URLs). For example, in config/environments/production.rb:
|
41
|
+
|
42
|
+
SITE_DOMAIN="www.yourdomainname.com"
|
43
|
+
|
44
|
+
### Extra Attributes (Optional)
|
45
|
+
The :extra_attributes_session_key may not be needed, depending on what type of Authenticator your CAS server is using. You can
|
46
|
+
safely leave it out if you are just using the normal CMS logic. A CAS server can send additional information back, and these will be stored as
|
47
|
+
session variables that can be accessed in other methods.
|
48
|
+
|
49
|
+
## D. Add/Configure the 'CAS Authenticated User' Group
|
50
|
+
When you run rake db:migrate, this module will add a new group to the CMS called 'CAS Authenticated Users'. All users that
|
51
|
+
log in successfully will be assigned to members of this group. You will potentially want to rename this group to something
|
52
|
+
that more accurately reflects who these users are (i.e. Members, Staff, etc) and then set which sections of the website this
|
53
|
+
group can visit.
|
54
|
+
|
55
|
+
## E. Configure Login Form Portlet
|
56
|
+
Alter the Login Form portlet to look something like this:
|
57
|
+
|
58
|
+
<% form_tag "https://cas.yourdomainname.org" do %>
|
59
|
+
<%= login_ticket_tag %>
|
60
|
+
<%= service_url_tag %>
|
61
|
+
<p>
|
62
|
+
<%= label_tag :login %>
|
63
|
+
<%= text_field_tag :username, @login %>
|
64
|
+
</p>
|
65
|
+
<p>
|
66
|
+
<%= label_tag :password %>
|
67
|
+
<%= password_field_tag :password %>
|
68
|
+
</p>
|
69
|
+
<p>
|
70
|
+
<%= label_tag :remember_me %>
|
71
|
+
<%= check_box_tag :remember_me, '1', @remember_me %>
|
72
|
+
</p>
|
73
|
+
<p><%= submit_tag "Login" %></p>
|
74
|
+
<% end %>
|
75
|
+
|
76
|
+
The key changes are:
|
77
|
+
|
78
|
+
1. The form needs to submit directly to the CAS server
|
79
|
+
2. You need to add helpers for login_ticket_tag and service_url_tag. These generate hidden parameters CAS services need.
|
80
|
+
3. Change the username parameter from :login to :username
|
81
|
+
|
82
|
+
F. Known Issues
|
83
|
+
|
84
|
+
* Every page is secured by the CASClient Gateway Filter, which means a lot of redirects. This is potentially a big performance hit, and would require modifying the filter so it only handles checking login_tickets, rather than redirects.
|
85
|
+
* A user logged in using CAS will be assigned to a single group. There is no way to map a user to different groups (i.e. Platnium or Gold Members). Could potentially be done via cas extra info.
|
86
|
+
* The internal CMS User database is bypassed/not used for login for front end pages. This means it would fail the cmsadmin user tried to login via the Login Form.
|
87
|
+
* [Low] LoginPortlet Form tag should pull from CAS automatically (requires changes to CMS core)
|
88
|
+
* [Low] username/login field is different between CMS and CAS (requires core changes)
|
89
|
+
* The CAS Login page has to be styled to match the look and feel of the site.
|
90
|
+
* If the user types in wrong username/pw on CMS login form, they will be left on the CAS Login page, with message.
|
91
|
+
* Every hit to a page with the login form portlet is fetching a LT from CAS. This is potentially slow. [Performance]
|
92
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#
|
2
|
+
# This represents a user was autheniticated using a CAS service. Their user data is not saved in the database (in the users table_,
|
3
|
+
# but is retrieved from an external service and stored purely as session data.
|
4
|
+
#
|
5
|
+
#
|
6
|
+
class CasUser < GuestUser
|
7
|
+
|
8
|
+
GROUP_NAME = "cas_group"
|
9
|
+
|
10
|
+
def initialize(attributes={})
|
11
|
+
super({ :first_name => "CAS", :last_name => "User"}.merge(attributes))
|
12
|
+
@guest = false
|
13
|
+
end
|
14
|
+
|
15
|
+
# Using a single group for now. (This will need to be mapped to more groups later).
|
16
|
+
def group
|
17
|
+
@group ||= Group.find_by_code(GROUP_NAME)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# This assumes there is no existing LoginPortletHelper defined in the Core CMS project, and provides one
|
2
|
+
# to simplify what users need to do in the form.
|
3
|
+
module LoginPortletHelper
|
4
|
+
|
5
|
+
# Generates the hidden field for the service_url that the CAS server expects, which tells it where to redirect to. Must create
|
6
|
+
# an absolute URL.
|
7
|
+
def service_url_tag
|
8
|
+
hidden_field_tag :service, Cas::Utils.service_url(@portlet, @page, session[:return_to])
|
9
|
+
end
|
10
|
+
|
11
|
+
# Generates the hidden field for the login ticket that CAS server expects.
|
12
|
+
def login_ticket_tag
|
13
|
+
hidden_field_tag :lt, Cas::Utils.fetch_lt_from_cas
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class AddCasUserGroup < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
group = Group.create!(:name=>"CAS Authenticated Users", :code=>"cas_group", :group_type=>GroupType.find_by_name("Registered Public User"))
|
4
|
+
group.sections = Section.all
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.down
|
8
|
+
end
|
9
|
+
end
|
data/lib/bcms_cas.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'cas/utils'
|
2
|
+
require 'casclient'
|
3
|
+
require 'casclient/frameworks/rails/filter'
|
4
|
+
|
5
|
+
#
|
6
|
+
# Augments the core Cms::Controllers to add Cas Authentication behavior.
|
7
|
+
#
|
8
|
+
module Cas
|
9
|
+
module Authentication
|
10
|
+
|
11
|
+
# Called when this module is included on the given class.
|
12
|
+
def self.included(controller_class)
|
13
|
+
controller_class.send(:include, InstanceMethods)
|
14
|
+
|
15
|
+
controller_class.skip_filter :check_access_to_page
|
16
|
+
controller_class.before_filter CASClient::Frameworks::Rails::GatewayFilter
|
17
|
+
controller_class.before_filter :login_from_cas_ticket
|
18
|
+
controller_class.before_filter :check_access_to_page_normally
|
19
|
+
end
|
20
|
+
|
21
|
+
# Each instance of the controller will gain these methods.
|
22
|
+
module InstanceMethods
|
23
|
+
def check_access_to_page_normally
|
24
|
+
logger.warn "Checking auth using normal Cms filter."
|
25
|
+
check_access_to_page
|
26
|
+
end
|
27
|
+
|
28
|
+
# Attempts to set the current user based on the session attribute set by CAS.
|
29
|
+
def login_from_cas_ticket
|
30
|
+
logger.debug "Attempting to login using CAS session variable."
|
31
|
+
if session[:cas_user]
|
32
|
+
logger.warn "Who is @current_user '#{@current_user.login}'?" if @current_user
|
33
|
+
logger.warn "Who is User.current '#{User.current.login}'?" if User.current
|
34
|
+
|
35
|
+
user = CasUser.new(:login=>session[:cas_user])
|
36
|
+
|
37
|
+
# Having to set both of these feels very duplicative. Ideally I would like a way
|
38
|
+
# to set only once, but calling current_user= has sideeffects.
|
39
|
+
@current_user = User.current = user
|
40
|
+
|
41
|
+
logger.info "Found session[:cas_user]. Created CasUser with login '#{user.login}' and set as current_user." if @current_user
|
42
|
+
end
|
43
|
+
@current_user
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
Cms::ContentController.send(:include, Cas::Authentication)
|
48
|
+
|
49
|
+
|
50
|
+
# Extends the core SessionController to properly destroy the local session on logout, and redirect to CAS for Single Log out.
|
51
|
+
module SingleLogOut
|
52
|
+
def self.included(controller_class)
|
53
|
+
controller_class.send(:include, InstanceMethods)
|
54
|
+
controller_class.alias_method_chain :destroy, :cas
|
55
|
+
end
|
56
|
+
|
57
|
+
module InstanceMethods
|
58
|
+
|
59
|
+
def destroy_with_cas
|
60
|
+
logger.info "Handle single logout."
|
61
|
+
logout_user
|
62
|
+
Cas::Utils.logout(self, "http://#{SITE_DOMAIN}/")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
Cms::SessionsController.send(:include, Cas::SingleLogOut)
|
67
|
+
end
|
data/lib/cas/utils.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
#
|
2
|
+
# Customizes behavior of CASFilter.
|
3
|
+
#
|
4
|
+
module Cas
|
5
|
+
class Utils
|
6
|
+
# This is a wrapper around the default behavior of the CASClient Rails filter.
|
7
|
+
#
|
8
|
+
# The only difference is that it generates a return URL that the user can click on to get back to the homepage.
|
9
|
+
def self.logout(controller, service = nil)
|
10
|
+
# Copy/Paste from Filter
|
11
|
+
referer = reset_session_and_get_referrer(controller, service)
|
12
|
+
|
13
|
+
# New lines
|
14
|
+
client = CASClient::Frameworks::Rails::Filter.client
|
15
|
+
|
16
|
+
# Adding gateway=true param to this logout URL will cause immediate redirect, which is preferable
|
17
|
+
# since it means users aren't left stranded on the CAS server logout page.
|
18
|
+
url = client.logout_url(referer, referer)
|
19
|
+
controller.send(:redirect_to, "#{url}&gateway=true")
|
20
|
+
end
|
21
|
+
|
22
|
+
# Copy/Paste from CAS Filter
|
23
|
+
def self.reset_session_and_get_referrer(controller, service)
|
24
|
+
referer = service || controller.request.referer
|
25
|
+
st = controller.session[:cas_last_valid_ticket]
|
26
|
+
delete_service_session_lookup(st) if st
|
27
|
+
controller.send(:reset_session)
|
28
|
+
referer
|
29
|
+
end
|
30
|
+
#
|
31
|
+
# Gets a valid login_ticket from the CAS Server, which will allow us to submit directly from our CMS login forms.
|
32
|
+
#
|
33
|
+
def self.fetch_lt_from_cas
|
34
|
+
url = URI.parse("#{self.cas_server_url}/loginTicket")
|
35
|
+
post = Net::HTTP::Post.new(url.path)
|
36
|
+
post.set_form_data({'dummy'=>'data'})
|
37
|
+
|
38
|
+
https = Net::HTTP.new(url.host, url.port)
|
39
|
+
https.use_ssl = true
|
40
|
+
|
41
|
+
res = https.start {|http| http.request(post) }
|
42
|
+
lt = res.body
|
43
|
+
lt
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.check(portlet)
|
47
|
+
portlet.current_page.path
|
48
|
+
end
|
49
|
+
|
50
|
+
# Calculates which URL the user should be redirect to, after completing registration on the CAS server.
|
51
|
+
def self.service_url(portlet, page, redirect_to = nil)
|
52
|
+
path = page.path if page
|
53
|
+
path = "" unless page
|
54
|
+
goto = redirect_to || portlet.success_url || path
|
55
|
+
unless goto.starts_with?("http://")
|
56
|
+
goto = to_absolute_url(goto)
|
57
|
+
end
|
58
|
+
goto
|
59
|
+
end
|
60
|
+
|
61
|
+
# Looks up the URL of the CAS server from the environment
|
62
|
+
def self.cas_server_url
|
63
|
+
CASClient::Frameworks::Rails::Filter.config[:cas_base_url]
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def self.to_absolute_url(path)
|
69
|
+
"http://#{SITE_DOMAIN}#{path}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/rails/init.rb
ADDED
data/test/test_helper.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
|
3
|
+
require 'test_help'
|
4
|
+
|
5
|
+
class ActiveSupport::TestCase
|
6
|
+
# Transactional fixtures accelerate your tests by wrapping each test method
|
7
|
+
# in a transaction that's rolled back on completion. This ensures that the
|
8
|
+
# test database remains unchanged so your fixtures don't have to be reloaded
|
9
|
+
# between every test method. Fewer database queries means faster tests.
|
10
|
+
#
|
11
|
+
# Read Mike Clark's excellent walkthrough at
|
12
|
+
# http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
|
13
|
+
#
|
14
|
+
# Every Active Record database supports transactions except MyISAM tables
|
15
|
+
# in MySQL. Turn off transactional fixtures in this case; however, if you
|
16
|
+
# don't care one way or the other, switching from MyISAM to InnoDB tables
|
17
|
+
# is recommended.
|
18
|
+
#
|
19
|
+
# The only drawback to using transactional fixtures is when you actually
|
20
|
+
# need to test transactions. Since your test is bracketed by a transaction,
|
21
|
+
# any transactions started in your code will be automatically rolled back.
|
22
|
+
self.use_transactional_fixtures = true
|
23
|
+
|
24
|
+
# Instantiated fixtures are slow, but give you @david where otherwise you
|
25
|
+
# would need people(:david). If you don't want to migrate your existing
|
26
|
+
# test cases which use the @david style and don't mind the speed hit (each
|
27
|
+
# instantiated fixtures translates to a database query per test method),
|
28
|
+
# then set this back to true.
|
29
|
+
self.use_instantiated_fixtures = false
|
30
|
+
|
31
|
+
# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
|
32
|
+
#
|
33
|
+
# Note: You'll currently still have to declare fixtures explicitly in integration tests
|
34
|
+
# -- they do not yet inherit this setting
|
35
|
+
fixtures :all
|
36
|
+
|
37
|
+
# Add more helper methods to be used by all tests here...
|
38
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'mocha'
|
3
|
+
|
4
|
+
class MyController < ActionController::Base
|
5
|
+
include Cms::Authentication::Controller
|
6
|
+
|
7
|
+
def get_at_current_user
|
8
|
+
@current_user
|
9
|
+
end
|
10
|
+
|
11
|
+
def flash
|
12
|
+
{}
|
13
|
+
end
|
14
|
+
|
15
|
+
def destroy
|
16
|
+
"Exists only to be alias_method_chained"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class CasAuthTest < ActiveSupport::TestCase
|
21
|
+
|
22
|
+
def setup
|
23
|
+
MyController.expects(:skip_filter).with(:check_access_to_page)
|
24
|
+
MyController.expects(:before_filter).with(CASClient::Frameworks::Rails::GatewayFilter)
|
25
|
+
MyController.expects(:before_filter).with(:login_from_cas_ticket)
|
26
|
+
MyController.expects(:before_filter).with(:check_access_to_page_normally)
|
27
|
+
|
28
|
+
MyController.send(:include, Cas::Authentication)
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
def teardown
|
33
|
+
User.current = nil
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
test "Alias's the existing filter to a different name." do
|
38
|
+
c = MyController.new
|
39
|
+
c.expects(:check_access_to_page)
|
40
|
+
|
41
|
+
c.check_access_to_page_normally
|
42
|
+
end
|
43
|
+
|
44
|
+
test "adds current_user and login from session to class" do
|
45
|
+
c = MyController.new
|
46
|
+
|
47
|
+
assert c.respond_to?(:current_user)
|
48
|
+
assert c.respond_to?(:login_from_cas_ticket)
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
test "login_from_cas_ticket will create and set the current user and User.current if a session attribute was found." do
|
54
|
+
c = MyController.new
|
55
|
+
c.session = {}
|
56
|
+
c.session[:cas_user] = "1234"
|
57
|
+
|
58
|
+
User.current = Group.find_by_code("guest")
|
59
|
+
|
60
|
+
c.login_from_cas_ticket
|
61
|
+
|
62
|
+
current_user = c.get_at_current_user
|
63
|
+
assert_equal CasUser, current_user.class
|
64
|
+
assert_equal "1234", current_user.login
|
65
|
+
assert_equal current_user, User.current
|
66
|
+
end
|
67
|
+
|
68
|
+
test "Cms::ContentController gets augmented" do
|
69
|
+
assert (Cms::ContentController.new.respond_to? :check_access_to_page_normally)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
class CasSessionControllerTest < ActiveSupport::TestCase
|
75
|
+
|
76
|
+
|
77
|
+
test "alias_method_chain the normal methods" do
|
78
|
+
MyController.send(:include, Cas::SingleLogOut)
|
79
|
+
|
80
|
+
c = MyController.new
|
81
|
+
|
82
|
+
assert( c.respond_to? :destroy)
|
83
|
+
assert( c.respond_to? :destroy_with_cas)
|
84
|
+
assert( c.respond_to? :destroy_without_cas)
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
test "destroy_with_cas redirects to server and calls logout_user" do
|
89
|
+
MyController.send(:include, Cas::SingleLogOut)
|
90
|
+
c = MyController.new
|
91
|
+
|
92
|
+
c.expects(:logout_user)
|
93
|
+
|
94
|
+
Cas::Utils.expects(:logout).with(c, "http://#{SITE_DOMAIN}/")
|
95
|
+
|
96
|
+
c.destroy_with_cas
|
97
|
+
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
test "that BrowserCMS 3.0.3 installed." do
|
102
|
+
assert Cms::SessionsController.new.respond_to?(:logout_user), "Need to have BrowserCMS 3.0.3 installed for Cas module to work."
|
103
|
+
end
|
104
|
+
|
105
|
+
test "Cms::SessionController gets augmented" do
|
106
|
+
assert (Cms::SessionsController.new.respond_to? :destroy_with_cas)
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CasUserTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@s = Section.create!(:name=>"root", :root=>true, :path=>"/")
|
7
|
+
@p = Page.create!(:name=>"Home", :section=>@s, :path=>"/p")
|
8
|
+
@g = Group.create!(:name=>"G", :code=>"cas_group")
|
9
|
+
@g.sections = Section.all
|
10
|
+
end
|
11
|
+
|
12
|
+
test "group returns the cas_group" do
|
13
|
+
user = CasUser.new
|
14
|
+
|
15
|
+
assert_equal @g, user.group
|
16
|
+
end
|
17
|
+
|
18
|
+
test "cas_user should be able to view all sections (based on group)" do
|
19
|
+
user = CasUser.new
|
20
|
+
|
21
|
+
assert user.able_to_view?(@p)
|
22
|
+
end
|
23
|
+
|
24
|
+
test "setting login" do
|
25
|
+
user = CasUser.new(:login=>"bob")
|
26
|
+
assert_equal "bob", user.login
|
27
|
+
end
|
28
|
+
|
29
|
+
test "that CasUsers are not considered guests" do
|
30
|
+
user = CasUser.new
|
31
|
+
assert !user.guest?
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'mocha'
|
3
|
+
|
4
|
+
class CasUtilsTest < ActiveSupport::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@current_page = Page.new(:path=>"/expected")
|
8
|
+
@portlet = LoginPortlet.new
|
9
|
+
end
|
10
|
+
|
11
|
+
test "service_url returns absolute success_url if specified" do
|
12
|
+
@portlet.success_url = "/stuff"
|
13
|
+
assert_equal "http://localhost:3000/stuff", Cas::Utils.service_url(@portlet, @current_page), "This really need to be an absolute path for it work w/ CAS."
|
14
|
+
end
|
15
|
+
|
16
|
+
test "service_url returns current page if specified" do
|
17
|
+
p = LoginPortlet.new
|
18
|
+
p.current_page = Page.new(:path=>"/expected")
|
19
|
+
|
20
|
+
s = Cas::Utils.service_url(p, @current_page)
|
21
|
+
assert_equal "http://localhost:3000/expected", s
|
22
|
+
end
|
23
|
+
|
24
|
+
test "service_url returns redirect_to if available" do
|
25
|
+
s = Cas::Utils.service_url(@portlet, @current_page, "/redirected")
|
26
|
+
assert_equal "http://localhost:3000/redirected", s
|
27
|
+
end
|
28
|
+
|
29
|
+
test "Nil page doesn't cause Nil exception" do
|
30
|
+
s = Cas::Utils.service_url(@portlet, nil, nil)
|
31
|
+
assert_equal "http://localhost:3000", s
|
32
|
+
end
|
33
|
+
|
34
|
+
test "Portlets work as expected (CMS Core check)" do
|
35
|
+
p = LoginPortlet.new
|
36
|
+
|
37
|
+
assert_equal nil, p.success_url, "Validate that LoginPortlet returns nil if no success_url is set (rather than an empty string."
|
38
|
+
end
|
39
|
+
|
40
|
+
test "cas_server_url looks up CAS server from config in environment" do
|
41
|
+
expected = "https://127.0.0.1"
|
42
|
+
CASClient::Frameworks::Rails::Filter.expects(:config).returns({:cas_base_url=>expected})
|
43
|
+
|
44
|
+
assert_equal expected, Cas::Utils.cas_server_url
|
45
|
+
end
|
46
|
+
|
47
|
+
test "get login ticket" do
|
48
|
+
expected_host = "https://random.com"
|
49
|
+
Cas::Utils.expects(:cas_server_url).with.returns(expected_host)
|
50
|
+
|
51
|
+
Net::HTTP.any_instance.stubs(:start).returns(mock(:body=>"Ticket 100"))
|
52
|
+
uri = stub(:path=>"#{expected_host}/loginTicket", :host=>"", :port=>80)
|
53
|
+
URI.expects(:parse).with("#{expected_host}/loginTicket").returns(uri)
|
54
|
+
|
55
|
+
ticket = Cas::Utils.fetch_lt_from_cas
|
56
|
+
assert_equal "Ticket 100", ticket
|
57
|
+
end
|
58
|
+
|
59
|
+
# Verification test of CasClient API behavior.
|
60
|
+
test "[CASClient] Verify expected behavior of CASClient#logout_url" do
|
61
|
+
destination_url = "localhost"
|
62
|
+
|
63
|
+
client = CASClient::Client.new({:cas_base_url=>"/", :logout_url=>"/"})
|
64
|
+
|
65
|
+
logout_url = client.logout_url(destination_url, destination_url)
|
66
|
+
assert_equal "/?destination=localhost&url=localhost", logout_url, "Verifies that logout_url generates a correct URL."
|
67
|
+
assert_equal String, logout_url.class
|
68
|
+
end
|
69
|
+
|
70
|
+
test "Cas::Utils#logout redirects and attaches gateway=true to logout_url" do
|
71
|
+
destination_url = "localhost"
|
72
|
+
logout_url = "/?destination=localhost&url=localhost"
|
73
|
+
|
74
|
+
CASClient::Frameworks::Rails::Filter.expects(:client).returns(CASClient::Client.new({:cas_base_url=>""}))
|
75
|
+
CASClient::Client.any_instance.expects(:logout_url).with(destination_url, destination_url).returns(logout_url)
|
76
|
+
|
77
|
+
controller = stub()
|
78
|
+
controller.expects(:redirect_to).with("#{logout_url}&gateway=true")
|
79
|
+
Cas::Utils.expects(:reset_session_and_get_referrer).returns(destination_url)
|
80
|
+
|
81
|
+
Cas::Utils.logout(controller, "/")
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'mocha'
|
3
|
+
|
4
|
+
class LoginPortletHelperTest < ActionView::TestCase
|
5
|
+
|
6
|
+
test "Fetching login ticket" do
|
7
|
+
ticket = Cas::Utils.expects(:fetch_lt_from_cas).with().returns("ABC")
|
8
|
+
assert_equal hidden_field_tag( :lt, "ABC"), login_ticket_tag
|
9
|
+
end
|
10
|
+
end
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bcms_cas
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- BrowserMedia
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-05 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: github@browsermedia.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.markdown
|
24
|
+
files:
|
25
|
+
- app/models/cas_user.rb
|
26
|
+
- app/portlets/helpers/login_portlet_helper.rb
|
27
|
+
- db/migrate/20091002162550_add_cas_user_group.rb
|
28
|
+
- lib/bcms_cas.rb
|
29
|
+
- lib/bcms_cas/routes.rb
|
30
|
+
- lib/cas/authentication.rb
|
31
|
+
- lib/cas/utils.rb
|
32
|
+
- rails/init.rb
|
33
|
+
- README.markdown
|
34
|
+
has_rdoc: true
|
35
|
+
homepage: http://browsercms.org
|
36
|
+
licenses: []
|
37
|
+
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options:
|
40
|
+
- --charset=UTF-8
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: "0"
|
48
|
+
version:
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
requirements: []
|
56
|
+
|
57
|
+
rubyforge_project: browsercms
|
58
|
+
rubygems_version: 1.3.4
|
59
|
+
signing_key:
|
60
|
+
specification_version: 3
|
61
|
+
summary: A CAS Module for BrowserCMS
|
62
|
+
test_files:
|
63
|
+
- test/performance/browsing_test.rb
|
64
|
+
- test/test_helper.rb
|
65
|
+
- test/unit/cas/cas_authentication_test.rb
|
66
|
+
- test/unit/cas_user_test.rb
|
67
|
+
- test/unit/cas_utils_test.rb
|
68
|
+
- test/unit/helpers/login_portlet_helper_test.rb
|