synapses-cas 0.1.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/CHANGELOG +3 -0
 - data/Gemfile +3 -0
 - data/LICENSE +27 -0
 - data/README.md +20 -0
 - data/Rakefile +2 -0
 - data/bin/synapses-cas +30 -0
 - data/config.ru +17 -0
 - data/config/config.example.yml +592 -0
 - data/config/unicorn.rb +88 -0
 - data/db/migrate/001_create_initial_structure.rb +47 -0
 - data/lib/casserver.rb +11 -0
 - data/lib/casserver/authenticators/active_directory_ldap.rb +19 -0
 - data/lib/casserver/authenticators/active_resource.rb +127 -0
 - data/lib/casserver/authenticators/authlogic_crypto_providers/aes256.rb +43 -0
 - data/lib/casserver/authenticators/authlogic_crypto_providers/bcrypt.rb +92 -0
 - data/lib/casserver/authenticators/authlogic_crypto_providers/md5.rb +34 -0
 - data/lib/casserver/authenticators/authlogic_crypto_providers/sha1.rb +59 -0
 - data/lib/casserver/authenticators/authlogic_crypto_providers/sha512.rb +50 -0
 - data/lib/casserver/authenticators/base.rb +67 -0
 - data/lib/casserver/authenticators/client_certificate.rb +47 -0
 - data/lib/casserver/authenticators/google.rb +58 -0
 - data/lib/casserver/authenticators/ldap.rb +147 -0
 - data/lib/casserver/authenticators/ntlm.rb +88 -0
 - data/lib/casserver/authenticators/open_id.rb +22 -0
 - data/lib/casserver/authenticators/sql.rb +133 -0
 - data/lib/casserver/authenticators/sql_authlogic.rb +93 -0
 - data/lib/casserver/authenticators/sql_encrypted.rb +75 -0
 - data/lib/casserver/authenticators/sql_md5.rb +19 -0
 - data/lib/casserver/authenticators/sql_rest_auth.rb +82 -0
 - data/lib/casserver/authenticators/test.rb +22 -0
 - data/lib/casserver/cas.rb +323 -0
 - data/lib/casserver/localization.rb +13 -0
 - data/lib/casserver/model.rb +270 -0
 - data/lib/casserver/server.rb +758 -0
 - data/lib/casserver/utils.rb +32 -0
 - data/lib/casserver/views/_login_form.erb +42 -0
 - data/lib/casserver/views/layout.erb +18 -0
 - data/lib/casserver/views/login.erb +30 -0
 - data/lib/casserver/views/proxy.builder +12 -0
 - data/lib/casserver/views/proxy_validate.builder +25 -0
 - data/lib/casserver/views/service_validate.builder +18 -0
 - data/lib/casserver/views/validate.erb +2 -0
 - data/locales/de.yml +27 -0
 - data/locales/en.yml +26 -0
 - data/locales/es.yml +26 -0
 - data/locales/es_ar.yml +26 -0
 - data/locales/fr.yml +26 -0
 - data/locales/jp.yml +26 -0
 - data/locales/pl.yml +26 -0
 - data/locales/pt.yml +26 -0
 - data/locales/ru.yml +26 -0
 - data/locales/zh.yml +26 -0
 - data/locales/zh_tw.yml +26 -0
 - data/public/themes/cas.css +126 -0
 - data/public/themes/notice.png +0 -0
 - data/public/themes/ok.png +0 -0
 - data/public/themes/simple/bg.png +0 -0
 - data/public/themes/simple/favicon.png +0 -0
 - data/public/themes/simple/login_box_bg.png +0 -0
 - data/public/themes/simple/logo.png +0 -0
 - data/public/themes/simple/theme.css +28 -0
 - data/public/themes/urbacon/bg.png +0 -0
 - data/public/themes/urbacon/login_box_bg.png +0 -0
 - data/public/themes/urbacon/logo.png +0 -0
 - data/public/themes/urbacon/theme.css +33 -0
 - data/public/themes/warning.png +0 -0
 - data/resources/init.d.sh +58 -0
 - data/setup.rb +1585 -0
 - data/spec/alt_config.yml +50 -0
 - data/spec/authenticators/active_resource_spec.rb +109 -0
 - data/spec/authenticators/ldap_spec.rb +53 -0
 - data/spec/casserver_spec.rb +156 -0
 - data/spec/default_config.yml +50 -0
 - data/spec/model_spec.rb +42 -0
 - data/spec/spec.opts +4 -0
 - data/spec/spec_helper.rb +89 -0
 - data/spec/utils_spec.rb +53 -0
 - data/tasks/bundler.rake +4 -0
 - data/tasks/db/migrate.rake +12 -0
 - data/tasks/spec.rake +10 -0
 - metadata +380 -0
 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'casserver/authenticators/base'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'openid'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'openid/extensions/sreg'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'openid/extensions/pape'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'openid/store/memory'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            # CURRENTLY UNIMPLEMENTED
         
     | 
