diff --git a/.gitignore b/.gitignore index 90ad19cb..4fcd38c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,24 @@ -# See http://help.github.com/ignore-files/ for more about ignoring files. -# -# If you find yourself ignoring temporary files generated by your text editor -# or operating system, you probably want to add a global ignore instead: -# git config --global core.excludesfile ~/.gitignore_global - -# Ignore bundler config -/.bundle - -# Ignore the default SQLite database. -/db/*.sqlite3 - -# Ignore all logfiles and tempfiles. -/log/*.log -/tmp +*.gem +*.rbc +.bundle +.config +.yardoc .rails_generators~ - -/coverage - -/pkg - -# http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/ -/Gemfile.lock - -# Dummy application crap -/spec/dummy/log/*.log -/spec/dummy/tmp -/spec/dummy/db/*.sqlite3 +gemfiles/vendor +Gemfile.lock +InstalledFiles +_yardoc +coverage +doc/ +lib/bundler/man +pkg +rdoc +spec/reports +test/tmp +test/version_tmp +tmp +*.lock +.idea/ +.ruby-version +*.sqlite* +*.log diff --git a/.travis.yml b/.travis.yml index 327103aa..cb46f79c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,18 @@ language: ruby rvm: -- 2.1.0 - 2.2.2 +- 2.4.0 +- 2.4.1 +bundler_args: --without development +gemfile: + - gemfiles/rails_5.0.gemfile + - gemfiles/rails_5.1.gemfile +matrix: + allow_failures: + - rvm: 2.4.0 + - rvm: 2.4.1 + # gemfile: gemfiles/rails_5.0.gemfile + # gemfile: gemfiles/rails_5.1.gemfile notifications: hipchat: rooms: diff --git a/Appraisals b/Appraisals new file mode 100644 index 00000000..901c13f3 --- /dev/null +++ b/Appraisals @@ -0,0 +1,11 @@ +appraise 'rails-5.0' do + gem 'activerecord', '~> 5.0.0' + gem 'rails-controller-testing' + gem 'rspec-rails', '>= 3.5' +end + +appraise 'rails-5.1' do + gem 'activerecord', '~> 5.1.0' + gem 'rails-controller-testing' + gem 'rspec-rails', '>= 3.5' +end diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..c4205a1d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,22 @@ +# 11/15/2017 - v5.0.0 + +* Drop Rails 4.2 support +* Add Appraisals +* Fix tests to use keyword arguments +* Fix bugs revealed by IntegrationTest converting `nil` to blank strings +* Addressed deprecations +* Upgraded dummy app + +# 11/14/2017 - v4.2.0 + +* Add Ruby 2.4.0 and 2.4.1 support +* Drop Rails 4.1 support +* Update tests to address deprecations +* Replaced FactoryGirl with FactoryBot +* Fixed test that likely never worked, but did not fail because of deprecated gems +* Loosen gem versions +* Rubocop cleanup + +# 9/26/2015 + +* Added ability to pass a `context` object when verifying user login, allowing to pass extra data such as HTTP request (e.g. subdomain) if needed [5a99dac8f83492d643c20719f2d911d27c933a68](https://github.com/identification-io/CASino/commit/5a99dac8f83492d643c20719f2d911d27c933a68) diff --git a/Gemfile b/Gemfile index 851fabc2..f3f929d8 100644 --- a/Gemfile +++ b/Gemfile @@ -1,2 +1,18 @@ source 'https://rubygems.org' + +group :test do + gem 'appraisal', '>= 2.1' + gem 'capybara', '>= 2.1' + gem 'coveralls', '>= 0.7' + gem 'factory_bot', '>= 4.1' + gem 'rake', '>= 10.0' + gem 'rspec-its', '>= 1.0' + gem 'webmock', '>= 1.9' +end + +# Specify your gem's dependencies in groupify.gemspec gemspec + +platforms :ruby do + gem 'sqlite3', '>= 1.3' +end diff --git a/README.md b/README.md index e6d35746..13e0fb1e 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,17 @@ It currently supports [CAS 1.0 and CAS 2.0](http://apereo.github.io/cas) as well Please check our [documentation](http://casino.rbcas.com/) for setup and configuration instructions. +## Test Suite + +Run the RSpec test suite by installing the `appraisal` gem and dependencies: + + $ gem install appraisal + $ appraisal install + +And then running tests using `appraisal`: + + $ appraisal rake + ## License CASino is released under the [MIT License](http://www.opensource.org/licenses/MIT). See LICENSE.txt for further details. diff --git a/Rakefile b/Rakefile index 92e8bc1d..f20cdbc4 100755 --- a/Rakefile +++ b/Rakefile @@ -4,7 +4,7 @@ require 'rake' require 'bundler/gem_tasks' require 'rspec/core/rake_task' -task :default => :spec +task default: :spec desc 'Run all specs' RSpec::Core::RakeTask.new(:spec) do |spec| diff --git a/app/controllers/casino/application_controller.rb b/app/controllers/casino/application_controller.rb index 151495cc..6b165e68 100644 --- a/app/controllers/casino/application_controller.rb +++ b/app/controllers/casino/application_controller.rb @@ -7,6 +7,7 @@ class CASino::ApplicationController < ::ApplicationController unless Rails.env.development? rescue_from ActionView::MissingTemplate, with: :missing_template + rescue_from ActionController::UnknownFormat, with: :missing_template end def cookies diff --git a/app/controllers/casino/controller_concern/ticket_validator.rb b/app/controllers/casino/controller_concern/ticket_validator.rb index 53bfbb55..b7155d8c 100644 --- a/app/controllers/casino/controller_concern/ticket_validator.rb +++ b/app/controllers/casino/controller_concern/ticket_validator.rb @@ -7,7 +7,7 @@ def validate_ticket(ticket) validation_result = validate_ticket_for_service(ticket, params[:service], renew: params[:renew]) if validation_result.success? options = { ticket: ticket } - options[:proxy_granting_ticket] = acquire_proxy_granting_ticket(params[:pgtUrl], ticket) unless params[:pgtUrl].nil? + options[:proxy_granting_ticket] = acquire_proxy_granting_ticket(params[:pgtUrl], ticket) if params[:pgtUrl].present? build_ticket_validation_response(true, options) else build_ticket_validation_response(false, @@ -21,7 +21,7 @@ def build_ticket_validation_response(success, options = {}) end def ensure_service_ticket_parameters_present - if params[:ticket].nil? || params[:service].nil? + if params[:ticket].blank? || params[:service].blank? build_ticket_validation_response(false, error_code: 'INVALID_REQUEST', error_message: '"ticket" and "service" parameters are both required') diff --git a/app/controllers/casino/proxy_tickets_controller.rb b/app/controllers/casino/proxy_tickets_controller.rb index 7e95134e..b1a28525 100644 --- a/app/controllers/casino/proxy_tickets_controller.rb +++ b/app/controllers/casino/proxy_tickets_controller.rb @@ -31,7 +31,7 @@ def build_proxy_response(success, options = {}) end def ensure_proxy_parameters_present - if params[:pgt].nil? || params[:targetService].nil? + if params[:pgt].blank? || params[:targetService].blank? build_proxy_response(false, error_code: 'INVALID_REQUEST', error_message: '"pgt" and "targetService" parameters are both required') diff --git a/app/controllers/casino/sessions_controller.rb b/app/controllers/casino/sessions_controller.rb old mode 100644 new mode 100755 index 50c77ad4..a5d3c274 --- a/app/controllers/casino/sessions_controller.rb +++ b/app/controllers/casino/sessions_controller.rb @@ -16,12 +16,12 @@ def index def new tgt = current_ticket_granting_ticket - return handle_signed_in(tgt) unless params[:renew] || tgt.nil? - redirect_to(params[:service]) if params[:gateway] && params[:service].present? + return handle_signed_in(tgt) unless params[:renew].present? || tgt.nil? + redirect_to(params[:service]) if params[:gateway].present? && params[:service].present? end def create - validation_result = validate_login_credentials(params[:username], params[:password]) + validation_result = validate_login_credentials(params[:username], params[:password], current_authenticator_context) if !validation_result log_failed_login params[:username] show_login_error I18n.t('login_credential_acceptor.invalid_login_credentials') @@ -41,7 +41,7 @@ def destroy_others .ticket_granting_tickets .where('id != ?', current_ticket_granting_ticket.id) .destroy_all if signed_in? - redirect_to params[:service] || sessions_path + redirect_to params[:service].present? ? params[:service] : sessions_path end def logout diff --git a/app/helpers/casino/sessions_helper.rb b/app/helpers/casino/sessions_helper.rb index 13d27d74..1077a33c 100644 --- a/app/helpers/casino/sessions_helper.rb +++ b/app/helpers/casino/sessions_helper.rb @@ -23,6 +23,10 @@ def current_user tgt.user end + def current_authenticator_context + CASino.config.authenticator_context_builder.call(params, request) + end + def ensure_signed_in redirect_to login_path unless signed_in? end @@ -83,12 +87,12 @@ def handle_signed_in(tgt, options = {}) end def handle_signed_in_with_service(tgt, options) - if !service_allowed?(params[:service]) - @service = params[:service] - render 'casino/sessions/service_not_allowed', status: 403 - else + if service_allowed?(params[:service]) url = acquire_service_ticket(tgt, params[:service], options).service_with_ticket_url redirect_to url, status: :see_other + else + @service = params[:service] + render 'casino/sessions/service_not_allowed', status: 403 end end end diff --git a/app/models/casino/application_record.rb b/app/models/casino/application_record.rb new file mode 100644 index 00000000..6d054639 --- /dev/null +++ b/app/models/casino/application_record.rb @@ -0,0 +1,3 @@ +class CASino::ApplicationRecord < ActiveRecord::Base + self.abstract_class = true +end diff --git a/app/models/casino/auth_token_ticket.rb b/app/models/casino/auth_token_ticket.rb index dce6f077..01fc4e96 100644 --- a/app/models/casino/auth_token_ticket.rb +++ b/app/models/casino/auth_token_ticket.rb @@ -1,15 +1,14 @@ -class CASino::AuthTokenTicket < ActiveRecord::Base +class CASino::AuthTokenTicket < CASino::ApplicationRecord include CASino::ModelConcern::Ticket include CASino::ModelConcern::ConsumableTicket self.ticket_prefix = 'ATT'.freeze def self.cleanup - delete_all(['created_at < ?', CASino.config.auth_token_ticket[:lifetime].seconds.ago]) + where(['created_at < ?', CASino.config.auth_token_ticket[:lifetime].seconds.ago]).delete_all end def expired? - (Time.now - (self.created_at || Time.now)) > CASino.config.auth_token_ticket[:lifetime].seconds + (Time.now - (created_at || Time.now)) > CASino.config.auth_token_ticket[:lifetime].seconds end - end diff --git a/app/models/casino/login_attempt.rb b/app/models/casino/login_attempt.rb index 73ca13ca..4914fea9 100644 --- a/app/models/casino/login_attempt.rb +++ b/app/models/casino/login_attempt.rb @@ -1,4 +1,4 @@ -class CASino::LoginAttempt < ActiveRecord::Base +class CASino::LoginAttempt < CASino::ApplicationRecord include CASino::ModelConcern::BrowserInfo belongs_to :user diff --git a/app/models/casino/login_ticket.rb b/app/models/casino/login_ticket.rb index afc789ac..a18782af 100644 --- a/app/models/casino/login_ticket.rb +++ b/app/models/casino/login_ticket.rb @@ -1,14 +1,14 @@ -class CASino::LoginTicket < ActiveRecord::Base +class CASino::LoginTicket < CASino::ApplicationRecord include CASino::ModelConcern::Ticket include CASino::ModelConcern::ConsumableTicket self.ticket_prefix = 'LT'.freeze def self.cleanup - delete_all(['created_at < ?', CASino.config.login_ticket[:lifetime].seconds.ago]) + where(['created_at < ?', CASino.config.login_ticket[:lifetime].seconds.ago]).delete_all end def expired? - (Time.now - (self.created_at || Time.now)) > CASino.config.login_ticket[:lifetime].seconds + (Time.now - (created_at || Time.now)) > CASino.config.login_ticket[:lifetime].seconds end end diff --git a/app/models/casino/proxy_granting_ticket.rb b/app/models/casino/proxy_granting_ticket.rb index 07dece3d..33ee6525 100644 --- a/app/models/casino/proxy_granting_ticket.rb +++ b/app/models/casino/proxy_granting_ticket.rb @@ -1,5 +1,5 @@ -class CASino::ProxyGrantingTicket < ActiveRecord::Base +class CASino::ProxyGrantingTicket < CASino::ApplicationRecord include CASino::ModelConcern::Ticket self.ticket_prefix = 'PGT'.freeze diff --git a/app/models/casino/proxy_ticket.rb b/app/models/casino/proxy_ticket.rb index e64b358a..caef26c9 100644 --- a/app/models/casino/proxy_ticket.rb +++ b/app/models/casino/proxy_ticket.rb @@ -1,6 +1,6 @@ require 'addressable/uri' -class CASino::ProxyTicket < ActiveRecord::Base +class CASino::ProxyTicket < CASino::ApplicationRecord include CASino::ModelConcern::Ticket self.ticket_prefix = 'PT'.freeze @@ -10,11 +10,11 @@ class CASino::ProxyTicket < ActiveRecord::Base has_many :proxy_granting_tickets, as: :granter, dependent: :destroy def self.cleanup_unconsumed - self.destroy_all(['created_at < ? AND consumed = ?', CASino.config.proxy_ticket[:lifetime_unconsumed].seconds.ago, false]) + where(['created_at < ? AND consumed = ?', CASino.config.proxy_ticket[:lifetime_unconsumed].seconds.ago, false]).destroy_all end def self.cleanup_consumed - self.destroy_all(['created_at < ? AND consumed = ?', CASino.config.proxy_ticket[:lifetime_consumed].seconds.ago, true]) + where(['created_at < ? AND consumed = ?', CASino.config.proxy_ticket[:lifetime_consumed].seconds.ago, true]).destroy_all end def expired? diff --git a/app/models/casino/service_rule.rb b/app/models/casino/service_rule.rb index 27b9b1f9..6188d2fe 100644 --- a/app/models/casino/service_rule.rb +++ b/app/models/casino/service_rule.rb @@ -1,5 +1,5 @@ -class CASino::ServiceRule < ActiveRecord::Base +class CASino::ServiceRule < CASino::ApplicationRecord validates :name, presence: true validates :url, uniqueness: true, presence: true diff --git a/app/models/casino/service_ticket.rb b/app/models/casino/service_ticket.rb index 6e56fa4f..3a5ddd38 100644 --- a/app/models/casino/service_ticket.rb +++ b/app/models/casino/service_ticket.rb @@ -1,6 +1,6 @@ require 'addressable/uri' -class CASino::ServiceTicket < ActiveRecord::Base +class CASino::ServiceTicket < CASino::ApplicationRecord include CASino::ModelConcern::Ticket self.ticket_prefix = 'ST'.freeze @@ -10,15 +10,15 @@ class CASino::ServiceTicket < ActiveRecord::Base has_many :proxy_granting_tickets, as: :granter, dependent: :destroy def self.cleanup_unconsumed - self.delete_all(['created_at < ? AND consumed = ?', CASino.config.service_ticket[:lifetime_unconsumed].seconds.ago, false]) + where(['created_at < ? AND consumed = ?', CASino.config.service_ticket[:lifetime_unconsumed].seconds.ago, false]).delete_all end def self.cleanup_consumed - self.destroy_all(['(ticket_granting_ticket_id IS NULL OR created_at < ?) AND consumed = ?', CASino.config.service_ticket[:lifetime_consumed].seconds.ago, true]) + where(['(ticket_granting_ticket_id IS NULL OR created_at < ?) AND consumed = ?', CASino.config.service_ticket[:lifetime_consumed].seconds.ago, true]).destroy_all end def self.cleanup_consumed_hard - self.delete_all(['created_at < ? AND consumed = ?', (CASino.config.service_ticket[:lifetime_consumed] * 2).seconds.ago, true]) + where(['created_at < ? AND consumed = ?', (CASino.config.service_ticket[:lifetime_consumed] * 2).seconds.ago, true]).delete_all end def service=(service) @@ -27,21 +27,22 @@ def service=(service) end def service_with_ticket_url - service_uri = Addressable::URI.parse(self.service) - service_uri.query_values = (service_uri.query_values(Array) || []) << ['ticket', self.ticket] + service_uri = Addressable::URI.parse(service) + service_uri.query_values = (service_uri.query_values(Array) || []) << ['ticket', ticket] service_uri.to_s end def expired? lifetime = if consumed? - CASino.config.service_ticket[:lifetime_consumed] - else - CASino.config.service_ticket[:lifetime_unconsumed] - end - (Time.now - (self.created_at || Time.now)) > lifetime + CASino.config.service_ticket[:lifetime_consumed] + else + CASino.config.service_ticket[:lifetime_unconsumed] + end + (Time.now - (created_at || Time.now)) > lifetime end private + def send_single_sign_out_notification notifier = SingleSignOutNotifier.new(self) notifier.notify diff --git a/app/models/casino/ticket_granting_ticket.rb b/app/models/casino/ticket_granting_ticket.rb index 0def6e1e..d9069d3f 100644 --- a/app/models/casino/ticket_granting_ticket.rb +++ b/app/models/casino/ticket_granting_ticket.rb @@ -1,6 +1,6 @@ require 'user_agent' -class CASino::TicketGrantingTicket < ActiveRecord::Base +class CASino::TicketGrantingTicket < CASino::ApplicationRecord include CASino::ModelConcern::Ticket include CASino::ModelConcern::BrowserInfo diff --git a/app/models/casino/two_factor_authenticator.rb b/app/models/casino/two_factor_authenticator.rb index ed93c604..16435b06 100644 --- a/app/models/casino/two_factor_authenticator.rb +++ b/app/models/casino/two_factor_authenticator.rb @@ -1,11 +1,11 @@ -class CASino::TwoFactorAuthenticator < ActiveRecord::Base +class CASino::TwoFactorAuthenticator < CASino::ApplicationRecord belongs_to :user scope :active, -> { where(active: true) } def self.cleanup - self.delete_all(['(created_at < ?) AND active = ?', self.lifetime.ago, false]) + where(['(created_at < ?) AND active = ?', lifetime.ago, false]).delete_all end def self.lifetime @@ -13,6 +13,6 @@ def self.lifetime end def expired? - !self.active? && (Time.now - (self.created_at || Time.now)) > self.class.lifetime + !active? && (Time.now - (created_at || Time.now)) > self.class.lifetime end end diff --git a/app/models/casino/user.rb b/app/models/casino/user.rb index 2bd2a72b..b65685b6 100644 --- a/app/models/casino/user.rb +++ b/app/models/casino/user.rb @@ -1,5 +1,5 @@ -class CASino::User < ActiveRecord::Base +class CASino::User < CASino::ApplicationRecord serialize :extra_attributes, Hash has_many :ticket_granting_tickets diff --git a/app/processors/casino/authentication_processor.rb b/app/processors/casino/authentication_processor.rb old mode 100644 new mode 100755 index 2acf3648..c0b3ad9d --- a/app/processors/casino/authentication_processor.rb +++ b/app/processors/casino/authentication_processor.rb @@ -3,11 +3,17 @@ module CASino::AuthenticationProcessor extend ActiveSupport::Concern - def validate_login_credentials(username, password) + def validate_login_credentials(username, password, context = nil) authentication_result = nil authenticators.each do |authenticator_name, authenticator| begin - data = authenticator.validate(username, password) + credentials = [ username, password, context ] + + # Old authenticators that don't accept a 3rd context parameter will have a validate + # method that only accepts 2 arguments, so check for that. + credentials.pop if authenticator.class.instance_method(:validate).arity == 2 + + data = authenticator.validate(*credentials) rescue CASino::Authenticator::AuthenticatorError => e Rails.logger.error "Authenticator '#{authenticator_name}' (#{authenticator.class}) raised an error: #{e}" end diff --git a/app/views/casino/sessions/new.html.erb b/app/views/casino/sessions/new.html.erb index 71050fc3..30607949 100644 --- a/app/views/casino/sessions/new.html.erb +++ b/app/views/casino/sessions/new.html.erb @@ -14,7 +14,7 @@
<%= form_tag(login_path, method: :post, id: 'login-form') do %> <%= hidden_field_tag :lt, CASino::LoginTicket.create.ticket %> - <%= hidden_field_tag :service, params[:service] unless params[:service].nil? %> + <%= hidden_field_tag :service, params[:service] unless params[:service].blank? %> <%= label_tag :username, t('login.label_username') %> <%= text_field_tag :username, params[:username], autofocus:true %> <%= label_tag :password, t('login.label_password') %> @@ -28,4 +28,3 @@
<%= render 'footer' %> - diff --git a/casino.gemspec b/casino.gemspec index 95f79f33..2f2874cd 100644 --- a/casino.gemspec +++ b/casino.gemspec @@ -1,5 +1,5 @@ -# -*- encoding: utf-8 -*- -$:.push File.expand_path('../lib', __FILE__) + +$LOAD_PATH.push File.expand_path('../lib', __FILE__) require 'casino/version' Gem::Specification.new do |s| @@ -14,7 +14,7 @@ Gem::Specification.new do |s| s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") - s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } + s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) } s.require_paths = ['lib'] sign_file = File.expand_path '~/.gem/casino-private_key.pem' @@ -23,25 +23,15 @@ Gem::Specification.new do |s| s.cert_chain = ['casino-public_cert.pem'] end - s.add_development_dependency 'capybara', '~> 2.1' - s.add_development_dependency 'rake', '~> 10.0' - s.add_development_dependency 'rspec', '~> 3.0' - s.add_development_dependency 'rspec-its', '~> 1.0' - s.add_development_dependency 'rspec-rails', '~> 3.0' - s.add_development_dependency 'sqlite3', '~> 1.3' - s.add_development_dependency 'factory_girl', '~> 4.1' - s.add_development_dependency 'webmock', '~> 1.9' - s.add_development_dependency 'coveralls', '~> 0.7' - - s.add_runtime_dependency 'rails', '>= 4.1.0', '< 4.3.0' - s.add_runtime_dependency 'sass-rails', '>= 4.0.0', '< 6.0.0' - s.add_runtime_dependency 'addressable', '~> 2.3' - s.add_runtime_dependency 'terminal-table', '~> 1.4' - s.add_runtime_dependency 'useragent', '~> 0.4' - s.add_runtime_dependency 'faraday', '~> 0.8' - s.add_runtime_dependency 'rotp', '~> 2.0' - s.add_runtime_dependency 'grape', '~> 0.8' - s.add_runtime_dependency 'grape-entity', '~> 0.4' - s.add_runtime_dependency 'rqrcode_png', '~> 0.1' + s.add_runtime_dependency 'addressable', '>= 2.3' + s.add_runtime_dependency 'faraday', '>= 0.8' + s.add_runtime_dependency 'grape', '>= 0.8' + s.add_runtime_dependency 'grape-entity', '>= 0.4' s.add_runtime_dependency 'kaminari', '~> 0.16' + s.add_runtime_dependency 'rails', '>= 4.2' + s.add_runtime_dependency 'rotp', '>= 2.0' + s.add_runtime_dependency 'rqrcode_png', '>= 0.1' + s.add_runtime_dependency 'sass-rails', '>= 4.0.0' + s.add_runtime_dependency 'terminal-table', '>= 1.4' + s.add_runtime_dependency 'useragent', '>= 0.4' end diff --git a/db/migrate/20130809135400_create_core_schema.rb b/db/migrate/20130809135400_create_core_schema.rb index 57ddba69..8aec23e2 100644 --- a/db/migrate/20130809135400_create_core_schema.rb +++ b/db/migrate/20130809135400_create_core_schema.rb @@ -1,11 +1,11 @@ # In order to support pre-2.0 installations of CASino that included CASinoCore, # we must rebuild the un-namespaced CASinoCore schema so that we can upgrade -class CreateCoreSchema < ActiveRecord::Migration +class CreateCoreSchema < ActiveRecord::Migration[4.1] CoreTables = %w{login_tickets proxy_granting_tickets proxy_tickets service_rules service_tickets ticket_granting_tickets two_factor_authenticators users} def up CoreTables.each do |table_name| - if !ActiveRecord::Base.connection.table_exists? table_name + unless connection.data_source_exists? table_name send "create_#{table_name}" end end @@ -114,4 +114,4 @@ def create_users end add_index :users, [:authenticator, :username], :unique => true end -end \ No newline at end of file +end diff --git a/db/migrate/20130809135401_rename_base_models.rb b/db/migrate/20130809135401_rename_base_models.rb index c44c40cf..8d6fe406 100644 --- a/db/migrate/20130809135401_rename_base_models.rb +++ b/db/migrate/20130809135401_rename_base_models.rb @@ -1,4 +1,4 @@ -class RenameBaseModels < ActiveRecord::Migration +class RenameBaseModels < ActiveRecord::Migration[4.1] def up # Login Tickets rename_table :login_tickets, :casino_login_tickets diff --git a/db/migrate/20131022110146_cleanup_indexes.rb b/db/migrate/20131022110146_cleanup_indexes.rb index 0488cb8f..c267dd04 100644 --- a/db/migrate/20131022110146_cleanup_indexes.rb +++ b/db/migrate/20131022110146_cleanup_indexes.rb @@ -1,4 +1,4 @@ -class CleanupIndexes < ActiveRecord::Migration +class CleanupIndexes < ActiveRecord::Migration[4.1] def change # delete some leftovers in migrated CASino 1.x installations remove_deprecated_index_if_exists :login_tickets, [:ticket] diff --git a/db/migrate/20131022110246_fix_long_index_names.rb b/db/migrate/20131022110246_fix_long_index_names.rb index ba655754..1de923f6 100644 --- a/db/migrate/20131022110246_fix_long_index_names.rb +++ b/db/migrate/20131022110246_fix_long_index_names.rb @@ -1,4 +1,4 @@ -class FixLongIndexNames < ActiveRecord::Migration +class FixLongIndexNames < ActiveRecord::Migration[4.1] def change # Long names prevent us from doing some migrations, because the resulting # temporary index names would be longer than 64 characters: diff --git a/db/migrate/20131022110346_change_service_to_text.rb b/db/migrate/20131022110346_change_service_to_text.rb index 03352954..182c38fc 100644 --- a/db/migrate/20131022110346_change_service_to_text.rb +++ b/db/migrate/20131022110346_change_service_to_text.rb @@ -1,4 +1,4 @@ -class ChangeServiceToText < ActiveRecord::Migration +class ChangeServiceToText < ActiveRecord::Migration[4.1] def change change_column :casino_proxy_tickets, :service, :text change_column :casino_service_tickets, :service, :text diff --git a/db/migrate/20140821142611_change_user_agent_to_text.rb b/db/migrate/20140821142611_change_user_agent_to_text.rb index 89d7e432..deaad50f 100644 --- a/db/migrate/20140821142611_change_user_agent_to_text.rb +++ b/db/migrate/20140821142611_change_user_agent_to_text.rb @@ -1,4 +1,4 @@ -class ChangeUserAgentToText < ActiveRecord::Migration +class ChangeUserAgentToText < ActiveRecord::Migration[4.1] def change change_column :casino_ticket_granting_tickets, :user_agent, :text end diff --git a/db/migrate/20140827183611_fix_length_of_text_fields.rb b/db/migrate/20140827183611_fix_length_of_text_fields.rb index b9b38657..f6aac322 100644 --- a/db/migrate/20140827183611_fix_length_of_text_fields.rb +++ b/db/migrate/20140827183611_fix_length_of_text_fields.rb @@ -1,4 +1,4 @@ -class FixLengthOfTextFields < ActiveRecord::Migration +class FixLengthOfTextFields < ActiveRecord::Migration[4.1] def change change_column :casino_proxy_tickets, :service, :text, :limit => nil change_column :casino_service_tickets, :service, :text, :limit => nil diff --git a/db/migrate/20140831205255_create_auth_token_tickets.rb b/db/migrate/20140831205255_create_auth_token_tickets.rb index 5e6a0987..a1865e63 100644 --- a/db/migrate/20140831205255_create_auth_token_tickets.rb +++ b/db/migrate/20140831205255_create_auth_token_tickets.rb @@ -1,4 +1,4 @@ -class CreateAuthTokenTickets < ActiveRecord::Migration +class CreateAuthTokenTickets < ActiveRecord::Migration[4.1] def change create_table :casino_auth_token_tickets do |t| t.string :ticket, :null => false diff --git a/db/migrate/20151022192752_add_user_ip_to_ticket_granting_ticket.rb b/db/migrate/20151022192752_add_user_ip_to_ticket_granting_ticket.rb index 92b5a15f..011b75d6 100644 --- a/db/migrate/20151022192752_add_user_ip_to_ticket_granting_ticket.rb +++ b/db/migrate/20151022192752_add_user_ip_to_ticket_granting_ticket.rb @@ -1,4 +1,4 @@ -class AddUserIpToTicketGrantingTicket < ActiveRecord::Migration +class AddUserIpToTicketGrantingTicket < ActiveRecord::Migration[4.1] def up add_column :casino_ticket_granting_tickets, :user_ip, :string end diff --git a/db/migrate/20160502074450_create_login_attempts.rb b/db/migrate/20160502074450_create_login_attempts.rb index 802fe0c4..8b86c56c 100644 --- a/db/migrate/20160502074450_create_login_attempts.rb +++ b/db/migrate/20160502074450_create_login_attempts.rb @@ -1,4 +1,4 @@ -class CreateLoginAttempts < ActiveRecord::Migration +class CreateLoginAttempts < ActiveRecord::Migration[4.1] def change create_table :casino_login_attempts do |t| t.integer :user_id, null: true diff --git a/db/migrate/20160524121117_remove_username_from_login_attempts.rb b/db/migrate/20160524121117_remove_username_from_login_attempts.rb index d9a94bcd..a31063df 100644 --- a/db/migrate/20160524121117_remove_username_from_login_attempts.rb +++ b/db/migrate/20160524121117_remove_username_from_login_attempts.rb @@ -1,4 +1,4 @@ -class RemoveUsernameFromLoginAttempts < ActiveRecord::Migration +class RemoveUsernameFromLoginAttempts < ActiveRecord::Migration[4.1] def up remove_column :casino_login_attempts, :username change_column_null :casino_login_attempts, :user_id, false diff --git a/gemfiles/rails_5.0.gemfile b/gemfiles/rails_5.0.gemfile new file mode 100644 index 00000000..b7fc5e9e --- /dev/null +++ b/gemfiles/rails_5.0.gemfile @@ -0,0 +1,23 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "activerecord", "~> 5.0.0" +gem "rails-controller-testing" +gem "rspec-rails", ">= 3.5" + +group :test do + gem "appraisal", ">= 2.1" + gem "capybara", ">= 2.1" + gem "coveralls", ">= 0.7" + gem "factory_bot", ">= 4.1" + gem "rake", ">= 10.0" + gem "rspec-its", ">= 1.0" + gem "webmock", ">= 1.9" +end + +platforms :ruby do + gem "sqlite3", ">= 1.3" +end + +gemspec path: "../" diff --git a/gemfiles/rails_5.1.gemfile b/gemfiles/rails_5.1.gemfile new file mode 100644 index 00000000..19134c6f --- /dev/null +++ b/gemfiles/rails_5.1.gemfile @@ -0,0 +1,23 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "activerecord", "~> 5.1.0" +gem "rails-controller-testing" +gem "rspec-rails", ">= 3.5" + +group :test do + gem "appraisal", ">= 2.1" + gem "capybara", ">= 2.1" + gem "coveralls", ">= 0.7" + gem "factory_bot", ">= 4.1" + gem "rake", ">= 10.0" + gem "rspec-its", ">= 1.0" + gem "webmock", ">= 1.9" +end + +platforms :ruby do + gem "sqlite3", ">= 1.3" +end + +gemspec path: "../" diff --git a/lib/casino.rb b/lib/casino.rb index e15bac79..989a3d21 100644 --- a/lib/casino.rb +++ b/lib/casino.rb @@ -6,6 +6,7 @@ module CASino defaults = { authenticators: HashWithIndifferentAccess.new, + authenticator_context_builder: ->(params, request){ }, require_service_rules: false, logger: Rails.logger, frontend: HashWithIndifferentAccess.new( diff --git a/lib/casino/version.rb b/lib/casino/version.rb index 42e0204a..67c3a443 100644 --- a/lib/casino/version.rb +++ b/lib/casino/version.rb @@ -1,3 +1,3 @@ module CASino - VERSION = '4.1.2' + VERSION = '5.0.0'.freeze end diff --git a/lib/generators/casino/install/install_generator.rb b/lib/generators/casino/install/install_generator.rb index c2628277..16c10ea5 100644 --- a/lib/generators/casino/install/install_generator.rb +++ b/lib/generators/casino/install/install_generator.rb @@ -20,18 +20,18 @@ class InstallGenerator < Rails::Generators::Base def install_migrations return unless options['migration'] - rake 'casino:install:migrations' + generate 'casino:migration' end def copy_config_files return unless options['config_files'] copy_file 'cas.yml', 'config/cas.yml' - copy_file 'casino_and_overrides.scss', 'app/assets/stylesheets/casino_and_overrides.scss' + copy_file 'casino_and_overrides.scss', "app/assets/stylesheets/#{namespace_name}/casino_and_overrides.scss".squeeze('/') end def insert_assets_loader - insert_into_file 'app/assets/javascripts/application.js', :after => %r{//= require +['"]?jquery_ujs['"]?} do + insert_into_file "app/assets/javascripts/#{namespace_name}/application.js".squeeze('/'), :after => %r{//= require +['"]?jquery_ujs['"]?} do "\n//= require casino" end end @@ -43,5 +43,11 @@ def insert_engine_routes def show_readme readme 'README' end + + private + def namespace_name + Rails::Generators.namespace.to_s.underscore + end + end end diff --git a/lib/generators/casino/migration_generator.rb b/lib/generators/casino/migration_generator.rb new file mode 100644 index 00000000..868b43b9 --- /dev/null +++ b/lib/generators/casino/migration_generator.rb @@ -0,0 +1,24 @@ +require 'rails/generators/active_record' + +module CASino + class MigrationGenerator < ::Rails::Generators::Base + include Rails::Generators::Migration + source_root File.expand_path('../../../../db/migrate', __FILE__) + + namespace 'casino:migration' + + desc 'Installs CASino migration files.' + + def install + source_paths.each do |source_path| + Dir["#{source_path}/*.rb"].each do |filename| + migration_template File.basename(filename), "db/migrate/#{File.basename(filename).sub(/^\d+_/, '')}" + end + end + end + + def self.next_migration_number(dirname) + ActiveRecord::Generators::Base.next_migration_number(dirname) + end + end +end \ No newline at end of file diff --git a/spec/controllers/auth_tokens_controller_spec.rb b/spec/controllers/auth_tokens_controller_spec.rb index 3aade54d..1c95c5d6 100644 --- a/spec/controllers/auth_tokens_controller_spec.rb +++ b/spec/controllers/auth_tokens_controller_spec.rb @@ -1,10 +1,10 @@ require 'spec_helper' describe CASino::AuthTokensController do - include CASino::Engine.routes.url_helpers + routes { CASino::Engine.routes } - let(:params) { { } } - let(:request_options) { params.merge(use_route: :casino) } + let(:params) { {} } + let(:request_options) { {params: params} } before(:each) do CASino::AuthTokenValidationService.any_instance.stub(:validation_result).and_return(validation_result) @@ -17,7 +17,7 @@ let(:params) { { service: service } } it 'redirects to the login' do - get :login, request_options + get :login, **request_options response.should redirect_to(login_path(service: service)) end end @@ -27,14 +27,14 @@ context 'with a not allowed service' do before(:each) do - FactoryGirl.create :service_rule, :regex, url: '^https://.*' + FactoryBot.create :service_rule, :regex, url: '^https://.*' end let(:service) { 'http://www.example.org/' } let(:params) { { service: service } } it 'renders the service_not_allowed template' do - get :login, request_options + get :login, **request_options response.should render_template(:service_not_allowed) end end @@ -44,30 +44,30 @@ let(:params) { { service: service } } it 'redirects to the service' do - get :login, request_options + get :login, **request_options response.location.should =~ /^#{Regexp.escape service}\?ticket=ST-/ end it 'generates a service ticket' do lambda do - get :login, request_options + get :login, **request_options end.should change(CASino::ServiceTicket, :count).by(1) end end it 'creates a cookie' do - get :login, request_options + get :login, **request_options response.cookies['tgt'].should_not be_nil end it 'generates a ticket-granting ticket' do lambda do - get :login, request_options + get :login, **request_options end.should change(CASino::TicketGrantingTicket, :count).by(1) end it 'redirects to the session overview' do - get :login, request_options + get :login, **request_options response.should redirect_to(sessions_path) end end diff --git a/spec/controllers/login_attempts_controller_spec.rb b/spec/controllers/login_attempts_controller_spec.rb index 7ca62d98..613045fa 100644 --- a/spec/controllers/login_attempts_controller_spec.rb +++ b/spec/controllers/login_attempts_controller_spec.rb @@ -5,16 +5,16 @@ describe 'GET #index' do context 'with ticket granting ticket' do - let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket } - let(:login_attempt) { FactoryGirl.create :login_attempt, user: ticket_granting_ticket.user } + let(:ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket } + let(:login_attempt) { FactoryBot.create :login_attempt, user: ticket_granting_ticket.user } let(:old_login_attempt) do - FactoryGirl.create :login_attempt, user: ticket_granting_ticket.user, created_at: 10.weeks.ago + FactoryBot.create :login_attempt, user: ticket_granting_ticket.user, created_at: 10.weeks.ago end before do sign_in(ticket_granting_ticket) login_attempt.touch - FactoryGirl.create :login_attempt + FactoryBot.create :login_attempt end it 'assigns current users login attempts @login_attempts' do diff --git a/spec/controllers/proxy_tickets_controller_spec.rb b/spec/controllers/proxy_tickets_controller_spec.rb index ea79e0f5..e0bd7a32 100644 --- a/spec/controllers/proxy_tickets_controller_spec.rb +++ b/spec/controllers/proxy_tickets_controller_spec.rb @@ -1,10 +1,12 @@ require 'spec_helper' describe CASino::ProxyTicketsController do - let(:request_options) { params.merge(use_route: :casino) } + routes { CASino::Engine.routes } + + let(:request_options) { {params: params} } describe 'GET "proxyValidate"' do - let(:proxy_ticket) { FactoryGirl.create :proxy_ticket } + let(:proxy_ticket) { FactoryBot.create :proxy_ticket } let(:service) { proxy_ticket.service } let(:parameters) { { service: service, ticket: proxy_ticket.ticket }} let(:params) { parameters } @@ -17,12 +19,12 @@ let(:regex_proxy) { /\s*#{proxy_ticket.proxy_granting_ticket.pgt_url}<\/cas:proxy>\s*<\/cas:proxies>/ } it 'answers with the success text' do - get :proxy_validate, request_options + get :proxy_validate, **request_options response.body.should =~ regex_success end it 'includes the proxy in the response' do - get :proxy_validate, request_options + get :proxy_validate, **request_options response.body.should =~ regex_proxy end @@ -32,7 +34,7 @@ end it 'answers with the failure text' do - get :proxy_validate, request_options + get :proxy_validate, **request_options response.body.should =~ regex_failure end end @@ -41,7 +43,7 @@ let(:params) { parameters.merge(service: 'this_is_another_service') } it 'answers with the failure text' do - get :proxy_validate, request_options + get :proxy_validate, **request_options response.body.should =~ regex_failure end end @@ -50,7 +52,7 @@ let(:params) { { ticket: 'PT-1234', service: 'https://www.example.com/' } } it 'answers with the failure text' do - get :proxy_validate, request_options + get :proxy_validate, **request_options response.body.should =~ regex_failure end end @@ -65,13 +67,13 @@ context 'without proxy-granting ticket' do it 'answers with the failure text' do - get :create, request_options + get :create, **request_options response.body.should =~ regex_failure end it 'does not create a proxy ticket' do lambda do - get :create, request_options + get :create, **request_options end.should_not change(CASino::ProxyTicket, :count) end end @@ -80,34 +82,34 @@ let(:params) { parameters.merge(pgt: 'PGT-123453789') } it 'answers with the failure text' do - get :create, request_options + get :create, **request_options response.body.should =~ regex_failure end it 'does not create a proxy ticket' do lambda do - get :create, request_options + get :create, **request_options end.should_not change(CASino::ProxyTicket, :count) end end context 'with a proxy-granting ticket' do - let(:proxy_granting_ticket) { FactoryGirl.create :proxy_granting_ticket } + let(:proxy_granting_ticket) { FactoryBot.create :proxy_granting_ticket } let(:params) { parameters.merge(pgt: proxy_granting_ticket.ticket) } it 'answers with the success text' do - get :create, request_options + get :create, **request_options response.body.should =~ regex_success end it 'does create a proxy ticket' do lambda do - get :create, request_options + get :create, **request_options end.should change(proxy_granting_ticket.proxy_tickets, :count).by(1) end it 'includes the proxy ticket in the response' do - get :create, request_options + get :create, **request_options proxy_ticket = CASino::ProxyTicket.last response.body.should =~ /#{proxy_ticket.ticket}<\/cas:proxyTicket>/ end @@ -116,13 +118,13 @@ let(:params) { parameters.merge(pgt: proxy_granting_ticket.ticket, targetService: nil) } it 'answers with the failure text' do - get :create, request_options + get :create, **request_options response.body.should =~ regex_failure end it 'does not create a proxy ticket' do lambda do - get :create, request_options + get :create, **request_options end.should_not change(CASino::ProxyTicket, :count) end end diff --git a/spec/controllers/service_and_proxy_tickets_controller_spec.rb b/spec/controllers/service_and_proxy_tickets_controller_spec.rb index 64cdbbe1..c8fe72e0 100644 --- a/spec/controllers/service_and_proxy_tickets_controller_spec.rb +++ b/spec/controllers/service_and_proxy_tickets_controller_spec.rb @@ -1,9 +1,10 @@ require 'spec_helper' shared_examples_for 'a service ticket validator' do - include CASino::Engine.routes.url_helpers - let(:request_options) { params.merge(use_route: :casino) } - let(:service_ticket) { FactoryGirl.create :service_ticket } + routes { CASino::Engine.routes } + + let(:request_options) { {params: params} } + let(:service_ticket) { FactoryBot.create :service_ticket } let(:service) { service_ticket.service } let(:parameters) { { service: service, ticket: service_ticket.ticket }} let(:params) { parameters } @@ -20,7 +21,7 @@ context "without '#{missing_parameter}'" do it 'answers with the failure text' do - get validation_action, request_options + get validation_action, **request_options response.body.should =~ regex_failure end end @@ -34,7 +35,7 @@ end it 'includes the extra attributes' do - get validation_action, request_options + get validation_action, **request_options response.body.should =~ /1234<\/cas\:id\>/ end end @@ -45,7 +46,7 @@ end it 'includes all values' do - get validation_action, request_options + get validation_action, **request_options response.body.should =~ /test<\/cas\:memberOf\>/ response.body.should =~ /yolo<\/cas\:memberOf\>/ end @@ -57,19 +58,19 @@ end it 'includes the long-term flag in the answer' do - get validation_action, request_options + get validation_action, **request_options response.body.should =~ /true<\/cas\:longTermAuthenticationRequestTokenUsed>/ end end context 'without renew flag' do it 'consumes the service ticket' do - get validation_action, request_options + get validation_action, **request_options service_ticket.reload.consumed.should == true end it 'answers with the success text' do - get validation_action, request_options + get validation_action, **request_options response.body.should =~ regex_success end end @@ -78,7 +79,7 @@ let(:service) { "#{service_ticket.service}?" } it 'answers with the success text' do - get validation_action, request_options + get validation_action, **request_options response.body.should =~ regex_success end end @@ -88,12 +89,12 @@ context 'with a service ticket without issued_from_credentials flag' do it 'consumes the service ticket' do - get validation_action, request_options + get validation_action, **request_options service_ticket.reload.consumed.should == true end it 'answers with the failure text' do - get validation_action, request_options + get validation_action, **request_options response.body.should =~ regex_failure end end @@ -105,12 +106,12 @@ end it 'consumes the service ticket' do - get validation_action, request_options + get validation_action, **request_options service_ticket.reload.consumed.should == true end it 'answers with the success text' do - get validation_action, request_options + get validation_action, **request_options response.body.should =~ regex_success end end @@ -128,35 +129,35 @@ let(:pgt_url) { 'http://www.example.org' } it 'answers with the success text' do - get validation_action, request_options + get validation_action, **request_options response.body.should =~ regex_success end it 'does not create a proxy-granting ticket' do lambda do - get validation_action, request_options + get validation_action, **request_options end.should_not change(service_ticket.proxy_granting_tickets, :count) end end it 'answers with the success text' do - get validation_action, request_options + get validation_action, **request_options response.body.should =~ regex_success end it 'includes the PGTIOU in the response' do - get validation_action, request_options + get validation_action, **request_options response.body.should =~ /\\n?\s*PGTIOU-.+/ end it 'creates a proxy-granting ticket' do lambda do - get validation_action, request_options + get validation_action, **request_options end.should change(service_ticket.proxy_granting_tickets, :count).by(1) end it 'contacts the callback server' do - get validation_action, request_options + get validation_action, **request_options proxy_granting_ticket = CASino::ProxyGrantingTicket.last WebMock.should have_requested(:get, 'https://www.example.org').with(query: { pgtId: proxy_granting_ticket.ticket, @@ -170,13 +171,13 @@ end it 'answers with the success text' do - get validation_action, request_options + get validation_action, **request_options response.body.should =~ regex_success end it 'does not create a proxy-granting ticket' do lambda do - get validation_action, request_options + get validation_action, **request_options end.should_not change(service_ticket.proxy_granting_tickets, :count) end end @@ -187,13 +188,13 @@ end it 'answers with the success text' do - get validation_action, request_options + get validation_action, **request_options response.body.should =~ regex_success end it 'does not create a proxy-granting ticket' do lambda do - get validation_action, request_options + get validation_action, **request_options end.should_not change(service_ticket.proxy_granting_tickets, :count) end end @@ -206,7 +207,7 @@ end it 'answers with the failure text' do - get validation_action, request_options + get validation_action, **request_options response.body.should =~ regex_failure end end diff --git a/spec/controllers/service_tickets_controller_spec.rb b/spec/controllers/service_tickets_controller_spec.rb index e6ace6fc..6483ac70 100644 --- a/spec/controllers/service_tickets_controller_spec.rb +++ b/spec/controllers/service_tickets_controller_spec.rb @@ -1,7 +1,9 @@ describe CASino::ServiceTicketsController do + routes { CASino::Engine.routes } + describe 'GET "validate"' do - let(:request_options) { params.merge(use_route: :casino) } - let(:service_ticket) { FactoryGirl.create :service_ticket } + let(:request_options) { {params: params} } + let(:service_ticket) { FactoryBot.create :service_ticket } let(:service) { service_ticket.service } let(:parameters) { { service: service, ticket: service_ticket.ticket }} let(:params) { parameters } @@ -14,12 +16,12 @@ context 'with an unconsumed service ticket' do context 'without renew flag' do it 'consumes the service ticket' do - get :validate, request_options + get :validate, **request_options service_ticket.reload.consumed.should == true end it 'answers with the expected response text' do - get :validate, request_options + get :validate, **request_options response.body.should == response_text_success end end @@ -29,12 +31,12 @@ context 'with a service ticket without issued_from_credentials flag' do it 'consumes the service ticket' do - get :validate, request_options + get :validate, **request_options service_ticket.reload.consumed.should == true end it 'answers with the expected response text' do - get :validate, request_options + get :validate, **request_options response.body.should == response_text_failure end end @@ -45,12 +47,12 @@ end it 'consumes the service ticket' do - get :validate, request_options + get :validate, **request_options service_ticket.reload.consumed.should == true end it 'answers with the expected response text' do - get :validate, request_options + get :validate, **request_options response.body.should == response_text_success end end @@ -63,7 +65,7 @@ end it 'answers with the expected response text' do - get :validate, request_options + get :validate, **request_options response.body.should == response_text_failure end end diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index 79ecb3f8..a2e13dd3 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -5,8 +5,9 @@ routes { CASino::Engine.routes } - let(:params) { { } } - let(:user_agent) { 'YOLOBrowser 420.00'} + let(:params) { {} } + let(:request_options) { {params: params} } + let(:user_agent) { 'YOLOBrowser 420.00' } before(:each) do request.user_agent = user_agent @@ -15,21 +16,21 @@ describe 'GET "new"' do context 'with a not allowed service' do before(:each) do - FactoryGirl.create :service_rule, :regex, url: '^https://.*' + FactoryBot.create :service_rule, :regex, url: '^https://.*' end let(:service) { 'http://www.example.org/' } let(:params) { { service: service } } it 'renders the service_not_allowed template' do - get :new, params + get :new, **request_options response.should render_template(:service_not_allowed) end end context 'when logged out' do it 'renders the new template' do - get :new, params + get :new, **request_options response.should render_template(:new) end @@ -39,7 +40,7 @@ let(:params) { { service: service, gateway: 'true' } } it 'redirects to the service' do - get :new, params + get :new, **request_options response.should redirect_to(service) end end @@ -48,7 +49,7 @@ let(:params) { { gateway: 'true' } } it 'renders the new template' do - get :new, params + get :new, **request_options response.should render_template(:new) end end @@ -56,17 +57,17 @@ end context 'when logged in' do - let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket } + let(:ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket } before(:each) do sign_in(ticket_granting_ticket) end context 'when two-factor authentication is pending' do - let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket, :awaiting_two_factor_authentication } + let(:ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket, :awaiting_two_factor_authentication } it 'renders the new template' do - get :new, params + get :new, **request_options response.should render_template(:new) end end @@ -78,7 +79,7 @@ end it 'renders the new template' do - get :new, params + get :new, **request_options response.should render_template(:new) end end @@ -88,24 +89,24 @@ let(:params) { { service: service } } it 'redirects to the service' do - get :new, params + get :new, **request_options response.location.should =~ /^#{Regexp.escape service}\?ticket=ST-/ end it 'generates a service ticket' do - lambda do - get :new, params - end.should change(CASino::ServiceTicket, :count).by(1) + -> { get :new, **request_options }.should change(CASino::ServiceTicket, :count).by(1) end it 'does not set the issued_from_credentials flag on the service ticket' do - get :new, params + get :new, **request_options CASino::ServiceTicket.last.should_not be_issued_from_credentials end context 'with renew parameter' do + let(:params) { super().merge(renew: 'true') } + it 'renders the new template' do - get :new, params.merge(renew: 'true') + get :new, **request_options response.should render_template(:new) end end @@ -116,7 +117,7 @@ let(:params) { { service: service } } it 'does not remove the attributes' do - get :new, params + get :new, **request_options response.location.should =~ /^#{Regexp.escape service}&ticket=ST-/ end end @@ -126,21 +127,19 @@ let(:params) { { service: service } } it 'redirects to the session overview' do - get :new, params + get :new, **request_options response.should redirect_to(sessions_path) end end context 'without a service' do it 'redirects to the session overview' do - get :new, params + get :new, **request_options response.should redirect_to(sessions_path) end it 'does not generate a service ticket' do - lambda do - get :new, params - end.should change(CASino::ServiceTicket, :count).by(0) + -> { get :new, **request_options }.should change(CASino::ServiceTicket, :count).by(0) end context 'with a changed browser' do @@ -151,7 +150,7 @@ end it 'renders the new template' do - get :new, params + get :new, **request_options response.should render_template(:new) end end @@ -160,7 +159,7 @@ context 'with an unsupported format' do it 'sets the status code to 406' do - get :new, use_route: :casino, format: :xml + get :new, format: :xml response.status.should == 406 end end @@ -169,41 +168,41 @@ describe 'POST "create"' do context 'without a valid login ticket' do it 'renders the new template' do - post :create, params + post :create, **request_options response.should render_template(:new) end end context 'with an expired login ticket' do - let(:expired_login_ticket) { FactoryGirl.create :login_ticket, :expired } - let(:params) { { lt: expired_login_ticket.ticket }} + let(:expired_login_ticket) { FactoryBot.create :login_ticket, :expired } + let(:params) { { lt: expired_login_ticket.ticket } } it 'renders the new template' do - post :create, params + post :create, **request_options response.should render_template(:new) end end context 'with a valid login ticket' do - let(:login_ticket) { FactoryGirl.create :login_ticket } + let(:login_ticket) { FactoryBot.create :login_ticket } let(:username) { 'testuser' } - let(:params) { { lt: login_ticket.ticket, username: username, password: 'wrrooonnng' }} - let!(:user) { FactoryGirl.create :user, username: username } + let(:params) { { lt: login_ticket.ticket, username: username, password: 'wrrooonnng' } } + let!(:user) { FactoryBot.create :user, username: username } context 'with invalid credentials' do it 'renders the new template' do - post :create, params + post :create, **request_options response.should render_template(:new) end it 'creates session log' do expect do - post :create, params + post :create, **request_options end.to change { CASino::LoginAttempt.count }.by 1 end it 'assigns session log the correct attributes' do - post :create, params + post :create, **request_options expect(CASino::LoginAttempt.last.user).to eq user expect(CASino::LoginAttempt.last.successful).to eq false @@ -217,24 +216,24 @@ let(:params) { { lt: login_ticket.ticket, username: username, password: 'foobar123', service: service } } it 'creates a cookie' do - post :create, params + post :create, **request_options response.cookies['tgt'].should_not be_nil end it 'saves user_ip' do - post :create, params + post :create, **request_options tgt = CASino::TicketGrantingTicket.last tgt.user_ip.should == '0.0.0.0' end it 'creates session log' do expect do - post :create, params + post :create, **request_options end.to change { CASino::LoginAttempt.count }.by 1 end it 'assigns session log the correct attributes' do - post :create, params + post :create, **request_options expect(CASino::LoginAttempt.last.user.username).to eq username expect(CASino::LoginAttempt.last.successful).to eq true @@ -249,12 +248,12 @@ end it 'creates a cookie with an expiration date set' do - post :create, params + post :create, **request_options cookie_jar['tgt']['expires'].should be_kind_of(Time) end it 'creates a long-term ticket-granting ticket' do - post :create, params + post :create, **request_options tgt = CASino::TicketGrantingTicket.last tgt.long_term.should == true end @@ -262,22 +261,22 @@ context 'with two-factor authentication enabled' do let!(:user) { CASino::User.create! username: username, authenticator: authenticator } - let!(:two_factor_authenticator) { FactoryGirl.create :two_factor_authenticator, user: user } + let!(:two_factor_authenticator) { FactoryBot.create :two_factor_authenticator, user: user } it 'renders the validate_otp template' do - post :create, params + post :create, **request_options response.should render_template(:validate_otp) end end context 'with a not allowed service' do before(:each) do - FactoryGirl.create :service_rule, :regex, url: '^https://.*' + FactoryBot.create :service_rule, :regex, url: '^https://.*' end let(:service) { 'http://www.example.org/' } it 'renders the service_not_allowed template' do - post :create, params + post :create, **request_options response.should render_template(:service_not_allowed) end end @@ -290,7 +289,7 @@ end it 'renders the new template' do - post :create, params + post :create, **request_options response.should render_template(:new) end end @@ -299,25 +298,21 @@ let(:service) { nil } it 'redirects to the session overview' do - post :create, params + post :create, **request_options response.should redirect_to(sessions_path) end it 'generates a ticket-granting ticket' do - lambda do - post :create, params - end.should change(CASino::TicketGrantingTicket, :count).by(1) + -> { post :create, **request_options }.should change(CASino::TicketGrantingTicket, :count).by(1) end context 'when the user does not exist yet' do it 'generates exactly one user' do - lambda do - post :create, params - end.should change(CASino::User, :count).by(1) + -> { post :create, **request_options }.should change(CASino::User, :count).by(1) end it 'sets the users attributes' do - post :create, params + post :create, **request_options user = CASino::User.last user.username.should == username user.authenticator.should == authenticator @@ -328,14 +323,12 @@ let!(:user) { CASino::User.create! username: username, authenticator: authenticator } it 'does not regenerate the user' do - lambda do - post :create, params - end.should_not change(CASino::User, :count) + -> { post :create, **request_options }.should_not change(CASino::User, :count) end it 'updates the extra attributes' do lambda do - post :create, params + post :create, **request_options user.reload end.should change(user, :extra_attributes) end @@ -346,25 +339,21 @@ let(:service) { 'https://www.example.com' } it 'redirects to the service' do - post :create, params + post :create, **request_options response.location.should =~ /^#{Regexp.escape service}\/\?ticket=ST-/ end it 'generates a service ticket' do - lambda do - post :create, params - end.should change(CASino::ServiceTicket, :count).by(1) + -> { post :create, **request_options }.should change(CASino::ServiceTicket, :count).by(1) end it 'does set the issued_from_credentials flag on the service ticket' do - post :create, params + post :create, **request_options CASino::ServiceTicket.last.should be_issued_from_credentials end it 'generates a ticket-granting ticket' do - lambda do - post :create, params - end.should change(CASino::TicketGrantingTicket, :count).by(1) + -> { post :create, **request_options }.should change(CASino::TicketGrantingTicket, :count).by(1) end end end @@ -373,16 +362,16 @@ describe 'POST "validate_otp"' do context 'with an existing ticket-granting ticket' do - let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket, :awaiting_two_factor_authentication } + let(:ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket, :awaiting_two_factor_authentication } let(:user) { ticket_granting_ticket.user } let(:tgt) { ticket_granting_ticket.ticket } let(:user_agent) { ticket_granting_ticket.user_agent } let(:otp) { '123456' } let(:service) { 'http://www.example.com/testing' } - let(:params) { { tgt: tgt, otp: otp, service: service }} + let(:params) { { tgt: tgt, otp: otp, service: service } } context 'with an active authenticator' do - let!(:two_factor_authenticator) { FactoryGirl.create :two_factor_authenticator, user: user } + let!(:two_factor_authenticator) { FactoryBot.create :two_factor_authenticator, user: user } context 'with a valid OTP' do before(:each) do @@ -390,12 +379,12 @@ end it 'redirects to the service' do - post :validate_otp, params + post :validate_otp, **request_options response.location.should =~ /^#{Regexp.escape service}\?ticket=ST-/ end it 'does activate the ticket-granting ticket' do - post :validate_otp, params + post :validate_otp, **request_options ticket_granting_ticket.reload.should_not be_awaiting_two_factor_authentication end @@ -408,19 +397,19 @@ end it 'creates a cookie with an expiration date set' do - post :validate_otp, params + post :validate_otp, **request_options cookie_jar['tgt']['expires'].should be_kind_of(Time) end end context 'with a not allowed service' do before(:each) do - FactoryGirl.create :service_rule, :regex, url: '^https://.*' + FactoryBot.create :service_rule, :regex, url: '^https://.*' end let(:service) { 'http://www.example.org/' } it 'renders the service_not_allowed template' do - post :validate_otp, params + post :validate_otp, **request_options response.should render_template(:service_not_allowed) end end @@ -432,12 +421,12 @@ end it 'renders the validate_otp template' do - post :validate_otp, params + post :validate_otp, **request_options response.should render_template(:validate_otp) end it 'does not activate the ticket-granting ticket' do - post :validate_otp, params + post :validate_otp, **request_options ticket_granting_ticket.reload.should be_awaiting_two_factor_authentication end end @@ -446,7 +435,7 @@ context 'without a ticket-granting ticket' do it 'redirects to the login page' do - post :validate_otp, params + post :validate_otp, **request_options response.should redirect_to(login_path) end end @@ -454,22 +443,22 @@ describe 'GET "logout"' do let(:url) { nil } - let(:params) { { :url => url } } + let(:params) { { url: url } } context 'with an existing ticket-granting ticket' do - let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket } + let(:ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket } before(:each) do sign_in(ticket_granting_ticket) end it 'deletes the ticket-granting ticket' do - get :logout, params - CASino::TicketGrantingTicket.where(id: ticket_granting_ticket.id).first.should == nil + get :logout, **request_options + CASino::TicketGrantingTicket.where(id: ticket_granting_ticket.id).first.should.nil? end it 'renders the logout template' do - get :logout, params + get :logout, **request_options response.should render_template(:logout) end @@ -477,34 +466,34 @@ let(:url) { 'http://www.example.com' } it 'assigns the URL' do - get :logout, params + get :logout, **request_options assigns(:url).should == url end end context 'with a service' do - let(:params) { { :service => url } } + let(:params) { { service: url } } let(:url) { 'http://www.example.org' } context 'when whitelisted' do it 'redirects to the service' do - get :logout, params + get :logout, **request_options response.should redirect_to(url) end end context 'when not whitelisted' do before(:each) do - FactoryGirl.create :service_rule, :regex, url: '^https://.*' + FactoryBot.create :service_rule, :regex, url: '^https://.*' end it 'renders the logout template' do - get :logout, params + get :logout, **request_options response.should render_template(:logout) end it 'does not assign the URL' do - get :logout, params + get :logout, **request_options assigns(:url).should be_nil end end @@ -513,7 +502,7 @@ context 'without a ticket-granting ticket' do it 'renders the logout template' do - get :logout, params + get :logout, **request_options response.should render_template(:logout) end end @@ -526,67 +515,67 @@ end describe 'two-factor authenticator settings' do - let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket } + let(:ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket } let(:user) { ticket_granting_ticket.user } context 'without a two-factor authenticator registered' do it 'does not assign any two-factor authenticators' do - get :index, params + get :index, **request_options assigns(:two_factor_authenticators).should == [] end end context 'with an inactive two-factor authenticator' do - let!(:two_factor_authenticator) { FactoryGirl.create :two_factor_authenticator, :inactive, user: user } + let!(:two_factor_authenticator) { FactoryBot.create :two_factor_authenticator, :inactive, user: user } it 'does not assign any two-factor authenticators' do - get :index, params + get :index, **request_options assigns(:two_factor_authenticators).should == [] end end context 'with a two-factor authenticator registered' do - let(:two_factor_authenticator) { FactoryGirl.create :two_factor_authenticator, user: user } - let!(:other_two_factor_authenticator) { FactoryGirl.create :two_factor_authenticator } + let(:two_factor_authenticator) { FactoryBot.create :two_factor_authenticator, user: user } + let!(:other_two_factor_authenticator) { FactoryBot.create :two_factor_authenticator } it 'does assign the two-factor authenticator' do - get :index, params + get :index, **request_options assigns(:two_factor_authenticators).should == [two_factor_authenticator] end end end describe 'sessions overview' do - let!(:other_ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket } + let!(:other_ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket } let(:user) { other_ticket_granting_ticket.user } context 'as user owning the other ticket granting ticket' do - let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket, user: user } + let(:ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket, user: user } it 'assigns both ticket granting tickets' do - get :index, params + get :index, **request_options assigns(:ticket_granting_tickets).should == [ticket_granting_ticket, other_ticket_granting_ticket] end end context 'with a ticket-granting ticket with same username but different authenticator' do - let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket } + let(:ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket } let(:tgt) { ticket_granting_ticket.ticket } it 'does not assign the other ticket granting ticket' do - get :index, params + get :index, **request_options assigns(:ticket_granting_tickets).should == [ticket_granting_ticket] end end end describe 'last login attempts' do - let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket } + let(:ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket } let(:login_attempts) do 6.times.map do |counter| - FactoryGirl.create :login_attempt, user: ticket_granting_ticket.user, - created_at: counter.minutes.ago + FactoryBot.create :login_attempt, user: ticket_granting_ticket.user, + created_at: counter.minutes.ago end end @@ -597,7 +586,7 @@ end it 'assigns last five login attempts' do - get :index, params + get :index, **request_options expect(assigns(:login_attempts)).to eq login_attempts.sort_by(&:created_at).from(1).to(6).reverse end @@ -606,14 +595,14 @@ context 'without a ticket-granting ticket' do it 'redirects to the login page' do - get :index, params + get :index, **request_options response.should redirect_to(login_path) end end end describe 'DELETE "destroy"' do - let(:owner_ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket } + let(:owner_ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket } let(:user) { owner_ticket_granting_ticket.user } before(:each) do @@ -621,54 +610,48 @@ end context 'with an existing ticket-granting ticket' do - let!(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket, user: user } - let(:service_ticket) { FactoryGirl.create :service_ticket, ticket_granting_ticket: ticket_granting_ticket } - let(:consumed_service_ticket) { FactoryGirl.create :service_ticket, :consumed, ticket_granting_ticket: ticket_granting_ticket } + let!(:ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket, user: user } + let(:service_ticket) { FactoryBot.create :service_ticket, ticket_granting_ticket: ticket_granting_ticket } + let(:consumed_service_ticket) { FactoryBot.create :service_ticket, :consumed, ticket_granting_ticket: ticket_granting_ticket } let(:params) { { id: ticket_granting_ticket.id } } it 'deletes exactly one ticket-granting ticket' do - lambda do - delete :destroy, params - end.should change(CASino::TicketGrantingTicket, :count).by(-1) + -> { delete :destroy, **request_options }.should change(CASino::TicketGrantingTicket, :count).by(-1) end it 'deletes the ticket-granting ticket' do - delete :destroy, params + delete :destroy, **request_options CASino::TicketGrantingTicket.where(id: params[:id]).length.should == 0 end it 'redirects to the session overview' do - delete :destroy, params + delete :destroy, **request_options response.should redirect_to(sessions_path) end end context 'with an invalid ticket-granting ticket' do - let(:params) { { id: 99999 } } + let(:params) { { id: 99_999 } } it 'does not delete a ticket-granting ticket' do - lambda do - delete :destroy, params - end.should_not change(CASino::TicketGrantingTicket, :count) + -> { delete :destroy, **request_options }.should_not change(CASino::TicketGrantingTicket, :count) end it 'redirects to the session overview' do - delete :destroy, params + delete :destroy, **request_options response.should redirect_to(sessions_path) end end context 'when trying to delete ticket-granting ticket of another user' do - let!(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket } + let!(:ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket } let(:params) { { id: ticket_granting_ticket.id } } it 'does not delete a ticket-granting ticket' do - lambda do - delete :destroy, params - end.should_not change(CASino::TicketGrantingTicket, :count) + -> { delete :destroy, **request_options }.should_not change(CASino::TicketGrantingTicket, :count) end it 'redirects to the session overview' do - delete :destroy, params + delete :destroy, **request_options response.should redirect_to(sessions_path) end end @@ -676,26 +659,24 @@ describe 'GET "destroy_others"' do let(:url) { nil } - let(:params) { { :service => url } } + let(:params) { { service: url } } context 'with an existing ticket-granting ticket' do - let(:user) { FactoryGirl.create :user } - let!(:other_users_ticket_granting_tickets) { FactoryGirl.create_list :ticket_granting_ticket, 3 } - let!(:other_ticket_granting_tickets) { FactoryGirl.create_list :ticket_granting_ticket, 3, user: user } - let!(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket, user: user } + let(:user) { FactoryBot.create :user } + let!(:other_users_ticket_granting_tickets) { FactoryBot.create_list :ticket_granting_ticket, 3 } + let!(:other_ticket_granting_tickets) { FactoryBot.create_list :ticket_granting_ticket, 3, user: user } + let!(:ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket, user: user } before(:each) do sign_in(ticket_granting_ticket) end it 'deletes all other ticket-granting tickets' do - lambda do - get :destroy_others, params - end.should change(CASino::TicketGrantingTicket, :count).by(-3) + -> { get :destroy_others, **request_options }.should change(CASino::TicketGrantingTicket, :count).by(-3) end it 'redirects to the session overview' do - get :destroy_others, params + get :destroy_others, **request_options response.should redirect_to(sessions_path) end @@ -703,7 +684,7 @@ let(:url) { 'http://www.example.com' } it 'redirects to the service' do - get :destroy_others, params + get :destroy_others, **request_options response.should redirect_to(url) end end @@ -714,7 +695,7 @@ let(:url) { 'http://www.example.com' } it 'redirects to the service' do - get :destroy_others, params + get :destroy_others, **request_options response.should redirect_to(url) end end diff --git a/spec/controllers/two_factor_authenticators_controller_spec.rb b/spec/controllers/two_factor_authenticators_controller_spec.rb index 6587a882..386bb1d4 100644 --- a/spec/controllers/two_factor_authenticators_controller_spec.rb +++ b/spec/controllers/two_factor_authenticators_controller_spec.rb @@ -1,13 +1,14 @@ require 'spec_helper' describe CASino::TwoFactorAuthenticatorsController do - include CASino::Engine.routes.url_helpers - let(:params) { { } } - let(:request_options) { params.merge(use_route: :casino) } + routes { CASino::Engine.routes } + + let(:params) { Hash.new } + let(:request_options) { {params: params} } describe 'GET "new"' do context 'with an existing ticket-granting ticket' do - let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket } + let(:ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket } let(:user) { ticket_granting_ticket.user } let(:user_agent) { ticket_granting_ticket.user_agent } @@ -17,22 +18,22 @@ it 'creates exactly one authenticator' do lambda do - get :new, request_options + get :new, **request_options end.should change(CASino::TwoFactorAuthenticator, :count).by(1) end it 'assigns the two_factor_authenticator' do - get :new, request_options + get :new, **request_options assigns(:two_factor_authenticator).should be_kind_of(CASino::TwoFactorAuthenticator) end it 'creates an inactive two-factor authenticator' do - get :new, request_options + get :new, **request_options CASino::TwoFactorAuthenticator.last.should_not be_active end it 'renders the new template' do - get :new, request_options + get :new, **request_options response.should render_template(:new) end @@ -44,7 +45,7 @@ render_views it 'renders the new template' do - get :new, request_options + get :new, **request_options response.should render_template(:new) end end @@ -52,7 +53,7 @@ context 'without a ticket-granting ticket' do it 'redirects to the login page' do - get :new, request_options + get :new, **request_options response.should redirect_to(login_path) end end @@ -60,7 +61,7 @@ describe 'POST "create"' do context 'with an existing ticket-granting ticket' do - let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket } + let(:ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket } let(:user) { ticket_granting_ticket.user } let(:id) { two_factor_authenticator.id } let(:otp) { '123456' } @@ -72,7 +73,7 @@ context 'with an invalid authenticator' do context 'with an expired authenticator' do - let(:two_factor_authenticator) { FactoryGirl.create :two_factor_authenticator, :inactive, user: user } + let(:two_factor_authenticator) { FactoryBot.create :two_factor_authenticator, :inactive, user: user } before(:each) do two_factor_authenticator.created_at = 10.hours.ago @@ -80,18 +81,18 @@ end it 'redirects to the two-factor authenticator new page' do - post :create, request_options + post :create, **request_options response.should redirect_to(new_two_factor_authenticator_path) end it 'adds a error message' do - post :create, request_options + post :create, **request_options flash[:error].should == I18n.t('two_factor_authenticators.invalid_two_factor_authenticator') end end context 'with a authenticator of another user' do - let(:two_factor_authenticator) { FactoryGirl.create :two_factor_authenticator, :inactive } + let(:two_factor_authenticator) { FactoryBot.create :two_factor_authenticator, :inactive } before(:each) do two_factor_authenticator.created_at = 10.hours.ago @@ -99,14 +100,14 @@ end it 'redirects to the two-factor authenticator new page' do - post :create, request_options + post :create, **request_options response.should redirect_to(new_two_factor_authenticator_path) end end end context 'with a valid authenticator' do - let(:two_factor_authenticator) { FactoryGirl.create :two_factor_authenticator, :inactive, user: user } + let(:two_factor_authenticator) { FactoryBot.create :two_factor_authenticator, :inactive, user: user } context 'with a valid OTP' do before(:each) do @@ -114,30 +115,30 @@ end it 'redirects to the session overview' do - post :create, request_options + post :create, **request_options response.should redirect_to(sessions_path) end it 'adds a notice' do - post :create, request_options + post :create, **request_options flash[:notice].should == I18n.t('two_factor_authenticators.successfully_activated') end it 'does activate the authenticator' do - post :create, request_options + post :create, **request_options two_factor_authenticator.reload.should be_active end context 'when another two-factor authenticator was active' do - let!(:other_two_factor_authenticator) { FactoryGirl.create :two_factor_authenticator, user: user } + let!(:other_two_factor_authenticator) { FactoryBot.create :two_factor_authenticator, user: user } it 'does activate the authenticator' do - post :create, request_options + post :create, **request_options two_factor_authenticator.reload.should be_active end it 'does delete the other authenticator' do - post :create, request_options + post :create, **request_options lambda do other_two_factor_authenticator.reload end.should raise_error(ActiveRecord::RecordNotFound) @@ -152,22 +153,22 @@ end it 'rerenders the new page' do - post :create, request_options + post :create, **request_options response.should render_template(:new) end it 'adds a error message' do - post :create, request_options + post :create, **request_options flash[:error].should == I18n.t('two_factor_authenticators.invalid_one_time_password') end it 'assigns the two-factor authenticator' do - post :create, request_options + post :create, **request_options assigns(:two_factor_authenticator).should be_kind_of(CASino::TwoFactorAuthenticator) end it 'does not activate the authenticator' do - post :create, request_options + post :create, **request_options two_factor_authenticator.reload.should_not be_active end end @@ -176,7 +177,7 @@ context 'without a ticket-granting ticket' do it 'redirects to the login page' do - post :create, request_options + post :create, **request_options response.should redirect_to(login_path) end end @@ -184,7 +185,7 @@ describe 'DELETE "destroy"' do context 'with an existing ticket-granting ticket' do - let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket } + let(:ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket } let(:user) { ticket_granting_ticket.user } let(:params) { { id: two_factor_authenticator.id } } @@ -193,21 +194,21 @@ end context 'with a valid two-factor authenticator' do - let!(:two_factor_authenticator) { FactoryGirl.create :two_factor_authenticator, user: user } - let!(:other_two_factor_authenticator) { FactoryGirl.create :two_factor_authenticator } + let!(:two_factor_authenticator) { FactoryBot.create :two_factor_authenticator, user: user } + let!(:other_two_factor_authenticator) { FactoryBot.create :two_factor_authenticator } it 'redirects to the session overview' do - delete :destroy, request_options + delete :destroy, **request_options response.should redirect_to(sessions_path) end it 'adds a notice' do - delete :destroy, request_options + delete :destroy, **request_options flash[:notice].should == I18n.t('two_factor_authenticators.successfully_deleted') end it 'deletes the two-factor authenticator' do - delete :destroy, request_options + delete :destroy, **request_options lambda do two_factor_authenticator.reload end.should raise_error(ActiveRecord::RecordNotFound) @@ -215,30 +216,32 @@ it 'does not delete other two-factor authenticators' do lambda do - delete :destroy, request_options + delete :destroy, **request_options end.should change(CASino::TwoFactorAuthenticator, :count).by(-1) end end context 'with a two-factor authenticator of another user' do - let!(:two_factor_authenticator) { FactoryGirl.create :two_factor_authenticator } + let!(:two_factor_authenticator) { FactoryBot.create :two_factor_authenticator } it 'redirects to the session overview' do - delete :destroy, request_options + delete :destroy, **request_options response.should redirect_to(sessions_path) end it 'does not delete two-factor authenticators' do lambda do - delete :destroy, request_options + delete :destroy, **request_options end.should_not change(CASino::TwoFactorAuthenticator, :count) end end end context 'without a ticket-granting ticket' do + let(:params) { { id: 0 } } + it 'redirects to the login page' do - delete :destroy, request_options + delete :destroy, **request_options response.should redirect_to(login_path) end end diff --git a/spec/dummy/app/controllers/application_controller.rb b/spec/dummy/app/controllers/application_controller.rb index e8065d95..ae44c518 100644 --- a/spec/dummy/app/controllers/application_controller.rb +++ b/spec/dummy/app/controllers/application_controller.rb @@ -1,3 +1,3 @@ class ApplicationController < ActionController::Base - protect_from_forgery + protect_from_forgery prepend: true end diff --git a/spec/dummy/bin/bundle b/spec/dummy/bin/bundle new file mode 100755 index 00000000..66e9889e --- /dev/null +++ b/spec/dummy/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/spec/dummy/bin/rails b/spec/dummy/bin/rails new file mode 100755 index 00000000..5191e692 --- /dev/null +++ b/spec/dummy/bin/rails @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +APP_PATH = File.expand_path('../../config/application', __FILE__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/spec/dummy/bin/rake b/spec/dummy/bin/rake new file mode 100755 index 00000000..17240489 --- /dev/null +++ b/spec/dummy/bin/rake @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/spec/dummy/bin/setup b/spec/dummy/bin/setup new file mode 100755 index 00000000..acdb2c13 --- /dev/null +++ b/spec/dummy/bin/setup @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +require 'pathname' + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +Dir.chdir APP_ROOT do + # This script is a starting point to setup your application. + # Add necessary setup steps to this file: + + puts "== Installing dependencies ==" + system "gem install bundler --conservative" + system "bundle check || bundle install" + + # puts "\n== Copying sample files ==" + # unless File.exist?("config/database.yml") + # system "cp config/database.yml.sample config/database.yml" + # end + + puts "\n== Preparing database ==" + system "bin/rake db:setup" + + puts "\n== Removing old logs and tempfiles ==" + system "rm -f log/*" + system "rm -rf tmp/cache" + + puts "\n== Restarting application server ==" + system "touch tmp/restart.txt" +end diff --git a/spec/dummy/config/application.rb b/spec/dummy/config/application.rb index db67e81f..0c65f4b3 100644 --- a/spec/dummy/config/application.rb +++ b/spec/dummy/config/application.rb @@ -2,9 +2,9 @@ require 'rails/all' -Bundler.require -require 'sass-rails' -require 'casino' +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) module Dummy class Application < Rails::Application @@ -12,16 +12,6 @@ class Application < Rails::Application # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. - # Custom directories with classes and modules you want to be autoloadable. - # config.autoload_paths += %W(#{config.root}/extras) - - # Only load the plugins named here, in the order given (default is alphabetical). - # :all can be used as a placeholder for all plugins not explicitly named. - # config.plugins = [ :exception_notification, :ssl_requirement, :all ] - - # Activate observers that should always be running. - # config.active_record.observers = :cacher, :garbage_collector, :forum_observer - # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. # config.time_zone = 'Central Time (US & Canada)' @@ -30,25 +20,7 @@ class Application < Rails::Application # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.default_locale = :de - # Configure the default encoding used in templates for Ruby 1.9. - config.encoding = "utf-8" - - # Configure sensitive parameters which will be filtered from the log file. - config.filter_parameters += [:password] - - # Enable escaping HTML in JSON. - config.active_support.escape_html_entities_in_json = true - - # Use SQL instead of Active Record's schema dumper when creating the database. - # This is necessary if your schema can't be completely dumped by the schema dumper, - # like if you have constraints or database-specific column types - # config.active_record.schema_format = :sql - - # Enable the asset pipeline - config.assets.enabled = true - - # Version of your assets, change this if you want to expire all your assets - config.assets.version = '1.0' + # Do not swallow errors in after_commit/after_rollback callbacks. + # config.active_record.raise_in_transactional_callbacks = true end end - diff --git a/spec/dummy/config/boot.rb b/spec/dummy/config/boot.rb index eba06813..6b750f00 100644 --- a/spec/dummy/config/boot.rb +++ b/spec/dummy/config/boot.rb @@ -1,10 +1,3 @@ -require 'rubygems' -gemfile = File.expand_path('../../../../Gemfile', __FILE__) +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) -if File.exist?(gemfile) - ENV['BUNDLE_GEMFILE'] = gemfile - require 'bundler' - Bundler.setup -end - -$:.unshift File.expand_path('../../../../lib', __FILE__) \ No newline at end of file +require 'bundler/setup' # Set up gems listed in the Gemfile. diff --git a/spec/dummy/config/environment.rb b/spec/dummy/config/environment.rb index 3da5eb91..ee8d90dc 100644 --- a/spec/dummy/config/environment.rb +++ b/spec/dummy/config/environment.rb @@ -1,5 +1,5 @@ -# Load the rails application +# Load the Rails application. require File.expand_path('../application', __FILE__) -# Initialize the rails application -Dummy::Application.initialize! +# Initialize the Rails application. +Rails.application.initialize! diff --git a/spec/dummy/config/environments/development.rb b/spec/dummy/config/environments/development.rb index 19920c4a..b55e2144 100644 --- a/spec/dummy/config/environments/development.rb +++ b/spec/dummy/config/environments/development.rb @@ -1,30 +1,41 @@ -Dummy::Application.configure do - # Settings specified here will take precedence over those in config/application.rb +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. config.cache_classes = false - # Log error messages when you accidentally call methods on nil. - config.whiny_nils = true + # Do not eager load code on boot. + config.eager_load = false - # Show full error reports and disable caching + # Show full error reports and disable caching. config.consider_all_requests_local = true config.action_controller.perform_caching = false - # Don't care if the mailer can't send + # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false - # Print deprecation notices to the Rails logger + # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log - # Only use best-standards-support built into browsers - config.action_dispatch.best_standards_support = :builtin + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load - # Do not compress assets - config.assets.compress = false - - # Expands the lines which load the assets + # Debug mode disables concatenation and preprocessing of assets. + # This option may cause significant delays in view rendering with a large + # number of complex assets. config.assets.debug = true + + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. + config.assets.digest = true + + # Adds additional error checking when serving assets at runtime. + # Checks for improperly declared sprockets dependencies. + # Raises helpful error messages. + config.assets.raise_runtime_errors = true + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true end diff --git a/spec/dummy/config/environments/production.rb b/spec/dummy/config/environments/production.rb index bdac56a7..5580b3cd 100644 --- a/spec/dummy/config/environments/production.rb +++ b/spec/dummy/config/environments/production.rb @@ -1,67 +1,79 @@ -Dummy::Application.configure do - # Settings specified here will take precedence over those in config/application.rb +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. - # Code is not reloaded between requests + # Code is not reloaded between requests. config.cache_classes = true - # Full error reports are disabled and caching is turned on + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. config.consider_all_requests_local = false config.action_controller.perform_caching = true - # Disable Rails's static asset server (Apache or nginx will already do this) - config.serve_static_assets = false + # Enable Rack::Cache to put a simple HTTP cache in front of your application + # Add `rack-cache` to your Gemfile before enabling this. + # For large-scale production use, consider using a caching reverse proxy like + # NGINX, varnish or squid. + # config.action_dispatch.rack_cache = true + + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + # config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? - # Compress JavaScripts and CSS - config.assets.compress = true + # Compress JavaScripts and CSS. + config.assets.js_compressor = :uglifier + # config.assets.css_compressor = :sass - # Don't fallback to assets pipeline if a precompiled asset is missed + # Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = false - # Generate digests for assets URLs + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. config.assets.digest = true - # Defaults to nil and saved in location specified by config.assets.prefix - # config.assets.manifest = YOUR_PATH + # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb - # Specifies the header that your server uses for sending files - # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache - # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true - # See everything in the log (default is :info) - # config.log_level = :debug + # Use the lowest log level to ensure availability of diagnostic information + # when problems arise. + config.log_level = :debug - # Prepend all log lines with the following tags + # Prepend all log lines with the following tags. # config.log_tags = [ :subdomain, :uuid ] - # Use a different logger for distributed setups + # Use a different logger for distributed setups. # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) - # Use a different cache store in production + # Use a different cache store in production. # config.cache_store = :mem_cache_store - # Enable serving of images, stylesheets, and JavaScripts from an asset server - # config.action_controller.asset_host = "http://assets.example.com" - - # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) - # config.assets.precompile += %w( search.js ) + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.action_controller.asset_host = 'http://assets.example.com' - # Disable delivery errors, bad email addresses will be ignored + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. # config.action_mailer.raise_delivery_errors = false - # Enable threaded mode - # config.threadsafe! - # Enable locale fallbacks for I18n (makes lookups for any locale fall back to - # the I18n.default_locale when a translation can not be found) + # the I18n.default_locale when a translation cannot be found). config.i18n.fallbacks = true - # Send deprecation notices to registered listeners + # Send deprecation notices to registered listeners. config.active_support.deprecation = :notify - # Log the query plan for queries taking more than this (works - # with SQLite, MySQL, and PostgreSQL) - # config.active_record.auto_explain_threshold_in_seconds = 0.5 + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false end diff --git a/spec/dummy/config/environments/test.rb b/spec/dummy/config/environments/test.rb index 6954c02f..1e09ecab 100644 --- a/spec/dummy/config/environments/test.rb +++ b/spec/dummy/config/environments/test.rb @@ -1,5 +1,5 @@ -Dummy::Application.configure do - # Settings specified here will take precedence over those in config/application.rb +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. # The test environment is used exclusively to run your application's # test suite. You never need to work with it otherwise. Remember that @@ -7,27 +7,36 @@ # and recreated between test runs. Don't rely on the data there! config.cache_classes = true + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. config.eager_load = false - # Configure static asset server for tests with Cache-Control for performance - config.serve_static_assets = true - config.static_cache_control = "public, max-age=3600" + # Configure static file server for tests with Cache-Control for performance. + # config.serve_static_files = true + # config.static_cache_control = 'public, max-age=3600' - # Show full error reports and disable caching + # Show full error reports and disable caching. config.consider_all_requests_local = true config.action_controller.perform_caching = false - # Raise exceptions instead of rendering exception templates + # Raise exceptions instead of rendering exception templates. config.action_dispatch.show_exceptions = false - # Disable request forgery protection in test environment - config.action_controller.allow_forgery_protection = false + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false # Tell Action Mailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test - # Print deprecation notices to the stderr + # Randomize the order test cases are executed. + config.active_support.test_order = :random + + # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true end diff --git a/spec/dummy/config/initializers/assets.rb b/spec/dummy/config/initializers/assets.rb new file mode 100644 index 00000000..01ef3e66 --- /dev/null +++ b/spec/dummy/config/initializers/assets.rb @@ -0,0 +1,11 @@ +# Be sure to restart your server when you modify this file. + +# Version of your assets, change this if you want to expire all your assets. +Rails.application.config.assets.version = '1.0' + +# Add additional assets to the asset load path +# Rails.application.config.assets.paths << Emoji.images_path + +# Precompile additional assets. +# application.js, application.css, and all non-JS/CSS in app/assets folder are already added. +# Rails.application.config.assets.precompile += %w( search.js ) diff --git a/spec/dummy/config/initializers/cookies_serializer.rb b/spec/dummy/config/initializers/cookies_serializer.rb new file mode 100644 index 00000000..ac5f8b66 --- /dev/null +++ b/spec/dummy/config/initializers/cookies_serializer.rb @@ -0,0 +1,3 @@ +# Be sure to restart your server when you modify this file. + +Rails.application.config.action_dispatch.cookies_serializer = :marshal diff --git a/spec/dummy/config/initializers/filter_parameter_logging.rb b/spec/dummy/config/initializers/filter_parameter_logging.rb new file mode 100644 index 00000000..4a994e1e --- /dev/null +++ b/spec/dummy/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Configure sensitive parameters which will be filtered from the log file. +Rails.application.config.filter_parameters += [:password] diff --git a/spec/dummy/config/initializers/inflections.rb b/spec/dummy/config/initializers/inflections.rb index 5d8d9be2..ac033bf9 100644 --- a/spec/dummy/config/initializers/inflections.rb +++ b/spec/dummy/config/initializers/inflections.rb @@ -1,15 +1,16 @@ # Be sure to restart your server when you modify this file. -# Add new inflection rules using the following format -# (all these examples are active by default): -# ActiveSupport::Inflector.inflections do |inflect| +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| # inflect.plural /^(ox)$/i, '\1en' # inflect.singular /^(ox)en/i, '\1' # inflect.irregular 'person', 'people' # inflect.uncountable %w( fish sheep ) # end -# + # These inflection rules are supported but not enabled by default: -# ActiveSupport::Inflector.inflections do |inflect| +# ActiveSupport::Inflector.inflections(:en) do |inflect| # inflect.acronym 'RESTful' # end diff --git a/spec/dummy/config/initializers/mime_types.rb b/spec/dummy/config/initializers/mime_types.rb index 72aca7e4..dc189968 100644 --- a/spec/dummy/config/initializers/mime_types.rb +++ b/spec/dummy/config/initializers/mime_types.rb @@ -2,4 +2,3 @@ # Add new mime types for use in respond_to blocks: # Mime::Type.register "text/richtext", :rtf -# Mime::Type.register_alias "text/html", :iphone diff --git a/spec/dummy/config/initializers/session_store.rb b/spec/dummy/config/initializers/session_store.rb index 952473ff..e766b67b 100644 --- a/spec/dummy/config/initializers/session_store.rb +++ b/spec/dummy/config/initializers/session_store.rb @@ -1,8 +1,3 @@ # Be sure to restart your server when you modify this file. -Dummy::Application.config.session_store :cookie_store, key: '_dummy_session' - -# Use the database for sessions instead of the cookie-based default, -# which shouldn't be used to store highly confidential information -# (create the session table with "rails generate session_migration") -# Dummy::Application.config.session_store :active_record_store +Rails.application.config.session_store :cookie_store, key: '_dummy_session' diff --git a/spec/dummy/config/initializers/wrap_parameters.rb b/spec/dummy/config/initializers/wrap_parameters.rb index 999df201..33725e95 100644 --- a/spec/dummy/config/initializers/wrap_parameters.rb +++ b/spec/dummy/config/initializers/wrap_parameters.rb @@ -1,14 +1,14 @@ # Be sure to restart your server when you modify this file. -# + # This file contains settings for ActionController::ParamsWrapper which # is enabled by default. # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. ActiveSupport.on_load(:action_controller) do - wrap_parameters format: [:json] + wrap_parameters format: [:json] if respond_to?(:wrap_parameters) end -# Disable root element in JSON by default. -ActiveSupport.on_load(:active_record) do - self.include_root_in_json = false -end +# To enable root element in JSON for ActiveRecord objects. +# ActiveSupport.on_load(:active_record) do +# self.include_root_in_json = true +# end diff --git a/spec/dummy/config/locales/en.yml b/spec/dummy/config/locales/en.yml index 179c14ca..06539571 100644 --- a/spec/dummy/config/locales/en.yml +++ b/spec/dummy/config/locales/en.yml @@ -1,5 +1,23 @@ -# Sample localization file for English. Add more files in this directory for other locales. -# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. +# Files in the config/locales directory are used for internationalization +# and are automatically loaded by Rails. If you want to use locales other +# than English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t 'hello' +# +# In views, this is aliased to just `t`: +# +# <%= t('hello') %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# To learn more, please read the Rails Internationalization guide +# available at http://guides.rubyonrails.org/i18n.html. en: hello: "Hello world" diff --git a/spec/dummy/config/routes.rb b/spec/dummy/config/routes.rb index 70603503..98780b10 100644 --- a/spec/dummy/config/routes.rb +++ b/spec/dummy/config/routes.rb @@ -1,3 +1,3 @@ -Dummy::Application.routes.draw do +Rails.application.routes.draw do mount CASino::Engine => '/', :as => 'casino' end diff --git a/spec/dummy/config/secrets.yml b/spec/dummy/config/secrets.yml new file mode 100644 index 00000000..e06d20b4 --- /dev/null +++ b/spec/dummy/config/secrets.yml @@ -0,0 +1,22 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key is used for verifying the integrity of signed cookies. +# If you change this key, all old signed cookies will become invalid! + +# Make sure the secret is at least 30 characters and all random, +# no regular words or you'll be exposed to dictionary attacks. +# You can use `rake secret` to generate a secure secret key. + +# Make sure the secrets in this file are kept private +# if you're sharing your code publicly. + +development: + secret_key_base: 7463dad7369a8af3bad6686dc147bdb2d383cc46774039841a4b957fee7d56e138b109cfd4ac152a6efebf77514013b1c8518fe75c4bf4e4e4711954d008555f + +test: + secret_key_base: b2b4f2373d4d9b941719a61a402cd239c279324aeb073f090d181c381d6fd347d86c0b67114ebf376ad80f6e565ffcd3eefdca7de615e2b40c2846fc4f546865 + +# Do not keep production secrets in the repository, +# instead read values from the environment. +production: + secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> diff --git a/spec/features/login_attempts_spec.rb b/spec/features/login_attempts_spec.rb index 7a2da775..59588b5e 100644 --- a/spec/features/login_attempts_spec.rb +++ b/spec/features/login_attempts_spec.rb @@ -7,7 +7,7 @@ context 'when logged in' do let(:login_attempt) do - FactoryGirl.create :login_attempt, created_at: Time.zone.parse('2015-01-01 09:10'), + FactoryBot.create :login_attempt, created_at: Time.zone.parse('2015-01-01 09:10'), user: CASino::User.first end diff --git a/spec/features/session_overview_spec.rb b/spec/features/session_overview_spec.rb index ebe2db83..b1e42a3f 100644 --- a/spec/features/session_overview_spec.rb +++ b/spec/features/session_overview_spec.rb @@ -7,7 +7,7 @@ context 'when logged in' do let(:login_attempt) do - FactoryGirl.create :login_attempt, created_at: Time.zone.parse('2015-01-01 09:10'), + FactoryBot.create :login_attempt, created_at: Time.zone.parse('2015-01-01 09:10'), user: CASino::User.first end diff --git a/spec/model/auth_token_ticket_spec.rb b/spec/model/auth_token_ticket_spec.rb index b883b81a..b0065eb5 100644 --- a/spec/model/auth_token_ticket_spec.rb +++ b/spec/model/auth_token_ticket_spec.rb @@ -17,7 +17,7 @@ describe '#to_s' do it 'returns the ticket identifier' do ticket = described_class.new ticket: 'ATT-12345' - "#{ticket}".should == ticket.ticket + ticket.to_s.should == ticket.ticket end end end diff --git a/spec/model/login_ticket_spec.rb b/spec/model/login_ticket_spec.rb index 8c7d77a8..fe77e7cf 100644 --- a/spec/model/login_ticket_spec.rb +++ b/spec/model/login_ticket_spec.rb @@ -17,7 +17,7 @@ describe '#to_s' do it 'returns the ticket identifier' do ticket = described_class.new ticket: 'LT-12345' - "#{ticket}".should == ticket.ticket + ticket.to_s.should == ticket.ticket end end end diff --git a/spec/model/proxy_ticket_spec.rb b/spec/model/proxy_ticket_spec.rb index 5090524f..20151b8a 100644 --- a/spec/model/proxy_ticket_spec.rb +++ b/spec/model/proxy_ticket_spec.rb @@ -1,21 +1,21 @@ require 'spec_helper' describe CASino::ProxyTicket do - let(:unconsumed_ticket) { + let(:unconsumed_ticket) do ticket = described_class.new ticket: 'PT-12345', service: 'any_string_is_valid' ticket.proxy_granting_ticket_id = 1 ticket - } - let(:consumed_ticket) { + end + let(:consumed_ticket) do ticket = described_class.new ticket: 'PT-54321', service: 'any_string_is_valid' ticket.proxy_granting_ticket_id = 1 ticket.consumed = true ticket.save! ticket - } + end describe '#expired?' do - [:unconsumed, :consumed].each do |state| + %i[unconsumed consumed].each do |state| context "with an #{state} ticket" do let(:ticket) { send("#{state}_ticket") } diff --git a/spec/model/service_rule_spec.rb b/spec/model/service_rule_spec.rb index 2f3fe47f..b0dac03f 100644 --- a/spec/model/service_rule_spec.rb +++ b/spec/model/service_rule_spec.rb @@ -26,7 +26,7 @@ context 'with a regex rule' do before(:each) do - FactoryGirl.create :service_rule, :regex, url: '^https://.*' + FactoryBot.create :service_rule, :regex, url: '^https://.*' end ['https://www.example.org/', 'https://www.google.com/'].each do |service_url| @@ -45,7 +45,7 @@ context 'with many regex rules' do before(:each) do 100.times do |counter| - FactoryGirl.create :service_rule, :regex, url: "^https://www#{counter}.example.com" + FactoryBot.create :service_rule, :regex, url: "^https://www#{counter}.example.com" end end @@ -60,7 +60,7 @@ context 'with a non-regex rule' do before(:each) do - FactoryGirl.create :service_rule, url: 'https://www.google.com/foo' + FactoryBot.create :service_rule, url: 'https://www.google.com/foo' end ['https://www.google.com/foo'].each do |service_url| diff --git a/spec/model/service_ticket/single_sign_out_notifier_spec.rb b/spec/model/service_ticket/single_sign_out_notifier_spec.rb index c1b138af..9aee1c04 100644 --- a/spec/model/service_ticket/single_sign_out_notifier_spec.rb +++ b/spec/model/service_ticket/single_sign_out_notifier_spec.rb @@ -2,7 +2,7 @@ require 'nokogiri' describe CASino::ServiceTicket::SingleSignOutNotifier do - let(:service_ticket) { FactoryGirl.create :service_ticket } + let(:service_ticket) { FactoryBot.create :service_ticket } let(:service) { service_ticket.service } let(:notifier) { described_class.new service_ticket } @@ -22,7 +22,7 @@ end it 'sets the timeout values' do - [:read_timeout=, :open_timeout=].each do |timeout| + %i[read_timeout= open_timeout=].each do |timeout| Net::HTTP.any_instance.should_receive(timeout).with(CASino.config.service_ticket[:single_sign_out_notification][:timeout]) end notifier.notify @@ -36,7 +36,7 @@ context 'with server error' do [404, 500].each do |status_code| - context "#{status_code}" do + context status_code.to_s do before(:each) do stub_request(:post, service).to_return status: status_code end diff --git a/spec/model/service_ticket_spec.rb b/spec/model/service_ticket_spec.rb index 2c32353f..21f73443 100644 --- a/spec/model/service_ticket_spec.rb +++ b/spec/model/service_ticket_spec.rb @@ -1,23 +1,21 @@ -# encoding: utf-8 - require 'spec_helper' describe CASino::ServiceTicket do - let(:unconsumed_ticket) { + let(:unconsumed_ticket) do ticket = described_class.new ticket: 'ST-12345', service: 'https://example.com/cas-service' ticket.ticket_granting_ticket_id = 1 ticket - } - let(:consumed_ticket) { + end + let(:consumed_ticket) do ticket = described_class.new ticket: 'ST-54321', service: 'https://example.com/cas-service' ticket.ticket_granting_ticket_id = 1 ticket.consumed = true ticket.save! ticket - } + end describe '#expired?' do - [:unconsumed, :consumed].each do |state| + %i[unconsumed consumed].each do |state| context "with an #{state} ticket" do let(:ticket) { send("#{state}_ticket") } diff --git a/spec/model/ticket_granting_ticket_spec.rb b/spec/model/ticket_granting_ticket_spec.rb index c55e1d52..7112de8f 100644 --- a/spec/model/ticket_granting_ticket_spec.rb +++ b/spec/model/ticket_granting_ticket_spec.rb @@ -2,15 +2,15 @@ require 'useragent' describe CASino::TicketGrantingTicket do - let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket, user_agent: 'TestBrowser' } - let(:service_ticket) { FactoryGirl.create :service_ticket, ticket_granting_ticket: ticket_granting_ticket } + let(:ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket, user_agent: 'TestBrowser' } + let(:service_ticket) { FactoryBot.create :service_ticket, ticket_granting_ticket: ticket_granting_ticket } subject { ticket_granting_ticket } it_behaves_like 'has browser info' describe '#destroy' do - let!(:consumed_service_ticket) { FactoryGirl.create :service_ticket, :consumed, ticket_granting_ticket: ticket_granting_ticket } + let!(:consumed_service_ticket) { FactoryBot.create :service_ticket, :consumed, ticket_granting_ticket: ticket_granting_ticket } context 'when notification for a service ticket fails' do before(:each) do @@ -32,12 +32,10 @@ end end - describe "user_ip" do - + describe 'user_ip' do it 'returns request remote_ip' do ticket_granting_ticket.user_ip.should == '127.0.0.1' end - end describe '#same_user?' do @@ -50,7 +48,7 @@ end context 'with a ticket from another user' do - let(:other_ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket } + let(:other_ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket } it 'should return false' do ticket_granting_ticket.same_user?(other_ticket_granting_ticket).should == false @@ -58,7 +56,7 @@ end context 'with a ticket from the same user' do - let(:other_ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket, user: ticket_granting_ticket.user } + let(:other_ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket, user: ticket_granting_ticket.user } it 'should return true' do ticket_granting_ticket.same_user?(other_ticket_granting_ticket).should == true @@ -136,7 +134,7 @@ end describe '.cleanup' do - let!(:other_ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket } + let!(:other_ticket_granting_ticket) { FactoryBot.create :ticket_granting_ticket } it 'deletes expired ticket-granting tickets' do ticket_granting_ticket.created_at = 25.hours.ago diff --git a/spec/model/two_factor_authenticator_spec.rb b/spec/model/two_factor_authenticator_spec.rb index 5ecf0fe7..c80ec017 100644 --- a/spec/model/two_factor_authenticator_spec.rb +++ b/spec/model/two_factor_authenticator_spec.rb @@ -3,7 +3,7 @@ describe CASino::TwoFactorAuthenticator do describe '.cleanup' do it 'deletes expired inactive two-factor authenticators' do - authenticator = FactoryGirl.create :two_factor_authenticator, :inactive + authenticator = FactoryBot.create :two_factor_authenticator, :inactive authenticator.created_at = 10.hours.ago authenticator.save! lambda do @@ -12,7 +12,7 @@ end it 'does not delete not expired inactive two-factor authenticators' do - authenticator = FactoryGirl.create :two_factor_authenticator, :inactive + authenticator = FactoryBot.create :two_factor_authenticator, :inactive authenticator.created_at = (CASino.config.two_factor_authenticator[:lifetime_inactive].seconds - 5).ago lambda do described_class.cleanup @@ -20,7 +20,7 @@ end it 'does not delete active two-factor authenticators' do - authenticator = FactoryGirl.create :two_factor_authenticator + authenticator = FactoryBot.create :two_factor_authenticator authenticator.created_at = 10.hours.ago authenticator.save! lambda do diff --git a/spec/services/auth_token_validation_service_spec.rb b/spec/services/auth_token_validation_service_spec.rb index 1f5c2266..d4ce1de7 100644 --- a/spec/services/auth_token_validation_service_spec.rb +++ b/spec/services/auth_token_validation_service_spec.rb @@ -71,7 +71,7 @@ context 'with valid user data' do let(:token_data) { { authenticator: 'static', username: 'testuser' } } - let(:user_data) { { username: 'testuser', extra_attributes: { "name" => "Test User", "game" => [ "StarCraft 2", "Doto" ] } } } + let(:user_data) { { username: 'testuser', extra_attributes: { 'name' => 'Test User', 'game' => ['StarCraft 2', 'Doto'] } } } let(:validation_result) { { authenticator: 'static', user_data: user_data } } its(:user_data) { should == user_data } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 68936c8c..7acce3a1 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,5 @@ # This file is copied to spec/ when you run 'rails generate rspec:install' -ENV["RAILS_ENV"] ||= 'test' +ENV['RAILS_ENV'] ||= 'test' require 'coveralls' Coveralls.wear! @@ -9,7 +9,7 @@ add_filter '/spec' end -require File.expand_path('../dummy/config/environment.rb', __FILE__) +require File.expand_path('../dummy/config/environment.rb', __FILE__) require 'rspec/rails' require 'rspec/its' require 'webmock/rspec' @@ -20,4 +20,4 @@ # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. -Dir[File.join(ENGINE_RAILS_ROOT, 'spec/support/**/*.rb')].each {|f| require f } +Dir[File.join(ENGINE_RAILS_ROOT, 'spec/support/**/*.rb')].each { |f| require f } diff --git a/spec/support/factories/login_attempt_factory.rb b/spec/support/factories/login_attempt_factory.rb index 1efa37a4..933fc436 100644 --- a/spec/support/factories/login_attempt_factory.rb +++ b/spec/support/factories/login_attempt_factory.rb @@ -1,6 +1,6 @@ require 'factory_girl' -FactoryGirl.define do +FactoryBot.define do factory :login_attempt, class: CASino::LoginAttempt do user successful true diff --git a/spec/support/factories/login_ticket_factory.rb b/spec/support/factories/login_ticket_factory.rb index 3533ce22..7e9233e6 100644 --- a/spec/support/factories/login_ticket_factory.rb +++ b/spec/support/factories/login_ticket_factory.rb @@ -1,6 +1,6 @@ require 'factory_girl' -FactoryGirl.define do +FactoryBot.define do factory :login_ticket, class: CASino::LoginTicket do sequence :ticket do |n| "LT-ticket#{n}" diff --git a/spec/support/factories/proxy_granting_ticket_factory.rb b/spec/support/factories/proxy_granting_ticket_factory.rb index eb651653..de37c40a 100644 --- a/spec/support/factories/proxy_granting_ticket_factory.rb +++ b/spec/support/factories/proxy_granting_ticket_factory.rb @@ -1,6 +1,6 @@ require 'factory_girl' -FactoryGirl.define do +FactoryBot.define do factory :proxy_granting_ticket, class: CASino::ProxyGrantingTicket do association :granter, factory: :service_ticket sequence :ticket do |n| diff --git a/spec/support/factories/proxy_ticket_factory.rb b/spec/support/factories/proxy_ticket_factory.rb index 11dc2c45..c4321550 100644 --- a/spec/support/factories/proxy_ticket_factory.rb +++ b/spec/support/factories/proxy_ticket_factory.rb @@ -1,6 +1,6 @@ require 'factory_girl' -FactoryGirl.define do +FactoryBot.define do factory :proxy_ticket, class: CASino::ProxyTicket do proxy_granting_ticket sequence :ticket do |n| diff --git a/spec/support/factories/service_rule_factory.rb b/spec/support/factories/service_rule_factory.rb index 5c6ff3c3..b1830000 100644 --- a/spec/support/factories/service_rule_factory.rb +++ b/spec/support/factories/service_rule_factory.rb @@ -1,6 +1,6 @@ require 'factory_girl' -FactoryGirl.define do +FactoryBot.define do factory :service_rule, class: CASino::ServiceRule do sequence :order do |n| n diff --git a/spec/support/factories/service_ticket_factory.rb b/spec/support/factories/service_ticket_factory.rb index 23ea3370..ab34bc29 100644 --- a/spec/support/factories/service_ticket_factory.rb +++ b/spec/support/factories/service_ticket_factory.rb @@ -1,6 +1,6 @@ require 'factory_girl' -FactoryGirl.define do +FactoryBot.define do factory :service_ticket, class: CASino::ServiceTicket do ticket_granting_ticket sequence :ticket do |n| diff --git a/spec/support/factories/ticket_granting_ticket_factory.rb b/spec/support/factories/ticket_granting_ticket_factory.rb index 1c20658d..bc43756a 100644 --- a/spec/support/factories/ticket_granting_ticket_factory.rb +++ b/spec/support/factories/ticket_granting_ticket_factory.rb @@ -1,6 +1,6 @@ require 'factory_girl' -FactoryGirl.define do +FactoryBot.define do factory :ticket_granting_ticket, class: CASino::TicketGrantingTicket do user sequence :ticket do |n| diff --git a/spec/support/factories/two_factor_authenticator_factory.rb b/spec/support/factories/two_factor_authenticator_factory.rb index d21534fe..109304b2 100644 --- a/spec/support/factories/two_factor_authenticator_factory.rb +++ b/spec/support/factories/two_factor_authenticator_factory.rb @@ -1,7 +1,7 @@ require 'factory_girl' require 'rotp' -FactoryGirl.define do +FactoryBot.define do factory :two_factor_authenticator, class: CASino::TwoFactorAuthenticator do user secret do diff --git a/spec/support/factories/user_factory.rb b/spec/support/factories/user_factory.rb index bcc73fe0..ed90d198 100644 --- a/spec/support/factories/user_factory.rb +++ b/spec/support/factories/user_factory.rb @@ -1,11 +1,11 @@ require 'factory_girl' -FactoryGirl.define do +FactoryBot.define do factory :user, class: CASino::User do authenticator 'test' sequence(:username) do |n| "test#{n}" end - extra_attributes({ fullname: "Test User", age: 15, roles: [:user] }) + extra_attributes(fullname: 'Test User', age: 15, roles: [:user]) end end diff --git a/spec/support/features_helper.rb b/spec/support/features_helper.rb index eca827b2..80aa327c 100644 --- a/spec/support/features_helper.rb +++ b/spec/support/features_helper.rb @@ -17,7 +17,7 @@ def enable_two_factor_authentication visit new_two_factor_authenticator_path secret = find('p#secret').text.gsub(/^Secret:\s*/, '') ROTP::TOTP.new(secret).tap do |totp| - fill_in 'otp', with: "#{totp.now}" + fill_in 'otp', with: totp.now.to_s click_button 'Verify and enable' end end diff --git a/spec/support/rspec.rb b/spec/support/rspec.rb index 135b6b17..89a19f7d 100644 --- a/spec/support/rspec.rb +++ b/spec/support/rspec.rb @@ -9,11 +9,11 @@ config.mock_with :rspec do |mocks| mocks.yield_receiver_to_any_instance_implementation_blocks = false # TODO: we should maybe port existing tests to the new expect syntax - mocks.syntax = [:should, :expect] + mocks.syntax = %i[should expect] end config.expect_with :rspec do |c| # TODO: we should maybe port existing tests to the new expect syntax - c.syntax = [:should, :expect] + c.syntax = %i[should expect] end end