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 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
@@ -0,0 +1,7 @@
1
+ module Cms::Routes
2
+ def routes_for_bcms_cas
3
+ namespace(:cms) do |cms|
4
+ #cms.content_blocks :cas
5
+ end
6
+ end
7
+ end
data/lib/bcms_cas.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'bcms_cas/routes'
2
+ require 'cas/authentication'
@@ -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
@@ -0,0 +1,3 @@
1
+ gem_root = File.expand_path(File.join(File.dirname(__FILE__), ".."))
2
+ Cms.add_to_rails_paths gem_root
3
+ Cms.add_generator_paths gem_root, "db/migrate/[0-9]*_*.rb"
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+ require 'performance_test_help'
3
+
4
+ # Profiling results for each test method are written to tmp/performance.
5
+ class BrowsingTest < ActionController::PerformanceTest
6
+ def test_homepage
7
+ get '/'
8
+ end
9
+ end
@@ -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