| 
      
 10 
     | 
    
         
            +
            # This is just starter code.
         
     | 
| 
      
 11 
     | 
    
         
            +
            class CASServer::Authenticators::OpenID < CASServer::Authenticators::Base
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              def validate(credentials)
         
     | 
| 
      
 14 
     | 
    
         
            +
                raise NotImplementedError, "The OpenID authenticator is not yet implemented. "+
         
     | 
| 
      
 15 
     | 
    
         
            +
                  "See http://code.google.com/p/rubycas-server/issues/detail?id=36 if you are interested in helping this along."
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                read_standard_credentials(credentials)
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                store = OpenID::Store::Memory.new
         
     | 
| 
      
 20 
     | 
    
         
            +
                consumer = OpenID::Consumer.new({}, store)
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,133 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'casserver/authenticators/base'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            begin
         
     | 
| 
      
 4 
     | 
    
         
            +
              require 'active_record'
         
     | 
| 
      
 5 
     | 
    
         
            +
            rescue LoadError
         
     | 
| 
      
 6 
     | 
    
         
            +
              require 'rubygems'
         
     | 
| 
      
 7 
     | 
    
         
            +
              require 'active_record'
         
     | 
| 
      
 8 
     | 
    
         
            +
            end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            # Authenticates against a plain SQL table.
         
     | 
| 
      
 11 
     | 
    
         
            +
            #
         
     | 
| 
      
 12 
     | 
    
         
            +
            # This assumes that all of your users are stored in a table that has a 'username'
         
     | 
| 
      
 13 
     | 
    
         
            +
            # column and a 'password' column. When the user logs in, CAS conects to the
         
     | 
| 
      
 14 
     | 
    
         
            +
            # database and looks for a matching username/password in the users table. If a
         
     | 
| 
      
 15 
     | 
    
         
            +
            # matching username and password is found, authentication is successful.
         
     | 
| 
      
 16 
     | 
    
         
            +
            #
         
     | 
| 
      
 17 
     | 
    
         
            +
            # Any database backend supported by ActiveRecord can be used.
         
     | 
| 
      
 18 
     | 
    
         
            +
            #
         
     | 
| 
      
 19 
     | 
    
         
            +
            # Config example:
         
     | 
| 
      
 20 
     | 
    
         
            +
            #
         
     | 
| 
      
 21 
     | 
    
         
            +
            #   authenticator:
         
     | 
| 
      
 22 
     | 
    
         
            +
            #     class: CASServer::Authenticators::SQL
         
     | 
| 
      
 23 
     | 
    
         
            +
            #     database:
         
     | 
| 
      
 24 
     | 
    
         
            +
            #       adapter: mysql
         
     | 
| 
      
 25 
     | 
    
         
            +
            #       database: some_database_with_users_table
         
     | 
| 
      
 26 
     | 
    
         
            +
            #       username: root
         
     | 
| 
      
 27 
     | 
    
         
            +
            #       password:
         
     | 
| 
      
 28 
     | 
    
         
            +
            #       server: localhost
         
     | 
| 
      
 29 
     | 
    
         
            +
            #     user_table: users
         
     | 
| 
      
 30 
     | 
    
         
            +
            #     username_column: username
         
     | 
| 
      
 31 
     | 
    
         
            +
            #     password_column: password
         
     | 
| 
      
 32 
     | 
    
         
            +
            #
         
     | 
| 
      
 33 
     | 
    
         
            +
            # When replying to a CAS client's validation request, the server will normally
         
     | 
| 
      
 34 
     | 
    
         
            +
            # provide the client with the authenticated user's username. However it is now
         
     | 
| 
      
 35 
     | 
    
         
            +
            # possible for the server to provide the client with additional attributes.
         
     | 
| 
      
 36 
     | 
    
         
            +
            # You can configure the SQL authenticator to provide data from additional
         
     | 
| 
      
 37 
     | 
    
         
            +
            # columns in the users table by listing the names of the columns under the
         
     | 
| 
      
 38 
     | 
    
         
            +
            # 'extra_attributes' option. Note though that this functionality is experimental.
         
     | 
