changed the way the config file is loaded to make it a bit easier to test against different config files in the spec

This commit is contained in:
Matt Zukowski 2010-09-23 16:59:20 -04:00
Родитель a761029542
Коммит 861cba76fc
7 изменённых файлов: 158 добавлений и 610 удалений

Просмотреть файл

@ -2,7 +2,7 @@
require 'rubygems'
$: << File.dirname(__FILE__) + "../lib"
$: << File.dirname(__FILE__) + "/../lib"
require 'casserver/server'

Просмотреть файл

@ -7,10 +7,12 @@ require 'casserver/utils'
require 'casserver/cas'
require 'logger'
$LOG = Logger.new(STDOUT)
$LOG ||= Logger.new(STDOUT)
module CASServer
class Server < Sinatra::Base
CONFIG_FILE = ENV['CONFIG_FILE'] || "/etc/rubycas-server/config.yml"
include CASServer::CAS # CAS protocol helpers
include Localization
@ -22,10 +24,9 @@ module CASServer
:maximum_unused_service_ticket_lifetime => 5.minutes, # CAS Protocol Spec, sec. 3.2.1 (recommended expiry time)
:maximum_session_lifetime => 1.month, # all tickets are deleted after this period of time
:log => {:file => 'casserver.log', :level => 'DEBUG'},
:uri_path => "/"
:uri_path => ""
)
set :config, config
set :config_file_loaded, false
def self.uri_path
config[:uri_path]
@ -37,8 +38,6 @@ module CASServer
handler = detect_rack_handler
handler_name = handler.name.gsub(/.*::/, '')
set :url_prefix, '/cas/'
puts "== RubyCAS-Server is starting up " +
"on port #{config[:port] || port} for #{environment} with backup from #{handler_name}" unless handler_name =~/cgi/i
handler.run self, handler_options do |server|
@ -77,7 +76,14 @@ module CASServer
config.merge! HashWithIndifferentAccess.new(YAML.load(config_file))
set :server, config[:server] || 'webrick'
set :config_file_loaded, true
end
def self.reconfigure!(config)
config.each do |key, val|
self.config[key] = val
end
init_database!
init_authenticators!
end
def self.handler_options
@ -171,17 +177,13 @@ module CASServer
end
def self.init_database!
CASServer::Model::Base.establish_connection(config[:database])
#CASServer::Model::Base.establish_connection(config[:database])
ActiveRecord::Base.establish_connection(config[:database])
end
configure do
begin
config_file
rescue NameError
config_file = "/etc/rubycas-server/config.yml"
end
load_config_file(config_file) unless config_file_loaded?
load_config_file(CONFIG_FILE)
init_database!
init_authenticators!
end

46
spec/alt_config.yml Normal file
Просмотреть файл

@ -0,0 +1,46 @@
server: webrick
port: 6543
#ssl_cert: test.pem
uri_path: /test
#bind_address: 0.0.0.0
# database:
# adapter: mysql
# database: casserver
# username: root
# password:
# host: localhost
# reconnect: true
database:
adapter: sqlite3
database: casserver.db
authenticator:
class: CASServer::Authenticators::Test
password: spec_password
theme: simple
organization: "RSPEC-TEST"
infoline: "This is an rspec test."
#custom_views_file: /path/to/custom/views.rb
default_locale: en
log:
file: casserver_spec.log
level: DEBUG
#db_log:
# file: casserver_spec_db.log
enable_single_sign_out: true
#maximum_unused_login_ticket_lifetime: 300
#maximum_unused_service_ticket_lifetime: 300
#maximum_session_lifetime: 172800
#downcase_username: true

Просмотреть файл

