casino_core 1.0.6 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
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"