casino_core 1.0.6 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # CASinoCore [![Build Status](https://secure.travis-ci.org/pencil/CASinoCore.png?branch=master)](https://travis-ci.org/pencil/CASinoCore)
1
+ # CASinoCore [![Build Status](https://secure.travis-ci.org/rbCAS/CASinoCore.png?branch=master)](https://travis-ci.org/rbCAS/CASinoCore)
2
2
 
3
3
  A CAS server core library.
4
4
 
data/Rakefile CHANGED
@@ -20,7 +20,7 @@ require 'jeweler'
20
20
  Jeweler::Tasks.new do |gem|
21
21
  # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
22
22
  gem.name = "casino_core"
23
- gem.homepage = "http://github.com/pencil/CASinoCore"
23
+ gem.homepage = "http://rbcas.org/"
24
24
  gem.license = "MIT"
25
25
  gem.summary = "A CAS server core library."
26
26
  gem.description = gem.summary
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.6
1
+ 1.0.7
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "casino_core"
8
- s.version = "1.0.6"
8
+ s.version = "1.0.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Nils Caspar"]
12
- s.date = "2012-12-31"
12
+ s.date = "2013-01-01"
13
13
  s.description = "A CAS server core library."
14
14
  s.email = "ncaspar@me.com"
15
15
  s.extra_rdoc_files = [
@@ -117,7 +117,7 @@ Gem::Specification.new do |s|
117
117
  "spec/support/factories/service_ticket_factory.rb",
118
118
  "spec/support/factories/ticket_granting_ticket_factory.rb"
119
119
  ]
120
- s.homepage = "http://github.com/pencil/CASinoCore"
120
+ s.homepage = "http://rbcas.org/"
121
121
  s.licenses = ["MIT"]
122
122
  s.require_paths = ["lib"]
123
123
  s.rubygems_version = "1.8.24"
@@ -19,6 +19,11 @@ module CASinoCore
19
19
  config = YAML.load_file('config/cas.yml')[@environment].symbolize_keys
20
20
  recursive_symbolize_keys!(config)
21
21
  CASinoCore::Settings.init config
22
+
23
+ ActiveSupport::Inflector.inflections do |inflect|
24
+ inflect.acronym 'CAS'
25
+ inflect.acronym 'CASino'
26
+ end
22
27
  end
23
28
 
24
29
  private
@@ -2,6 +2,8 @@ module CASinoCore
2
2
  class Authenticator
3
3
  autoload :Static, 'casino_core/authenticator/static.rb'
4
4
 
5
+ class AuthenticatorError < StandardError; end
6
+
5
7
  def validate(username, password)
6
8
  raise NotImplementedError, "This method must be implemented by a class extending #{self.class}"
7
9
  end
@@ -5,7 +5,11 @@ module CASinoCore
5
5
  def validate_login_credentials(username, password)
6
6
  authentication_result = nil
7
7
  CASinoCore::Settings.authenticators.each do |authenticator_name, authenticator|
8
- data = authenticator.validate(username, password)
8
+ begin
9
+ data = authenticator.validate(username, password)
10
+ rescue CASinoCore::Authenticator::AuthenticatorError => e
11
+ logger.error "Authenticator '#{authenticator_name}' (#{authenticator.class}) raised an error: #{e}"
12
+ end
9
13
  if data
10
14
  authentication_result = { authenticator: authenticator_name, user_data: data }
11
15
  logger.info("Credentials for username '#{data[:username]}' successfully validated using authenticator '#{authenticator_name}' (#{authenticator.class})")
@@ -22,6 +22,6 @@ class CASinoCore::Model::ProxyTicket < ActiveRecord::Base
22
22
  else
23
23
  CASinoCore::Settings.proxy_ticket[:lifetime_unconsumed]
24
24
  end
25
- Time.now - self.created_at > lifetime
25
+ (Time.now - (self.created_at || Time.now)) > lifetime
26
26
  end
27
27
  end
@@ -35,7 +35,7 @@ class CASinoCore::Model::ServiceTicket < ActiveRecord::Base
35
35
  else
36
36
  CASinoCore::Settings.service_ticket[:lifetime_unconsumed]
37
37
  end
38
- Time.now - self.created_at > lifetime
38
+ (Time.now - (self.created_at || Time.now)) > lifetime
39
39
  end
40
40
 
41
41
  private