| 
      
 39 
     | 
    
         
            +
            # It should work with RubyCAS-Client, but may or may not work with other CAS
         
     | 
| 
      
 40 
     | 
    
         
            +
            # clients.
         
     | 
| 
      
 41 
     | 
    
         
            +
            #
         
     | 
| 
      
 42 
     | 
    
         
            +
            # For example, with this configuration, the 'full_name' and 'access_level'
         
     | 
| 
      
 43 
     | 
    
         
            +
            # columns will be provided to your CAS clients along with the username:
         
     | 
| 
      
 44 
     | 
    
         
            +
            #
         
     | 
| 
      
 45 
     | 
    
         
            +
            #   authenticator:
         
     | 
| 
      
 46 
     | 
    
         
            +
            #     class: CASServer::Authenticators::SQL
         
     | 
| 
      
 47 
     | 
    
         
            +
            #     database:
         
     | 
| 
      
 48 
     | 
    
         
            +
            #       adapter: mysql
         
     | 
| 
      
 49 
     | 
    
         
            +
            #       database: some_database_with_users_table
         
     | 
| 
      
 50 
     | 
    
         
            +
            #     user_table: users
         
     | 
| 
      
 51 
     | 
    
         
            +
            #     username_column: username
         
     | 
| 
      
 52 
     | 
    
         
            +
            #     password_column: password
         
     | 
| 
      
 53 
     | 
    
         
            +
            #     ignore_type_column: true # indicates if you want to ignore Single Table Inheritance 'type' field
         
     | 
| 
      
 54 
     | 
    
         
            +
            #     extra_attributes: full_name, access_level
         
     | 
| 
      
 55 
     | 
    
         
            +
            #
         
     | 
| 
      
 56 
     | 
    
         
            +
            class CASServer::Authenticators::SQL < CASServer::Authenticators::Base
         
     | 
| 
      
 57 
     | 
    
         
            +
              def self.setup(options)
         
     | 
| 
      
 58 
     | 
    
         
            +
                raise CASServer::AuthenticatorError, "Invalid authenticator configuration!" unless options[:database]
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                user_model_name = "CASUser_#{options[:auth_index]}"
         
     | 
| 
      
 61 
     | 
    
         
            +
                $LOG.debug "CREATING USER MODEL #{user_model_name}"
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                class_eval %{
         
     | 
| 
      
 64 
     | 
    
         
            +
                  class #{user_model_name} < ActiveRecord::Base
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end
         
     | 
| 
      
 66 
     | 
    
         
            +
                }
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                @user_model = const_get(user_model_name)
         
     | 
| 
      
 69 
     | 
    
         
            +
                @user_model.establish_connection(options[:database])
         
     | 
| 
      
 70 
     | 
    
         
            +
                @user_model.set_table_name(options[:user_table] || 'users')
         
     | 
| 
      
 71 
     | 
    
         
            +
                @user_model.inheritance_column = 'no_inheritance_column' if options[:ignore_type_column]
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
              def self.user_model
         
     | 
| 
      
 75 
     | 
    
         
            +
                @user_model
         
     | 
| 
      
 76 
     | 
    
         
            +
              end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
              def validate(credentials)
         
     | 
| 
      
 79 
     | 
    
         
            +
                read_standard_credentials(credentials)
         
     | 
| 
      
 80 
     | 
    
         
            +
                raise_if_not_configured
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                user_model = self.class.user_model
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                username_column = @options[:username_column] || 'username'
         
     | 
| 
      
 85 
     | 
    
         
            +
                password_column = @options[:password_column] || 'password'
         
     | 
| 
      
 86 
     | 
    
         
            +
                
         
     | 
| 
      
 87 
     | 
    
         
            +
                $LOG.debug "#{self.class}: [#{user_model}] " + "Connection pool size: #{user_model.connection_pool.instance_variable_get(:@checked_out).length}/#{user_model.connection_pool.instance_variable_get(:@connections).length}"
         
     | 
| 
      
 88 
     | 
    
         
            +
                results = user_model.find(:all, :conditions => ["#{username_column} = ? AND #{password_column} = ?", @username, @password])
         
     | 
| 
      
 89 
     | 
    
         
            +
                user_model.connection_pool.checkin(user_model.connection)
         
     | 
| 
      
 90 
     | 
    
         
            +
                   
         
     | 
| 
      
 91 
     | 
    
         
            +
                if results.size > 0
         
     | 