@ -7,28 +7,25 @@ $LOG = Logger.new(File.basename(__FILE__).gsub('.rb','.log'))
include Capybara
CASServer::Server.enable(:raise_errors)
CASServer::Server.disable(:show_exceptions)
CASServer::Server.load_config_file('spec_config.yml')
VALID_USERNAME = 'spec_user'
VALID_PASSWORD = 'spec_password'
INVALID_PASSWORD = 'invalid_password'
#Capybara.current_driver = :selenium
Capybara.app = CASServer::Server
describe 'CASServer' do
describe CASServer do
describe "/login" do
before do
@target_service = 'http://my.app.test'
end
describe "/login" do
before do
load_server(File.dirname(__FILE__) + "/default_config.yml")
end
it "logs in successfully with valid username and password without a target service" do
visit "/login"
fill_in 'username', :with => VALID_USERNAME
fill_in 'password', :with => VALID_PASSWORD
click_button 'login-submit'
@ -73,7 +70,7 @@ describe CASServer do
describe '/logout' do
before do
@target_service = 'http://my.app.test'
load_server(File.dirname(__FILE__) + "/default_config.yml")
end
it "logs out successfully" do
@ -91,4 +88,17 @@ describe CASServer do
end
end # describe '/logout'
describe 'configuration' do
it "uri_path value changes prefix of routes" do
load_server(File.dirname(__FILE__) + "/alt_config.yml")
@target_service = 'http://my.app.test'
visit "/test/login"
page.status_code.should_not == 404
visit "/test/logout"
page.status_code.should_not == 404
end
end
end

46
spec/default_config.yml Normal file
Просмотреть файл

@ -0,0 +1,46 @@
server: webrick
port: 6543
#ssl_cert: test.pem
#uri_path: /cas
#bind_address: 0.0.0.0
# database:
# adapter: mysql
# database: casserver
# username: root
# password:
# host: localhost
# reconnect: true
database:
adapter: sqlite3
database: casserver.db
authenticator:
class: CASServer::Authenticators::Test
password: spec_password
theme: simple
organization: "RSPEC-TEST"
infoline: "This is an rspec test."
#custom_views_file: /path/to/custom/views.rb
default_locale: en
log:
file: casserver_spec.log
level: DEBUG
#db_log:
# file: casserver_spec_db.log
enable_single_sign_out: true
#maximum_unused_login_ticket_lifetime: 300
#maximum_unused_service_ticket_lifetime: 300
#maximum_session_lifetime: 172800
#downcase_username: true

Просмотреть файл