@@ -10,8 +10,14 @@ class CASinoCore::Model::TicketGrantingTicket < ActiveRecord::Base
10
10
  after_destroy :destroy_proxy_granting_tickets
11
11
 
12
12
  def browser_info
13
- user_agent = UserAgent.parse(self.user_agent)
14
- "#{user_agent.browser} (#{user_agent.platform})"
13
+ unless self.user_agent.blank?
14
+ user_agent = UserAgent.parse(self.user_agent)
15
+ if user_agent.platform.nil?
16
+ "#{user_agent.browser}"
17
+ else
18
+ "#{user_agent.browser} (#{user_agent.platform})"
19
+ end
20
+ end
15
21
  end
16
22
 
17
23
  def same_user?(other_ticket)
@@ -1,32 +1,63 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CASinoCore::Model::ProxyTicket do
4
- let(:ticket) {
5
- ticket = described_class.new ticket: 'PT-12345', service: 'any string is valid'
4
+ let(:unconsumed_ticket) {
5
+ ticket = described_class.new ticket: 'PT-12345', service: 'any_string_is_valid'
6
6
  ticket.proxy_granting_ticket_id = 1
7
7
  ticket
8
8
  }
9
+ let(:consumed_ticket) {
10
+ ticket = described_class.new ticket: 'PT-54321', service: 'any_string_is_valid'
11
+ ticket.proxy_granting_ticket_id = 1
12
+ ticket.consumed = true
13
+ ticket.save!
14
+ ticket
15
+ }
16
+
17
+ describe '#expired?' do
18
+ [:unconsumed, :consumed].each do |state|
19
+ context "with an #{state} ticket" do
20
+ let(:ticket) { send("#{state}_ticket") }
21
+
22
+ context 'with an expired ticket' do
23
+ before(:each) do
24
+ ticket.created_at = (CASinoCore::Settings.service_ticket[:"lifetime_#{state}"].seconds + 1).ago
25
+ ticket.save!
26
+ end
27
+
28
+ it 'returns true' do
29
+ ticket.expired?.should == true
30
+ end
31
+ end
32
+
33
+ context 'with an unexpired ticket' do
34
+ it 'returns false' do
35
+ ticket.expired?.should == false
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
9
41
 
10
42
  describe '.cleanup_unconsumed' do
11
43
  it 'deletes expired unconsumed service tickets' do
12
- ticket.created_at = 10.hours.ago
13
- ticket.save!
44
+ unconsumed_ticket.created_at = 10.hours.ago
45
+ unconsumed_ticket.save!
14
46
  lambda do
15
47
  described_class.cleanup_unconsumed
16
48
  end.should change(described_class, :count).by(-1)
17
- described_class.find_by_ticket('ST-12345').should be_false
49
+ described_class.find_by_ticket('PT-12345').should be_false
18
50
  end
19
51
  end
20
52
 
21
53
  describe '.cleanup_consumed' do
22
54
  it 'deletes expired consumed service tickets' do
23
- ticket.consumed = true
24
- ticket.created_at = 10.days.ago
25
- ticket.save!
55
+ consumed_ticket.created_at = 10.days.ago
56
+ consumed_ticket.save!
26
57
  lambda do
27
58
  described_class.cleanup_consumed
28
59
  end.should change(described_class, :count).by(-1)
29
- described_class.find_by_ticket('ST-12345').should be_false
60
+ described_class.find_by_ticket('PT-12345').should be_false
30
61
  end
31
62
  end
32
63
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CASinoCore::Model::ServiceTicket do
4
- let(:ticket) {
4
+ let(:unconsumed_ticket) {
5
5
  ticket = described_class.new ticket: 'ST-12345', service: 'https://example.com/cas-service'
6
6
  ticket.ticket_granting_ticket_id = 1
7
7
  ticket
@@ -14,10 +14,35 @@ describe CASinoCore::Model::ServiceTicket do
14
14
  ticket
15
15
  }
16
16
 
17
+ describe '#expired?' do
18
+ [:unconsumed, :consumed].each do |state|
19
+ context "with an #{state} ticket" do
20
+ let(:ticket) { send("#{state}_ticket") }
21
+
22
+ context 'with an expired ticket' do
23
+ before(:each) do
24
+ ticket.created_at = (CASinoCore::Settings.service_ticket[:"lifetime_#{state}"].seconds + 1).ago
25
+ ticket.save!
26
+ end
27
+
28
+ it 'returns true' do
29
+ ticket.expired?.should == true
30
+ end
31
+ end
32
+
33
+ context 'with an unexpired ticket' do
34
+ it 'returns false' do
35
+ ticket.expired?.should == false
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
17
42
  describe '.cleanup_unconsumed' do
18
43
  it 'deletes expired unconsumed service tickets' do
19
- ticket.created_at = 10.hours.ago
20
- ticket.save!
44
+ unconsumed_ticket.created_at = 10.hours.ago
45
+ unconsumed_ticket.save!
21
46
  lambda do
22
47
  described_class.cleanup_unconsumed
23
48
  end.should change(described_class, :count).by(-1)
@@ -25,6 +50,20 @@ describe CASinoCore::Model::ServiceTicket do
25
50
  end
26
51
  end
27
52
 
53
+ describe '.cleanup_consumed_hard' do
54
+ before(:each) do
55
+ described_class::SingleSignOutNotifier.any_instance.stub(:notify).and_return(false)
56
+ end
57
+
58
+ it 'deletes consumed service tickets with an unreachable Single Sign Out callback server' do
59
+ consumed_ticket.created_at = 10.days.ago
60
+ consumed_ticket.save!
61
+ lambda do
62
+ described_class.cleanup_consumed_hard
63
+ end.should change(described_class, :count).by(-1)
64
+ end
65
+ end
66
+
28
67
  describe '.cleanup_consumed' do
29
68
  before(:each) do
30
69
  described_class::SingleSignOutNotifier.any_instance.stub(:notify).and_return(true)
@@ -1,7 +1,8 @@
1
1
  require 'spec_helper'
2
+ require 'useragent'
2
3
 
3
4
  describe CASinoCore::Model::TicketGrantingTicket do
4
- let(:ticket_granting_ticket) { described_class.create! ticket: 'TGT-3ep9awhy2ty5UhL8wM1xAZ', username: 'example-user', authenticator: 'test' }
5
+ let(:ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket }
5
6
  let(:service_ticket) { FactoryGirl.create :service_ticket, ticket_granting_ticket: ticket_granting_ticket }
6
7
  let(:consumed_service_ticket) { FactoryGirl.create :service_ticket, :consumed, ticket_granting_ticket: ticket_granting_ticket }
7
8
 
@@ -25,4 +26,66 @@ describe CASinoCore::Model::TicketGrantingTicket do
25
26
  end
26
27
  end
27
28
  end
29
+
30
+ describe '#browser_info' do
31
+ let(:user_agent) { Object.new }
32
+ before(:each) do
33
+ user_agent.stub(:browser).and_return('TestBrowser')
34
+ UserAgent.stub(:parse).and_return(user_agent)
35
+ end
36
+
37
+ context 'without platform' do
38
+ before(:each) do
39
+ user_agent.stub(:platform).and_return(nil)
40
+ end
41
+
42
+ it 'returns the browser name' do
43
+ ticket_granting_ticket.browser_info.should == 'TestBrowser'
44
+ end
45
+ end
46
+
47
+ context 'with a platform' do
48
+ before(:each) do
49
+ user_agent.stub(:platform).and_return('Linux')
50
+ end
51
+
52
+ it 'returns the browser name' do
53
+ ticket_granting_ticket.browser_info.should == 'TestBrowser (Linux)'
54
+ end
55
+ end
56
+ end
57
+
58
+ describe '#same_user?' do
59
+ context 'with a nil value' do
60
+ let(:other_ticket_granting_ticket) { nil }
61
+
62
+ it 'should return false' do
63
+ ticket_granting_ticket.same_user?(other_ticket_granting_ticket).should == false
64
+ end
65
+ end
66
+
67
+ context 'with a ticket from another user' do
68
+ let(:other_ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket, username: 'bla' }
69
+
70
+ it 'should return false' do
71
+ ticket_granting_ticket.same_user?(other_ticket_granting_ticket).should == false
72
+ end
73
+ end
74
+
75
+ context 'with a ticket from another authenticator' do
76
+ let(:other_ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket, authenticator: 'bla' }
77
+
78
+ it 'should return false' do
79
+ ticket_granting_ticket.same_user?(other_ticket_granting_ticket).should == false
80
+ end
81
+ end
82
+
83
+ context 'with a ticket from the same user and authenticator' do
84
+ let(:other_ticket_granting_ticket) { FactoryGirl.create :ticket_granting_ticket }
85
+
86
+ it 'should return true' do
87
+ ticket_granting_ticket.same_user?(other_ticket_granting_ticket).should == true
88
+ end
89
+ end
90
+ end
28
91
  end
@@ -32,18 +32,32 @@ describe CASinoCore::Processor::LoginCredentialAcceptor do
32
32
  end
33
33
 
34
34
  context 'with valid credentials' do
35
+ let(:service) { 'https://www.example.org' }
35
36
  let(:login_data) { { lt: login_ticket.ticket, username: 'testuser', password: 'foobar123', service: service } }
36
37
 
37
38
  before(:each) do
38
39
  listener.stub(:user_logged_in)
39
40
  end
40
41
 
42
+ context 'when all authenticators raise an error' do
43
+ before(:each) do
44
+ CASinoCore::Authenticator::Static.any_instance.stub(:validate) do
45
+ raise CASinoCore::Authenticator::AuthenticatorError, 'error123'
46
+ end
47
+ end
48
+
49
+ it 'calls the #invalid_login_credentials method on the listener' do
50
+ listener.should_receive(:invalid_login_credentials).with(kind_of(CASinoCore::Model::LoginTicket))
51
+ processor.process(login_data)
52
+ end
53
+ end
54
+
41
55
  context 'without a service' do
42
56
  let(:service) { nil }
43
57
 
44
58
  it 'calls the #user_logged_in method on the listener' do
45
59
  listener.should_receive(:user_logged_in).with(nil, /^TGC\-/)
46
- processor.process(lt: login_ticket.ticket, username: 'testuser', password: 'foobar123')
60
+ processor.process(login_data)
47
61
  end
48
62
 
49
63
  it 'generates a ticket-granting ticket' do
@@ -1,8 +1,20 @@
1
+ require 'active_support/core_ext'
2
+ require 'simplecov'
3
+
4
+ SimpleCov.start do
5
+ add_filter '/spec'
6
+ base_path = "#{File.dirname(__FILE__)}/../"
7
+ Dir["#{base_path}lib/casino_core/*.rb"].each do |f|
8
+ f.gsub!(/\A#{base_path}(.+)\.rb\z/, '\1')
9
+ name = File.basename(f).humanize.pluralize
10
+ add_group name, f
11
+ end
12
+ end
13
+
1
14
  require 'database_cleaner'
2
15
  require 'logger'
3
16
  require 'webmock/rspec'
4
17
  require 'casino_core'
5
- require 'simplecov'
6
18
 
7
19
  # This file was generated by the `rspec --init` command. Conventionally, all
8
20
  # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
@@ -24,16 +36,6 @@ RSpec.configure do |config|
24
36
  # --seed 1234
25
37
  config.order = 'random'
26
38
 
27
- SimpleCov.start do
28
- add_filter '/spec'
29
- base_path = "#{File.dirname(__FILE__)}/../"
30
- Dir["#{base_path}lib/casino_core/*.rb"].each do |f|
31
- f.gsub!(/\A#{base_path}(.+)\.rb\z/, '\1')
32
- name = File.basename(f).humanize.pluralize
33
- add_group name, f
34
- end
35
- end
36
-
37
39
  CASinoCore.setup 'test'
38
40
  CASinoCore::Settings.logger.level = ::Logger::Severity::UNKNOWN
39
41
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: casino_core
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.0.6
5
+ version: 1.0.7
6
6
  platform: ruby
7
7
  authors:
8
8
  - Nils Caspar
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-12-31 00:00:00 Z
13
+ date: 2013-01-01 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -275,7 +275,7 @@ files:
275
275
  - spec/support/factories/proxy_ticket_factory.rb
276
276
  - spec/support/factories/service_ticket_factory.rb
277
277
  - spec/support/factories/ticket_granting_ticket_factory.rb
278
- homepage: http://github.com/pencil/CASinoCore
278
+ homepage: http://rbcas.org/
279
279
  licenses:
280
280
  - MIT
281
281
  post_install_message:
@@ -288,7 +288,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
288
288
  requirements:
289
289
  - - ">="
290
290
  - !ruby/object:Gem::Version
291
- hash: -3280265477686707578
291
+ hash: 903042986350696611
292
292
  segments:
293
293
  - 0
294
294
  version: "0"