| 
      
 92 
     | 
    
         
            +
                  $LOG.warn("#{self.class}: Multiple matches found for user #{@username.inspect}") if results.size > 1
         
     | 
| 
      
 93 
     | 
    
         
            +
                  
         
     | 
| 
      
 94 
     | 
    
         
            +
                  unless @options[:extra_attributes].blank?
         
     | 
| 
      
 95 
     | 
    
         
            +
                    if results.size > 1
         
     | 
| 
      
 96 
     | 
    
         
            +
                      $LOG.warn("#{self.class}: Unable to extract extra_attributes because multiple matches were found for #{@username.inspect}")
         
     | 
| 
      
 97 
     | 
    
         
            +
                    else
         
     | 
| 
      
 98 
     | 
    
         
            +
                      user = results.first
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                      extract_extra(user)
         
     | 
| 
      
 101 
     | 
    
         
            +
                      log_extra
         
     | 
| 
      
 102 
     | 
    
         
            +
                    end
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                  return true
         
     | 
| 
      
 106 
     | 
    
         
            +
                else
         
     | 
| 
      
 107 
     | 
    
         
            +
                  return false
         
     | 
| 
      
 108 
     | 
    
         
            +
                end
         
     | 
| 
      
 109 
     | 
    
         
            +
              end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
              protected
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
              def raise_if_not_configured
         
     | 
| 
      
 114 
     | 
    
         
            +
                raise CASServer::AuthenticatorError.new(
         
     | 
| 
      
 115 
     | 
    
         
            +
                  "Cannot validate credentials because the authenticator hasn't yet been configured"
         
     | 
| 
      
 116 
     | 
    
         
            +
                ) unless @options
         
     | 
| 
      
 117 
     | 
    
         
            +
              end
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
              def extract_extra user
         
     | 
| 
      
 120 
     | 
    
         
            +
                @extra_attributes = {}
         
     | 
| 
      
 121 
     | 
    
         
            +
                extra_attributes_to_extract.each do |col|
         
     | 
| 
      
 122 
     | 
    
         
            +
                  @extra_attributes[col] = user.send(col)
         
     | 
| 
      
 123 
     | 
    
         
            +
                end
         
     | 
| 
      
 124 
     | 
    
         
            +
              end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
              def log_extra
         
     | 
| 
      
 127 
     | 
    
         
            +
                if @extra_attributes.empty?
         
     | 
| 
      
 128 
     | 
    
         
            +
                  $LOG.warn("#{self.class}: Did not read any extra_attributes for user #{@username.inspect} even though an :extra_attributes option was provided.")
         
     | 
| 
      
 129 
     | 
    
         
            +
                else
         
     | 
| 
      
 130 
     | 
    
         
            +
                  $LOG.debug("#{self.class}: Read the following extra_attributes for user #{@username.inspect}: #{@extra_attributes.inspect}")
         
     | 
| 
      
 131 
     | 
    
         
            +
                end
         
     | 
| 
      
 132 
     | 
    
         
            +
              end
         
     | 
| 
      
 133 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,93 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'casserver/authenticators/sql'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # These were pulled directly from Authlogic, and new ones can be added
         
     | 
| 
      
 4 
     | 
    
         
            +
            # just by including new Crypto Providers
         
     | 
| 
      
 5 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/authlogic_crypto_providers/aes256'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/authlogic_crypto_providers/bcrypt'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/authlogic_crypto_providers/md5'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/authlogic_crypto_providers/sha1'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/authlogic_crypto_providers/sha512'
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            begin
         
     | 
| 
      
 12 
     | 
    
         
            +
              require 'active_record'
         
     | 
| 
      
 13 
     | 
    
         
            +
            rescue LoadError
         
     | 
| 
      
 14 
     | 
    
         
            +
              require 'rubygems'
         
     | 
| 
      
 15 
     | 
    
         
            +
              require 'active_record'
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            # This is a version of the SQL authenticator that works nicely with Authlogic.
         
     | 
| 
      
 19 
     | 
    
         
            +
            # Passwords are encrypted the same way as it done in Authlogic.
         
     | 
| 
      
 20 
     | 
    
         
            +
            # Before use you this, you MUST configure rest_auth_digest_streches and rest_auth_site_key in
         
     | 
| 
      
 21 
     | 
    
         
            +
            # config.
         
     | 
| 
      
 22 
     | 
    
         
            +
            #
         
     | 
| 
      
 23 
     | 
    
         
            +
            # Using this authenticator requires restful authentication plugin on rails (client) side.
         
     | 