@ -1,581 +0,0 @@
# IMPORTANT NOTE ABOUT YAML CONFIGURATION FILES
# ---> Be sure to use spaces instead of tabs for indentation. YAML is
# white-space sensitive!
##### SERVER SETUP ################################################################
# There are several ways to run RubyCAS-Server:
#
# webrick -- stand-alone WEBrick server; should work out-of-the-box; this is
# the default method, but probably not suited for high-traffic usage
# mongrel -- stand-alone Mongrel server; fast, but you'll need to install
# and compile Mongrel and run it behind an https reverse proxy like
# Pound or Apache 2.2's mod_proxy (since Mongrel cannot serve out
# over SSL on its own).
# passenger -- served out by Apache via the mod_rails/mod_rack module
# (see http://www.modrails.com/)
#
# The following are exampe configurations for each of these three methods:
#
###
### WEBrick example
###
# WEBrick is a simple, all-Ruby web server. This is the easiest method for running
# RubyCAS-Server. All you need is an SSL certificate (enter its path under the
# ssl_cert option). WEBrick is fine for sites with low to medium traffic, but for
# high-performance scenarios you may want to look into deploying using Mongrel
# or Passenger.
server: webrick
port: 6543
ssl_cert: /home/URBACON/mzukowski/Private/ssl/urbacon.pem
# If your private key is in a separate file from the cert
#ssl_key: /path/to/your/private_key.pem
# If you do not already have an SSL certificate and would like to automatically
# generate one, run the "generate_ssl_certificate" rake task and use the following
# settings:
# ssl_cert: ssl/cert.pem
# ssl_key: ssl/key.pem
# By default the login page will be available at the root path
# (e.g. https://login.example.net/). The uri_path option lets you serve it from a
# different path (e.g. https://login.example.net/cas).
uri_path: /cas
# This lets you bind the server to a specific address. Use 0.0.0.0 to listen on
# all available interfaces (this is the default).
#bind_address: 0.0.0.0
###
### Mongrel example
###
# Mongrel is much faster than WEBrick, but there are two caveats:
# 1. Since Mongrel can't serve out encrypted HTTP on its own (and CAS requires this),
# you will have to set up a reverse proxy like Pound or Apache's mod_proxy and
# route through it requests to the Mongrel server. So for example,
# your Pound server will receive all of the requests to RubyCAS-Server on port 443,
# and forward them to the Mongrel server listening on port 11011.
# 2. Some of Mongrel's components are compiled into native binaries, so if you are
# installing on Linux, make sure you have all of the standard build tools
# available. The binaries should be automatically compiled for you when you
# install the mogrel gem (if you're runnings Windows, pre-compiled
# binaries will be downloaded and installed, so don't worry about this).
#server: mongrel
#port: 11011
# Bind the server to a specific address. Use 0.0.0.0 to listen on all
# available interfaces (this is the default).
#bind_address: 0.0.0.0
### Reverse proxy configuration examples
# If you're using mod_proxy, your Apache vhost config should look something like this:
#
# Listen 443
# <VirtualHost *:443>
# ServerAdmin admin@example.net
# ServerName login.example.net
#
# SSLEngine On
# SSLCertificateFile /etc/apache2/ssl.crt/example.pem
#
# # Don't do forward proxying, we only want reverse proxying
# ProxyRequests Off
#
# <Proxy balancer://rubycas>
# Order allow,deny
# Allow from all
# BalancerMember http://127.0.0.1:11011
# </Proxy>
# </VirtualHost>
#
# For Pound, the config should be something like:
#
# ListenHTTPS
# Address 0.0.0.0
# Port 11011
# Cert "/etc/ssl/example.pem"
#
# Service
# BackEnd
# Address localhost
# Port 443
# End
# End
# End
###
### Phusion Passenger (running under Apache configured for SSL)
###
# No additional configuration is requried to run RubyCAS-Server under
# passsenger. Just follow the normal instructions for a Passenger app
# (see http://www.modrails.com/).
#
# Here's an example Apache vhost config for RubyCAS-Server and Passenger:
#
# Listen 443
# <VirtualHost *:442>
# ServerAdmin admin@example.net
# ServerName login.example.net
#
# SSLEngine On
# SSLCertificateFile /etc/apache2/ssl.crt/example.pem
#
# RailsAutoDetect off
#
# DocumentRoot /usr/lib/ruby/gems/1.8/gems/rubycas-server-0.8.0/public
#
# <Directory "/usr/lib/ruby/gems/1.8/gems/rubycas-server-0.8.0/public">
# AllowOverride all
# Allow from all
# </Directory>
# </VirtualHost>
#
##### DATABASE #################################################################
# Set up the database connection. Make sure that this database is secure!
#
# By default, we use MySQL, since it is widely used and does not require any
# additional
# ruby libraries besides ActiveRecord.
#
# With MySQL, your config would be something like the following:
# (be sure to create the casserver database in MySQL beforehand,
# i.e. `mysqladmin -u root create casserver`)
database:
adapter: mysql
database: casserver
username: root
password:
host: localhost
reconnect: true
#
# Instead of MySQL you can use SQLite3, PostgreSQL, MSSQL, or anything else
# supported by ActiveRecord.
#
# With SQLite3 (which does not require a separate database server), your
# configuration would look something like the following (don't forget to install
# the sqlite3-ruby gem beforehand!):
#database:
# adapter: sqlite3
# dbfile: /var/lib/casserver.db
##### AUTHENTICATION ###########################################################
# Configure how username/passwords are validated.
#
# !!! YOU MUST CONFIGURE AT LEAST ONE OF THESE AUTHENTICATION METHODS !!!
#
# There are several built-in methods for authentication:
# SQL, ActiveDirectory, LDAP, and GoogleAccounts. If none of these work for you,
# it is relatively easy to write your own custom Authenticator class (see below).
#
# === SQL Authentication =======================================================
#
# The simplest method is to validate against a SQL database. This assumes
# that all of your users are stored in a table that has a 'username' column
# and a 'password' column. When the user logs in, CAS connects to this database
# and looks for a matching username/password in the users table. If a matching
# username and password is found, authentication is successful.
#
# If you prefer to have your passwords stored in an encrypted form, have a
# look at the SQLEncrypted authenticator:
# http://code.google.com/p/rubycas-server/wiki/UsingTheSQLEncryptedAuthenticator
#
# If your users table stores passwords with MD5 hashing (for example as with
# Drupal) try using the SQLMd5 version of the SQL authenticator.
#
authenticator:
-
class: CASServer::Authenticators::Test
password: spec_password
-
class: CASServer::Authenticators::SQL
password_column: display_name
database:
adapter: mysql
database: utrack_development
username: root
password:
host: localhost
#-
# class: CASServer::Authenticators::ActiveDirectoryLDAP
# ldap:
# server: urbacon-ad01.urbacon.net
# port: 636
# base: dc=urbacon,dc=net
# filter: (objectClass=person) & !(msExchHideFromAddressLists=TRUE)
# auth_user: ldapq
# auth_password: urbacon
# encryption: simple_tls
# extra_attributes: cn, mail, memberOf
# Example:
#
#authenticator:
# class: CASServer::Authenticators::SQL
# database:
# adapter: mysql
# database: some_database_with_users_table
# username: root
# password:
# host: localhost
# user_table: users
# username_column: username
# password_column: password
#
# When replying to a CAS client's validation request, the server will normally
# provide the client with the authenticated user's username. However it is
# possible for the server to provide the client with additional attributes.
# You can configure the SQL authenticator to provide data from additional
# columns in the users table by listing the names of the columns under the
# 'extra_attributes' option. Note though that this functionality is experimental.
# It should work with RubyCAS-Client, but may or may not work with other CAS
# clients.
#
# For example, with this configuration, the 'full_name' and 'access_level'
# columns will be provided to your CAS clients along with the username:
#
#authenticator:
# class: CASServer::Authenticators::SQL
# database:
# adapter: mysql
# database: some_database_with_users_table
# user_table: users
# username_column: username
# password_column: password
# extra_attributes: full_name, access_level
#
#
# === Google Authentication ====================================================
#
# The Google authenticator allows users to log in to your CAS server using
# their Google account credentials (i.e. the same email and password they
# would use to log in to Google services like Gmail). This authenticator
# requires no special configuration -- just specify its class name:
#
#authenticator:
# class: CASServer::Authenticators::Google
#
# Note that as with all authenticators, it is possible to use the Google
# authenticator alongside other authenticators. For example, CAS can first
# attempt to validate the account with Google, and if that fails, fall back
# to some other local authentication mechanism.
#
# For example:
#
#authenticator:
# - class: CASServer::Authenticators::Google
# - class: CASServer::Authenticators::SQL
# database:
# adapter: mysql
# database: some_database_with_users_table
# user: root
# password:
# host: localhost
# user_table: user
# username_column: username
# password_column: password
#
#
# === ActiveDirectory Authentication ===========================================
#
# This method authenticates against Microsoft's Active Directory using LDAP.
# You must configure the ActiveDirectory server, and base DN. The port number
# and LDAP filter are optional. You must also enter a CN and password
# for a special "authenticator" user. This account is used to log in to
# the ActiveDirectory server and search LDAP. This does not have to be an
# administrative account -- it only has to be able to search for other
# users.
#
# Note that the auth_user parameter must be the user's CN (Common Name).
# In Active Directory, the CN is genarally the user's full name, which is usually
# NOT the same as their username (sAMAccountName).
#
# For example:
#
#authenticator:
# class: CASServer::Authenticators::ActiveDirectoryLDAP
# ldap:
# host: ad.example.net
# port: 389
# base: dc=example,dc=net
# filter: (objectClass=person)
# auth_user: authenticator
# auth_password: itsasecret
#
# A more complicated example, where the authenticator will use TLS encryption,
# will ignore users with disabled accounts, and will pass on the 'cn' and 'mail'
# attributes to CAS clients:
#
#authenticator:
# class: CASServer::Authenticators::ActiveDirectoryLDAP
# ldap:
# host: ad.example.net
# port: 636
# base: dc=example,dc=net
# filter: (objectClass=person) & !(msExchHideFromAddressLists=TRUE)
# auth_user: authenticator
# auth_password: itsasecret
# encryption: simple_tls
# extra_attributes: cn, mail
#
# It is possible to authenticate against Active Directory without the
# authenticator user, but this requires that users type in their CN as
# the username rather than typing in their sAMAccountName. In other words
# users will likely have to authenticate by typing their full name,
# rather than their username. If you prefer to do this, then just
# omit the auth_user and auth_password values in the above example.
#
#
# === LDAP Authentication ======================================================
#
# This is a more general version of the ActiveDirectory authenticator.
# The configuration is similar, except you don't need an authenticator
# username or password. The following example has been reported to work
# for a basic OpenLDAP setup.
#
#authenticator:
# class: CASServer::Authenticators::LDAP
# ldap:
# host: ldap.example.net
# port: 389
# base: dc=example,dc=net
# username_attribute: uid
# filter: (objectClass=person)
#
# If you need more secure connections via TSL, specify the 'encryption'
# option and change the port. This example also forces the authenticator
# to connect using a special "authenticator" user with the given
# username and password (see the ActiveDirectoryLDAP authenticator
# explanation above):
#
#authenticator:
# class: CASServer::Authenticators::LDAP
# ldap:
# host: ldap.example.net
# port: 636
# base: dc=example,dc=net
# filter: (objectClass=person)
# encryption: simple_tls
# auth_user: cn=admin,dc=example,dc=net
# auth_password: secret
#
# If you need additional data about the user passed to the client (for example,
# their 'cn' and 'mail' attributes, you can specify the list of attributes
# under the extra_attributes config option:
#
#authenticator:
# class: CASServer::Authenticators::LDAP
# ldap:
# host: ldap.example.net
# port: 389
# base: dc=example,dc=net
# filter: (objectClass=person)
# extra_attributes: cn, mail
#
# Note that the above functionality is somewhat limited by client compatibility.
# See the SQL authenticator notes above for more info.
#
#
# === Custom Authentication ====================================================
#
# It should be relatively easy to write your own Authenticator class. Have a look
# at the built-in authenticators in the casserver/authenticators directory. Your
# authenticator should extend the CASServer::Authenticators::Base class and must
# implement a validate() method that takes a single hash argument. When the user
# submits the login form, the username and password they entered is passed to
# validate() as a hash under :username and :password keys. In the future, this
# hash might also contain other data such as the domain that the user is logging
# in to.
#
# To use your custom authenticator, specify it's class name and path to the
# source file in the authenticator section of the config. Any other parameters
# you specify in the authenticator configuration will be passed on to the
# authenticator and made availabe in the validate() method as an @options hash.
#
# Example:
#
#authenticator:
# class: FooModule::MyCustomAuthenticator
# source: /path/to/source.rb
# option_a: foo
# another_option: yeeha
#
# === Multiple Authenticators ==================================================
#
# If you need to have more than one source for authentication, such as an LDAP
# directory and a database, you can use multiple authenticators by making
# :authenticator an array of authenticators.
#
#authenticator:
# -
# class: CASServer::Authenticators::ActiveDirectoryLDAP
# ldap:
# host: ad.example.net
# port: 389
# base: dc=example,dc=net
# filter: (objectClass=person)
# -
# class: CASServer::Authenticators::SQL
# database:
# adapter: mysql
# database: some_database_with_users_table
# user: root
# password:
# host: localhost
# user_table: user
# username_column: username
# password_column: password
#
# During authentication, the user credentials will be checked against the first
# authenticator and on failure fall through to the second authenticator.
#
##### LOOK & FEEL ##############################################################
# Set the path to the theme directory that determines how your CAS pages look.
#
# Custom themes are not well supported yet, but will be in the near future. In
# the meantime, if you want to create a custom theme, you can create a
# subdirectory under the CASServer's themes dir (for example,
# '/usr/lib/ruby/1.8/gems/casserver-xxx/public/themes', if you installed CASServer
# on Linux as a gem). A theme is basically just a theme.css file that overrides
# the themes/cas.css styles along with a collection of image files
# like logo.png and bg.png.
#
# By default, we use the 'simple' theme which you can find in themes/simple.
theme: urbacon
# The name of your company/organization. This will show up on the login page.
organization: URBACON
# A short bit of text that shows up on the login page. You can make this blank
# if you prefer to have no extra text shown at the bottom of the login box.
infoline: "Matt's Dev Server"
# Custom views file. Overrides methodes in lib/casserver/views.rb
#custom_views_file: /path/to/custom/views.rb
##### LOCALIZATION (L10N) #######################################################
# The server will attempt to detect the user's locale and show text in the
# appropriate language based on:
#
# 1. The 'lang' URL parameter (if any)
# 2. The 'lang' cookie (if any)
# 3. The HTTP_ACCEPT_LANGUAGE header supplied by the user's browser.
# 4. The HTTP_USER_AGENT header supplied by the user's browser.
#
# If the locale cannot be established based on one of the above checks (in the
# shown order), then the below 'default_locale' option will be used.
#
# The format is the same as standard linux locales (langagecode_COUNTRYCODE):
#
# ru_RU - Russian, Russia
# eo_AQ - Esperanto, Antarctica
#
# It will also work if you leave out the region (i.e. just "ru" for Russian,
# "eo" for Esperanto).
#
# If you are interested in contributing new translations or have corrections
# to the existing translations, see
# http://code.google.com/p/rubycas-server/wiki/HowToContribueTranslations
#
default_locale: en
##### LOGGING ##################################################################
# Configure general logging. This log is where you'll want to look in case of
# problems.
#
# You may want to change the file to something like /var/log/casserver.log
# Set the level to DEBUG if you want more detailed logging.
log:
file: /mnt/old-system/var/log/rails-logs/rubycas-server.log
level: DEBUG
# If you want full database logging, uncomment this next section.
# Every SQL query will be logged here. This is useful for debugging database
# problems.
#
#db_log:
# file: /var/log/casserver_db.log
##### SINGLE SIGN-OUT ##########################################################
# When a user logs in to a CAS-enabled client application, that application
# generally opens its own local user session. When the user then logs out
# through the CAS server, each of the CAS-enabled client applications need
# to be notified so that they can close their own local sessions for that user.
#
# Up until recently this was not possible within CAS. However, a method for
# performing this notification was recently added to the protocol (in CAS 3.1).
# This works exactly as described above -- when the user logs out, the CAS
# server individually contacts each client service and notifies it of the
# logout. Currently not all client applications support this, so this
# behaviour is disabled by default. To enable it, uncomment the following
# configuration line. Note that currently it is not possible to enable
# or disable single-sign-out on a per-service basis, but this functionality
# is planned for a future release.
enable_single_sign_out: true
##### OTHER ####################################################################
# You can set various ticket expiry times (specify the value in seconds).
# Unused login and service tickets become unusable this many seconds after
# they are created. (Defaults to 5 minutes)
#maximum_unused_login_ticket_lifetime: 300
#maximum_unused_service_ticket_lifetime: 300
# The server must periodically delete old tickets (login tickets, service tickets
# proxy-granting tickets, and ticket-granting tickets) to prevent buildup of
# stale data. This effectively limits the maximum length of a CAS session to
# the lifetime given here (in seconds). (Defaults to 48 hours)
#
# Note that this limit is not enforced on the client side; it refers only to the
# the maximum lifetime of tickets on the CAS server.
#maximum_session_lifetime: 172800
# If you want the usernames entered on the login page to be automatically
# downcased (converted to lowercase), enable the following option. When this
# option is set to true, if the user enters "JSmith" as their username, the
# system will automatically
# convert this to "jsmith".
downcase_username: true

Просмотреть файл

@ -1,14 +1,39 @@
require File.join(File.dirname(__FILE__), '..', 'lib', 'casserver', 'server.rb')
require 'rubygems'
require 'sinatra'
require 'rack/test'
require 'spec'
require 'spec/autorun'
require 'spec/interop/test'
require 'logger'
# set test environment
set :environment, :test
set :run, false
set :raise_errors, true
set :logging, false
def silence_warnings
old_verbose, $VERBOSE = $VERBOSE, nil
yield
ensure
$VERBOSE = old_verbose
end
# this called in specs' `before` block
# ... due to the way Sinatra applications are loaded,
# we're forced to delay loading of the server code
# until the start of each test so that certain
# configuraiton options can be changed (e.g. `uri_path`)
def load_server(config_file)
ENV['CONFIG_FILE'] = config_file
silence_warnings do
load File.dirname(__FILE__) + '/../lib/casserver/server.rb'
end
CASServer::Server.enable(:raise_errors)
CASServer::Server.disable(:show_exceptions)
#Capybara.current_driver = :selenium
Capybara.app = CASServer::Server
end