| 
      
 24 
     | 
    
         
            +
            #
         
     | 
| 
      
 25 
     | 
    
         
            +
            # * git://github.com/binarylogic/authlogic.git
         
     | 
| 
      
 26 
     | 
    
         
            +
            #
         
     | 
| 
      
 27 
     | 
    
         
            +
            # Usage:
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            # authenticator:
         
     | 
| 
      
 30 
     | 
    
         
            +
            #   class: CASServer::Authenticators::SQLAuthlogic
         
     | 
| 
      
 31 
     | 
    
         
            +
            #   database:
         
     | 
| 
      
 32 
     | 
    
         
            +
            #     adapter: mysql
         
     | 
| 
      
 33 
     | 
    
         
            +
            #     database: some_database_with_users_table
         
     | 
| 
      
 34 
     | 
    
         
            +
            #     user: root
         
     | 
| 
      
 35 
     | 
    
         
            +
            #     password:
         
     | 
| 
      
 36 
     | 
    
         
            +
            #     server: localhost
         
     | 
| 
      
 37 
     | 
    
         
            +
            #   user_table: user
         
     | 
| 
      
 38 
     | 
    
         
            +
            #   username_column: login
         
     | 
| 
      
 39 
     | 
    
         
            +
            #   password_column: crypted_password
         
     | 
| 
      
 40 
     | 
    
         
            +
            #   salt_column: password_salt
         
     | 
| 
      
 41 
     | 
    
         
            +
            #   encryptor: Sha1
         
     | 
| 
      
 42 
     | 
    
         
            +
            #   encryptor_options:
         
     | 
| 
      
 43 
     | 
    
         
            +
            #     digest_format: --SALT--PASSWORD--
         
     | 
| 
      
 44 
     | 
    
         
            +
            #     stretches: 1
         
     | 
| 
      
 45 
     | 
    
         
            +
            #
         
     | 
| 
      
 46 
     | 
    
         
            +
            class CASServer::Authenticators::SQLAuthlogic < CASServer::Authenticators::SQL
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              def validate(credentials)
         
     | 
| 
      
 49 
     | 
    
         
            +
                read_standard_credentials(credentials)
         
     | 
| 
      
 50 
     | 
    
         
            +
                raise_if_not_configured
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                user_model = self.class.user_model
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                username_column = @options[:username_column] || "login"
         
     | 
| 
      
 55 
     | 
    
         
            +
                password_column = @options[:password_column] || "crypted_password"
         
     | 
| 
      
 56 
     | 
    
         
            +
                salt_column     = @options[:salt_column]
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                $LOG.debug "#{self.class}: [#{user_model}] " + "Connection pool size: #{user_model.connection_pool.instance_variable_get(:@checked_out).length}/#{user_model.connection_pool.instance_variable_get(:@connections).length}"
         
     | 
| 
      
 59 
     | 
    
         
            +
                results = user_model.find(:all, :conditions => ["#{username_column} = ?", @username])
         
     | 
| 
      
 60 
     | 
    
         
            +
                user_model.connection_pool.checkin(user_model.connection)
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                begin
         
     | 
| 
      
 63 
     | 
    
         
            +
                  encryptor = eval("Authlogic::CryptoProviders::" + @options[:encryptor] || "Sha512")
         
     | 
| 
      
 64 
     | 
    
         
            +
                rescue
         
     | 
| 
      
 65 
     | 
    
         
            +
                  $LOG.warn("Could not initialize Authlogic crypto class for '#{@options[:encryptor]}'")
         
     | 
| 
      
 66 
     | 
    
         
            +
                  encryptor = Authlogic::CryptoProviders::Sha512
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                @options[:encryptor_options].each do |name, value|
         
     | 
| 
      
 70 
     | 
    
         
            +
                  encryptor.send("#{name}=", value) if encryptor.respond_to?("#{name}=")
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                if results.size > 0
         
     | 
| 
      
 74 
     | 
    
         
            +
                  $LOG.warn("Multiple matches found for user '#{@username}'") if results.size > 1
         
     | 
| 
      
 75 
     | 
    
         
            +
                  user = results.first
         
     | 
| 
      
 76 
     | 
    
         
            +
                  tokens = [@password, (not salt_column.nil?) && user.send(salt_column) || nil].compact
         
     | 
| 
      
 77 
     | 
    
         
            +
                  crypted = user.send(password_column)
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  unless @options[:extra_attributes].blank?
         
     | 
| 
      
 80 
     | 
    
         
            +
                    if results.size > 1
         
     | 
| 
      
 81 
     | 
    
         
            +
                      $LOG.warn("#{self.class}: Unable to extract extra_attributes because multiple matches were found for #{@username.inspect}")
         
     | 
| 
      
 82 
     | 
    
         
            +
                    else
         
     | 
| 
      
 83 
     | 
    
         
            +
                      extract_extra(user)
         
     | 
| 
      
 84 
     | 
    
         
            +
                      log_extra
         
     | 
| 
      
 85 
     | 
    
         
            +
                    end
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  return encryptor.matches?(crypted, tokens)
         
     | 
| 
      
 89 
     | 
    
         
            +
                else
         
     | 
| 
      
 90 
     | 
    
         
            +
                  return false
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
      
 92 
     | 
    
         
            +
              end
         
     | 
| 
      
 93 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,75 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'casserver/authenticators/sql'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'digest/sha1'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'digest/sha2'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'crypt-isaac'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            # This is a more secure version of the SQL authenticator. Passwords are encrypted
         
     | 
| 
      
 8 
     | 
    
         
            +
            # rather than being stored in plain text.
         
     | 
| 
      
 9 
     | 
    
         
            +
            #
         
     | 
| 
      
 10 
     | 
    
         
            +
            # Based on code contributed by Ben Mabey.
         
     | 
| 
      
 11 
     | 
    
         
            +
            #
         
     | 
| 
      
 12 
     | 
    
         
            +
            # Using this authenticator requires some configuration on the client side. Please see
         
     | 
| 
      
 13 
     | 
    
         
            +
            # http://code.google.com/p/rubycas-server/wiki/UsingTheSQLEncryptedAuthenticator
         
     | 
| 
      
 14 
     | 
    
         
            +
            class CASServer::Authenticators::SQLEncrypted < CASServer::Authenticators::SQL
         
     | 
| 
      
 15 
     | 
    
         
            +
              # Include this module into your application's user model.
         
     | 
| 
      
 16 
     | 
    
         
            +
              #
         
     | 
| 
      
 17 
     | 
    
         
            +
              # Your model must have an 'encrypted_password' column where the password will be stored,
         
     | 
| 
      
 18 
     | 
    
         
            +
              # and an 'encryption_salt' column that will be populated with a random string before
         
     | 
| 
      
 19 
     | 
    
         
            +
              # the user record is first created.
         
     | 
| 
      
 20 
     | 
    
         
            +
              module EncryptedPassword
         
     | 
| 
      
 21 
     | 
    
         
            +
                def self.included(mod)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  raise "#{self} should be inclued in an ActiveRecord class!" unless mod.respond_to?(:before_save)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  mod.before_save :generate_encryption_salt
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                def encrypt(str)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  generate_encryption_salt unless encryption_salt
         
     | 
| 
      
 28 
     | 
    
         
            +
                  Digest::SHA256.hexdigest("#{encryption_salt}::#{str}")
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def password=(password)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  self[:encrypted_password] = encrypt(password)
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                def generate_encryption_salt
         
     | 
| 
      
 36 
     | 
    
         
            +
                  self.encryption_salt = Digest::SHA1.hexdigest(Crypt::ISAAC.new.rand(2**31).to_s) unless
         
     | 
| 
      
 37 
     | 
    
         
            +
                    encryption_salt
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              def self.setup(options)
         
     | 
| 
      
 42 
     | 
    
         
            +
                super(options)
         
     | 
| 
      
 43 
     | 
    
         
            +
                user_model.__send__(:include, EncryptedPassword)
         
     | 
| 
      
 44 
     | 
    
         
            +
              end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
              def validate(credentials)
         
     | 
| 
      
 47 
     | 
    
         
            +
                read_standard_credentials(credentials)
         
     | 
| 
      
 48 
     | 
    
         
            +
                raise_if_not_configured
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                user_model = self.class.user_model
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                username_column = @options[:username_column] || "username"
         
     | 
| 
      
 53 
     | 
    
         
            +
                encrypt_function = @options[:encrypt_function] || 'user.encrypted_password == Digest::SHA256.hexdigest("#{user.encryption_salt}::#{@password}")'
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                $LOG.debug "#{self.class}: [#{user_model}] " + "Connection pool size: #{user_model.connection_pool.instance_variable_get(:@checked_out).length}/#{user_model.connection_pool.instance_variable_get(:@connections).length}"
         
     | 
| 
      
 56 
     | 
    
         
            +
                results = user_model.find(:all, :conditions => ["#{username_column} = ?", @username])
         
     | 
| 
      
 57 
     | 
    
         
            +
                user_model.connection_pool.checkin(user_model.connection)
         
     | 
| 
      
 58 
     | 
    
         
            +
                
         
     | 
| 
      
 59 
     | 
    
         
            +
                if results.size > 0
         
     | 
| 
      
 60 
     | 
    
         
            +
                  $LOG.warn("Multiple matches found for user '#{@username}'") if results.size > 1
         
     | 
| 
      
 61 
     | 
    
         
            +
                  user = results.first
         
     | 
| 
      
 62 
     | 
    
         
            +
                  unless @options[:extra_attributes].blank?
         
     | 
| 
      
 63 
     | 
    
         
            +
                    if results.size > 1
         
     | 
| 
      
 64 
     | 
    
         
            +
                      $LOG.warn("#{self.class}: Unable to extract extra_attributes because multiple matches were found for #{@username.inspect}")
         
     | 
| 
      
 65 
     | 
    
         
            +
                    else
         
     | 
| 
      
 66 
     | 
    
         
            +
                      extract_extra(user)
         
     | 
| 
      
 67 
     | 
    
         
            +
                          log_extra
         
     | 
| 
      
 68 
     | 
    
         
            +
                    end
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
                  return eval(encrypt_function)
         
     | 
| 
      
 71 
     | 
    
         
            +
                else
         
     | 
| 
      
 72 
     | 
    
         
            +
                  return false
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
              end
         
     | 
| 
      
 75 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'casserver/authenticators/sql'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'digest/md5'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            # Essentially the same as the standard SQL authenticator, but this version
         
     | 
| 
      
 6 
     | 
    
         
            +
            # assumes that your password is stored as an MD5 hash.
         
     | 
| 
      
 7 
     | 
    
         
            +
            #
         
     | 
| 
      
 8 
     | 
    
         
            +
            # This was contributed by malcomm for Drupal authentication. To work with
         
     | 
| 
      
 9 
     | 
    
         
            +
            # Drupal, you should use 'name' for the :username_column config option, and
         
     | 
| 
      
 10 
     | 
    
         
            +
            # 'pass' for the :password_column.
         
     | 
| 
      
 11 
     | 
    
         
            +
            class CASServer::Authenticators::SQLMd5 < CASServer::Authenticators::SQL
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              protected
         
     | 
| 
      
 14 
     | 
    
         
            +
                def read_standard_credentials(credentials)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  super
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @password = Digest::MD5.hexdigest(@password)
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,82 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'casserver/authenticators/sql_encrypted'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'digest/sha1'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            begin
         
     | 
| 
      
 6 
     | 
    
         
            +
              require 'active_record'
         
     | 
| 
      
 7 
     | 
    
         
            +
            rescue LoadError
         
     | 
| 
      
 8 
     | 
    
         
            +
              require 'rubygems'
         
     | 
| 
      
 9 
     | 
    
         
            +
              require 'active_record'
         
     | 
| 
      
 10 
     | 
    
         
            +
            end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            # This is a version of the SQL authenticator that works nicely with RestfulAuthentication.
         
     | 
| 
      
 13 
     | 
    
         
            +
            # Passwords are encrypted the same way as it done in RestfulAuthentication.
         
     | 
| 
      
 14 
     | 
    
         
            +
            # Before use you this, you MUST configure rest_auth_digest_streches and rest_auth_site_key in
         
     | 
| 
      
 15 
     | 
    
         
            +
            # config.
         
     | 
| 
      
 16 
     | 
    
         
            +
            #
         
     | 
| 
      
 17 
     | 
    
         
            +
            # Using this authenticator requires restful authentication plugin on rails (client) side.
         
     | 
| 
      
 18 
     | 
    
         
            +
            #
         
     | 
| 
      
 19 
     | 
    
         
            +
            # * git://github.com/technoweenie/restful-authentication.git
         
     | 
| 
      
 20 
     | 
    
         
            +
            #
         
     | 
| 
      
 21 
     | 
    
         
            +
            class CASServer::Authenticators::SQLRestAuth < CASServer::Authenticators::SQLEncrypted
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              def validate(credentials)
         
     | 
| 
      
 24 
     | 
    
         
            +
                read_standard_credentials(credentials)
         
     | 
| 
      
 25 
     | 
    
         
            +
                raise_if_not_configured
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                raise CASServer::AuthenticatorError, "You must specify a 'site_key' in the SQLRestAuth authenticator's configuration!" unless  @options[:site_key]
         
     | 
| 
      
 28 
     | 
    
         
            +
                raise CASServer::AuthenticatorError, "You must specify 'digest_streches' in the SQLRestAuth authenticator's configuration!" unless  @options[:digest_streches]
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                user_model = self.class.user_model
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                username_column = @options[:username_column] || "email"
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                $LOG.debug "#{self.class}: [#{user_model}] " + "Connection pool size: #{user_model.connection_pool.instance_variable_get(:@checked_out).length}/#{user_model.connection_pool.instance_variable_get(:@connections).length}"
         
     | 
| 
      
 35 
     | 
    
         
            +
                results = user_model.find(:all, :conditions => ["#{username_column} = ?", @username])
         
     | 
| 
      
 36 
     | 
    
         
            +
                user_model.connection_pool.checkin(user_model.connection)
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                if results.size > 0
         
     | 
| 
      
 39 
     | 
    
         
            +
                  $LOG.warn("Multiple matches found for user '#{@username}'") if results.size > 1
         
     | 
| 
      
 40 
     | 
    
         
            +
                  user = results.first
         
     | 
| 
      
 41 
     | 
    
         
            +
                  if user.crypted_password == user.encrypt(@password,@options[:site_key],@options[:digest_streches])
         
     | 
| 
      
 42 
     | 
    
         
            +
                    unless @options[:extra_attributes].blank?
         
     | 
| 
      
 43 
     | 
    
         
            +
                      extract_extra(user)
         
     | 
| 
      
 44 
     | 
    
         
            +
                      log_extra
         
     | 
| 
      
 45 
     | 
    
         
            +
                    end
         
     | 
| 
      
 46 
     | 
    
         
            +
                    return true
         
     | 
| 
      
 47 
     | 
    
         
            +
                  else
         
     | 
| 
      
 48 
     | 
    
         
            +
                    return false
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
                else
         
     | 
| 
      
 51 
     | 
    
         
            +
                  return false
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
              def self.setup(options)
         
     | 
| 
      
 56 
     | 
    
         
            +
                super(options)
         
     | 
| 
      
 57 
     | 
    
         
            +
                user_model.__send__(:include, EncryptedPassword)
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              module EncryptedPassword
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                def self.included(mod)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  raise "#{self} should be inclued in an ActiveRecord class!" unless mod.respond_to?(:before_save)
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                def encrypt(password,site_key,digest_streches)
         
     | 
| 
      
 67 
     | 
    
         
            +
                  password_digest(password, self.salt,site_key,digest_streches)
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                def secure_digest(*args)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  Digest::SHA1.hexdigest(args.flatten.join('--'))
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                def password_digest(password, salt,site_key,digest_streches)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  digest = site_key
         
     | 
| 
      
 76 
     | 
    
         
            +
                  digest_streches.times do
         
     | 
| 
      
 77 
     | 
    
         
            +
                    digest = secure_digest(digest, salt, password, site_key) 
         
     | 
| 
      
 78 
     | 
    
         
            +
                  end
         
     | 
| 
      
 79 
     | 
    
         
            +
                  digest
         
     | 
| 
      
 80 
     | 
    
         
            +
                end
         
     | 
| 
      
 81 
     | 
    
         
            +
              end
         
     | 
| 
      
 82 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: UTF-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'casserver/authenticators/base'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            # Dummy authenticator used for testing.
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Accepts any username as valid as long as the password is "testpassword"; otherwise authentication fails.
         
     | 
| 
      
 6 
     | 
    
         
            +
            # Raises an AuthenticationError when username is "do_error" (this is useful to test the Exception
         
     | 
| 
      
 7 
     | 
    
         
            +
            # handling functionality).
         
     | 
| 
      
 8 
     | 
    
         
            +
            class CASServer::Authenticators::Test < CASServer::Authenticators::Base
         
     | 
| 
      
 9 
     | 
    
         
            +
              def validate(credentials)
         
     | 
| 
      
 10 
     | 
    
         
            +
                read_standard_credentials(credentials)
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                raise CASServer::AuthenticatorError, "Username is 'do_error'!" if @username == 'do_error'
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                @extra_attributes[:test_utf_string] = "Ютф"
         
     | 
| 
      
 15 
     | 
    
         
            +
                @extra_attributes[:test_numeric] = 123.45
         
     | 
| 
      
 16 
     | 
    
         
            +
                @extra_attributes[:test_serialized] = {:foo => 'bar', :alpha => [1,2,3]}
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                valid_password = options[:password] || "testpassword"
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                return @password == valid_password
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     |