trivial_sso 4.0.0.3 → 4.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 757d1e6efcab4ef502c3b7081079211f9b59efb2
4
- data.tar.gz: 132360a31cfd6b5c8e5859c50acb907f433b30a4
3
+ metadata.gz: 936981875ed9f86e1f13252e3b2e98f86280b32e
4
+ data.tar.gz: 5c59ef3e7aec280fdba6918b50095ff354600ef0
5
5
  SHA512:
6
- metadata.gz: 513db9226ecb8da76264c56cc7c202355aff18553627c2f3b8c47d30758e0839d4509ba4553ec32953f14189a3b871f7329a13cd57552e7c8f36c9e0bd80f30e
7
- data.tar.gz: 0e1edc9ec2f99d0cd34424292107a32eaf54374c26060e7bab067bbf699b97c4a6adbbfc8ca25894556cd4dbb8d25d424ca534487f15877ebd29c72aee275834
6
+ metadata.gz: 39c154dbe5a77da77ee19f011022384858d912831261c6f632f287e37598a1ec79c21a6da827ccd6d789e55f32143f9b22b24255948cad946c4be5f5766b9d00
7
+ data.tar.gz: 68e0396f2c4aab07a10084c3c482a1464274c19a851eb26930e66ad68658783fe76ec9a2706b41e025896707dff1942a941fa194f2c6c3526767c30c8770d087
data/CHANGELOG.md CHANGED
@@ -1,6 +1,9 @@
1
1
  ## TrivialSso Change Log ##
2
2
  ### Changelog ###
3
3
 
4
+ ### 4.0.2
5
+ - expose the default expire on the Login class
6
+
4
7
  ### 4.0.0.3
5
8
  - ease the required ruby back to 1.9.3
6
9
 
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Code Climate](https://codeclimate.com/github/nacengineer/trivialsso.png)](https://codeclimate.com/github/nacengineer/trivialsso)
2
+
1
3
  ## TrivialSso
2
4
 
3
5
  A very simple gem to help with creating and reading cookies across multiple sites in a Ruby on Rails application.
@@ -26,84 +28,98 @@ After you've installed the gem, you need to generate a configuration file.
26
28
 
27
29
  This will create an initializer file with a shared secret. You need to modify this to a big long string of characters. Keep this safe from others as they could forge cookies for your sites if they get ahold of this string. All sites that use the single sign on must have this same shared secret for the cookies to properly interoperate.
28
30
 
29
- ## Creating a cookie
31
+ ## Creating an encrpyted string
32
+ ### Uses [ActiveSupport::MessageEncryptor](http://api.rubyonrails.org/classes/ActiveSupport/MessageEncryptor.html)
33
+
34
+ A encrypted and signed string is created using of data supplied to it via a [ruby Hash](http://www.ruby-doc.org/core-2.0/Hash.html).
35
+
36
+ This only requirement is that the Hash must contain a **username** key.
37
+
38
+ When you create the encrypted string an expire time is added to the payload. You have the option of either providing one, or a default of 9 hours from the current time will be used.
30
39
 
31
- A cookie is created using a hash of data supplied to it. This must contain a **username** key.
40
+ Note: Setting the [ActionDispatch#expires](http://api.rubyonrails.org/classes/ActionDispatch/Cookies.html) on the cookie is just a convenience to make sure it gets cleared by the browser.
32
41
 
33
- When you create the cookie data an expire time is built into the payload. Setting the **:expires** on the cookie is just a convenience to make sure it gets cleared by the browser. The actual expiration date that matters is what is encoded in the cookie.
42
+ The actual expiration date that is enforced by the application is what is encoded in the cookie.4
34
43
 
35
- ```ruby
36
- # Create a hash of data we want to store in the cookie.
37
- userdata = {
38
- "username" => current_user.login,
39
- "display" => current_user.display_name,
40
- "groups" => current_user.memberof
41
- }
44
+ Essentiall it is all boiled down to the follwoing...
42
45
 
43
- #Generate the cookie data
44
- cookie = TrivialSso::Login.cookie(userdata)
46
+ ### create a userdata hash
45
47
 
46
- # Set the cookie
47
- cookies[:sso_login] = {
48
- :value => cookie,
49
- :expires => TrivialSso::Login.expire_date,
50
- :domain => 'mydomain.com',
51
- :httponly => true,
52
- }
53
- ```
48
+ ```ruby
49
+ # Create a hash of data we want to store in the cookie.
50
+ userdata = {
51
+ "username" => current_user.login,
52
+ "display" => current_user.display_name,
53
+ "groups" => current_user.memberof
54
+ }
55
+
56
+ #### Generate the cookie data with Api.encode
57
+ cookie = TrivialSso::Api.encode(userdata)
58
+
59
+ #### Set the cookie
60
+ cookies[:sso_login] = {
61
+ :value => cookie,
62
+ :expires => TrivialSso::Login.default_expire,
63
+ :domain => 'mydomain.com',
64
+ :httponly => true
65
+ }
66
+ ```
54
67
 
55
68
  The above code creates a hash of data we will be putting in the cookie, generates the cookie, and then sets the cookie in the browser.
56
69
 
57
- ## Decoding a cookie
70
+ ### Decoding a cookie
58
71
 
59
- Retrieve the contents of the cookie by calling decode_cookie
72
+ Retrieve the contents of the cookie by calling Api.decode
60
73
 
61
- @userdata = TrivialSso::Login.decode_cookie(cookies[:sso_login])
74
+ ```ruby
75
+ @userdata = TrivialSso::Api.decode(cookies[:sso_login])
76
+ ```
62
77
 
63
- This will throw an exception if the cookie has been tampered with, or if the expiration date has passed.
78
+ This will return the originally encoded data as a __Hash__ with string keys.
79
+
80
+ NOTE: This will throw an exception if the cookie has been tampered with, or if the expiration date has passed.
64
81
 
65
82
  ## Sample code for application_controller
66
83
 
67
84
  Here are some methods you can add into your application controller to authenticate against the cookie.
68
85
 
69
- ```ruby
70
- # If there is a problem with the cookie, redirect back to our central login server.
71
- rescue_from TrivialSso::CookieError do |exception|
72
- redirect_to 'https://login.mydomain.com/'
73
- end
74
-
75
- # authorize our users based on the cookie.
76
- before_filter :auth_user!
77
-
78
- # authenticate a user and set @current_user
79
- def auth_user!
80
- cu = current_user
81
-
82
- # Check for authorization based on "groups" data that was put in the cookie
83
- # by the central login application.
84
- # you could also skip this check and just return true if the cookie is valid.
85
- if cu['groups'].include? "ALLOWED_GROUP" #all lower case
86
- @current_user = cu
87
- true
88
- else
89
- render :file => "#{Rails.root}/public/403", :formats => [:html], :status => 403, :layout => false
90
- end
91
-
92
- false
93
- end
94
-
95
- # our current_user decodes the cookie.
96
- def current_user
97
- TrivialSso::Login.decode_cookie(cookies[:sso_login])
98
- end
99
-
100
- # Define the name we want to record in paper_trail (if using)
101
- def user_for_paper_trail
102
- if @current_user.blank?
103
- "anonymous"
104
- else
105
- @current_user['username']
106
- end
107
- end
108
- ```
109
-
86
+ ```ruby
87
+ # If there is a problem with the cookie, redirect back to our central login server.
88
+ rescue_from TrivialSso::CookieError do |exception|
89
+ redirect_to 'https://login.mydomain.com/'
90
+ end
91
+
92
+ # authorize our users based on the cookie.
93
+ before_filter :auth_user!
94
+
95
+ # authenticate a user and set @current_user
96
+ def auth_user!
97
+ cu = current_user
98
+
99
+ # Check for authorization based on "groups" data that was put in the cookie
100
+ # by the central login application.
101
+ # you could also skip this check and just return true if the cookie is valid.
102
+ if cu['groups'].include? "ALLOWED_GROUP" #all lower case
103
+ @current_user = cu
104
+ true
105
+ else
106
+ render :file => "#{Rails.root}/public/403", :formats => [:html], :status => 403, :layout => false
107
+ end
108
+
109
+ false
110
+ end
111
+
112
+ # our current_user decodes the cookie.
113
+ def current_user
114
+ TrivialSso::Api.decode(cookies[:sso_login])
115
+ end
116
+
117
+ # Define the name we want to record in paper_trail (if using)
118
+ def user_for_paper_trail
119
+ if @current_user.blank?
120
+ "anonymous"
121
+ else
122
+ @current_user['username']
123
+ end
124
+ end
125
+ ```
@@ -0,0 +1,19 @@
1
+ module TrivialSso
2
+ class Api
3
+
4
+ class <<self
5
+
6
+ def encode(data, expire_time = nil, secret = nil)
7
+ TrivialSso::Login.new(
8
+ {data: data, expire_time: expire_time, secret: secret}
9
+ ).wrap
10
+ end
11
+
12
+ def decode(data, secret = nil)
13
+ TrivialSso::Login.new({data: data, secret: secret}).unwrap
14
+ end
15
+
16
+ end
17
+
18
+ end
19
+ end
@@ -8,13 +8,46 @@ module TrivialSso
8
8
  end
9
9
  end
10
10
 
11
- # Cookie can not be verified, data has been altered
12
- class BadCookie < CookieError
11
+ class MissingConfig < RuntimeError
13
12
  def to_s
14
- "Login cookie can not be verified!"
13
+ "There is something wrong with the config of this application"
15
14
  end
16
15
  end
17
16
 
17
+ # Cookie can not be verified, data has been altered
18
+ module BadData
19
+
20
+ class Signature < CookieError
21
+ def to_s
22
+ "The data signature supplied was not valid."
23
+ end
24
+ end
25
+
26
+ # Cookie can not be verified, data has been altered
27
+ class Message < CookieError
28
+ def to_s
29
+ "The data supplied was not valid. i.e. bad cookie data given"
30
+ end
31
+ end
32
+
33
+ class Given < CookieError
34
+ def to_s
35
+ <<-HERE
36
+ The data supplied is useless to me. i.e. Can't Wrap or Unwrap.
37
+ Try passing me some good data.
38
+ HERE
39
+ end
40
+ end
41
+
42
+ # Cookie is missing
43
+ class Missing < CookieError
44
+ def to_s
45
+ "No data was given."
46
+ end
47
+ end
48
+
49
+ end
50
+
18
51
  # cookie is no longer valid
19
52
  class LoginExpired < CookieError
20
53
  def to_s
@@ -22,24 +55,27 @@ module TrivialSso
22
55
  end
23
56
  end
24
57
 
25
- # Cookie is missing
26
- class MissingCookie < CookieError
58
+ # Cookie is lacking a username.
59
+ class NoUsernameData < CookieError
27
60
  def to_s
28
- "Login cookie is missing!"
61
+ "Need username to create cookie"
29
62
  end
30
63
  end
31
64
 
32
- # Cookie is lacking a username.
33
- class NoUsernameCookie < CookieError
65
+ # Missing configuration value.
66
+ class MissingRailsConfig < CookieError
34
67
  def to_s
35
- "Need username to create cookie"
68
+ <<-HERE
69
+ Missing secret configuration for cookie, need to define
70
+ config.sso_secret
71
+ HERE
36
72
  end
37
73
  end
38
74
 
39
75
  # Missing configuration value.
40
- class MissingConfig < CookieError
76
+ class MissingSecret < CookieError
41
77
  def to_s
42
- "Missing secret configuration for cookie, need to define config.sso_secret"
78
+ "Missing secret, need to define sso_secret"
43
79
  end
44
80
  end
45
81
 
@@ -50,5 +86,23 @@ module TrivialSso
50
86
  end
51
87
  end
52
88
 
89
+
90
+ class BadExpireTime < CookieError
91
+ def to_s
92
+ <<-HERE
93
+ The expire_time is useless to me. i.e. its not an Time object
94
+ transormed to integer time. Please retry with good data.
95
+ HERE
96
+ end
97
+ end
98
+
99
+ module Mode
100
+ class Wrong < CookieError
101
+ def to_s
102
+ "Can't use same object to decode and encode"
103
+ end
104
+ end
105
+ end
106
+
53
107
  end
54
108
  end
@@ -1,76 +1,89 @@
1
1
  module TrivialSso
2
2
  class Login
3
3
 
4
- # signing and un-signing may have to be refactored to use OpenSSL:HMAC...
5
- # as this will not work well across platforms. (ideally this should work for PHP as well)
6
-
7
- # Decodes and verifies an encrypted cookie
8
- # throw a proper exception if a bad or invalid cookie.
9
- # otherwise, return the username and userdata stored in the cookie
10
- def self.decode_cookie(cookie = nil)
11
- begin
12
- raise TrivialSso::Error::MissingCookie if cookie.nil? || cookie.empty?
13
- userdata, timestamp = encrypted_message.decrypt_and_verify(cookie)
14
- raise TrivialSso::Error::LoginExpired if check_timestamp(timestamp)
15
- userdata
16
- rescue NoMethodError
17
- raise TrivialSso::Error::MissingConfig
18
- rescue ActiveSupport::MessageVerifier::InvalidSignature ||
19
- ActiveSupport::MessageEncryptor::InvalidMessage
20
- raise TrivialSso::Error::BadCookie
21
- end
4
+ attr_accessor :data, :secret, :expire_time, :struct
5
+ attr_reader :wrap, :unwrap, :mode, :secret, :default_expire
6
+
7
+ def initialize(opts = {})
8
+ opts[:expire_time] = default_expire unless opts[:expire_time]
9
+ opts[:secret] = default_secret unless opts[:secret]
10
+ opts.each {|k,v| send("#{k}=".to_sym, v) if available_opts.include?(k.to_sym)}
11
+ end
12
+
13
+ def expire_time=(value)
14
+ @expire_time = time_or_default(value) if time_value_good?(value)
22
15
  end
23
16
 
24
- # create an encrypted and signed cookie containing userdata and an expiry date.
25
- # userdata should be an array, and at minimum include a 'username' key.
26
- # using json serializer to hopefully allow future cross version compatibliity
27
- # (Marshall, the default serializer, is not compatble between versions)
28
- def self.cookie(userdata, expire_date = default_expire_date)
29
- begin
30
- raise TrivialSso::Error::MissingConfig if sso_secret
31
- raise TrivialSso::Error::NoUsernameCookie if check_username(userdata)
32
- enc.encrypt_and_sign([userdata, expire_date])
33
- rescue NoMethodError
34
- raise TrivialSso::Error::MissingConfig
17
+ def data=(value)
18
+ if value.is_a?(String)
19
+ @mode, @data = :unwrap, value
20
+ elsif value.is_a?(Hash)
21
+ @mode, @data = :wrap, OpenStruct.new(value)
22
+ else
23
+ raise Error::BadData::Given
35
24
  end
36
25
  end
37
26
 
38
- private
27
+ def wrap
28
+ check_mode_set
29
+ raise Error::Mode::Wrong unless mode == __method__
30
+ TrivialSso::Wrap.new(data, sso_secret, expire_time).wrap
31
+ end
32
+
33
+ def unwrap
34
+ check_mode_set
35
+ raise Error::Mode::Wrong unless mode == __method__
36
+ response = TrivialSso::UnWrap.new(data, sso_secret).unwrap
37
+ struct ? OpenStruct.new(response) : response
38
+ end
39
39
 
40
- def self.check_username(userdata)
41
- userdata.nil? ||
42
- userdata.empty? ||
43
- ! userdata.has_key?('username') ||
44
- userdata['username'].empty?
40
+ def sso_secret
41
+ TrivialSso::Secret.new(secret).sso_secret
45
42
  end
46
43
 
47
- def self.enc
48
- ActiveSupport::MessageEncryptor.new(sso_secret , serializer: JSON)
44
+ def default_expire
45
+ (Time.now + 32400).to_i # 9 hours from now
49
46
  end
50
47
 
51
- def self.default_expire_date
52
- (9.hours.from_now).to_i
48
+ private
49
+
50
+ def default_secret
51
+ get_defined_sso_secret || SecureRandom.hex(64)
52
+ end
53
+
54
+ def get_defined_sso_secret
55
+ if rails_sso_secret_exists?
56
+ Rails.configuration.sso_secret
57
+ elsif defined? Rails
58
+ raise Error::MissingRailsConfig
59
+ else
60
+ false
61
+ end
53
62
  end
54
63
 
55
- def self.check_timestamp(timestamp)
56
- (timestamp - DateTime.now.to_i) <= 0
64
+ def rails_sso_secret_exists?
65
+ defined?(Rails) && Rails.configuration.sso_secret
57
66
  end
58
67
 
59
- def self.encrypted_message
60
- raise TrivialSso::Error::MissingRails unless defined? Rails
61
- ActiveSupport::MessageEncryptor.new(sso_secret, serializer: JSON)
68
+ def check_mode_set
69
+ raise Error::BadData::Given if mode.nil? || mode.empty?
62
70
  end
63
71
 
64
- def self.sso_secret
65
- check_for_rails
66
- if Rails.configuration.sso_secret.nil? || Rails.configuration.sso_secret.empty?
67
- raise TrivialSso::Error::MissingConfig
72
+ def time_value_good?(value)
73
+ if (value.is_a?(Integer) || value.is_a?(String)) && value.to_s.length == 10
74
+ true
75
+ else
76
+ raise Error::BadExpireTime
68
77
  end
69
- Rails.configuration.sso_secret
70
78
  end
71
79
 
72
- def self.check_for_rails
73
- raise TrivialSso::Error::MissingRails unless defined?(Rails)
80
+ def time_or_default(value)
81
+ value.to_i.nonzero? ? value.to_i : default_expire
82
+ end
83
+
84
+
85
+ def available_opts
86
+ [:data, :secret, :expire_time]
74
87
  end
75
88
 
76
89
  end
@@ -0,0 +1,14 @@
1
+ TrivialSso::Secret = Struct.new :sso_secret do
2
+
3
+ def sso_secret=(value)
4
+ # TODO Add something to verify value
5
+ @sso_secret = value if check_sso_secret(value)
6
+ end
7
+
8
+ private
9
+
10
+ def check_sso_secret(value)
11
+ !value.nil? || !value.empty? || (raise TrivialSso::Error::MissingSecret)
12
+ end
13
+
14
+ end
@@ -0,0 +1,54 @@
1
+ TrivialSso::UnWrap = Struct.new :data, :sso_secret do
2
+
3
+ attr_reader :userdata, :timestamp
4
+
5
+ def unwrap
6
+ decode_data_and_timestamp
7
+ userdata
8
+ end
9
+
10
+ private
11
+
12
+ def userdata=(value)
13
+ @userdata = (value.has_key?('table') ? value['table'] : value)
14
+ end
15
+
16
+ def timestamp=(time_as_int)
17
+ if (time_as_int - Time.now.to_i) <= 0
18
+ # TODO check if we can raise Error::LoginExpired
19
+ raise TrivialSso::Error::LoginExpired
20
+ else
21
+ @timestamp = time_as_int
22
+ end
23
+ end
24
+
25
+ def decode_data_and_timestamp
26
+ begin
27
+ has_data?
28
+ self.userdata, self.timestamp = \
29
+ encrypted_message.decrypt_and_verify(data)
30
+ rescue NoMethodError
31
+ raise TrivialSso::Error::MissingConfig
32
+ rescue ActiveSupport::MessageVerifier::InvalidSignature
33
+ raise TrivialSso::Error::BadData::Signature
34
+ rescue ActiveSupport::MessageEncryptor::InvalidMessage
35
+ raise TrivialSso::Error::BadData::Message
36
+ end
37
+ end
38
+
39
+ def has_data?
40
+ if data.nil? || data.empty?
41
+ raise TrivialSso::Error::BadData::Missing
42
+ else
43
+ true
44
+ end
45
+ end
46
+
47
+ def encrypted_message
48
+ unless defined? Rails
49
+ raise TrivialSso::Error::MissingRails
50
+ end
51
+ ActiveSupport::MessageEncryptor.new(sso_secret, serializer: JSON)
52
+ end
53
+
54
+ end
@@ -0,0 +1,31 @@
1
+ TrivialSso::Wrap = Struct.new :data, :sso_secret, :expire_time do
2
+
3
+ attr_reader :wrap
4
+
5
+ def wrap
6
+ begin
7
+ encryptor.encrypt_and_sign([data, expire_time]) if sanity_check
8
+ rescue NoMethodError
9
+ raise TrivialSso::Error::MissingConfig
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def sanity_check
16
+ sso_secret && check_username || false
17
+ end
18
+
19
+ def encryptor
20
+ ActiveSupport::MessageEncryptor.new(sso_secret, serializer: JSON)
21
+ end
22
+
23
+ def check_username
24
+ has_data? || (raise TrivialSso::Error::NoUsernameData)
25
+ end
26
+
27
+ def has_data?
28
+ data && !(data.username.nil? || data.username.empty?)
29
+ end
30
+
31
+ end
@@ -1,3 +1,3 @@
1
1
  module TrivialSso
2
- VERSION = "4.0.0.3"
2
+ VERSION = "4.0.3"
3
3
  end
data/lib/trivial_sso.rb CHANGED
@@ -1,3 +1,8 @@
1
+ require 'ostruct'
1
2
  require "trivial_sso/version"
2
3
  require 'trivial_sso/error'
4
+ require 'trivial_sso/struct/secret'
5
+ require 'trivial_sso/struct/un_wrap'
6
+ require 'trivial_sso/struct/wrap'
7
+ require 'trivial_sso/api'
3
8
  require 'trivial_sso/login'
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'trivial_sso'
3
+ require 'forgery'
4
+
5
+ # mock out rails app for sso_secret
6
+ module TrivialSso
7
+ class Application < Rails::Application
8
+ config.sso_secret = SecureRandom.hex(64)
9
+ end
10
+ end
11
+
12
+ describe TrivialSso::Api do
13
+ let(:sso_secret) {SecureRandom.hex(64)}
14
+ let(:expire_time) {(Time.now - 1000).to_i}
15
+ let(:userdata) {
16
+ {
17
+ 'username' => Forgery::Internet.user_name,
18
+ 'groups' => ['one', 'two']
19
+ }
20
+ }
21
+
22
+
23
+ it "gives cookie" do
24
+ TrivialSso::Api.encode(userdata).should be_kind_of String
25
+ end
26
+
27
+ it "gives data" do
28
+ data = TrivialSso::Api.decode(TrivialSso::Api.encode(userdata))
29
+ data['username'].should eq userdata['username']
30
+ data['groups'].should eq userdata['groups']
31
+ end
32
+
33
+ end
34
+
@@ -0,0 +1,106 @@
1
+ require 'active_support/core_ext'
2
+ require 'trivial_sso'
3
+ require 'forgery'
4
+ require 'securerandom'
5
+
6
+ require 'rails'
7
+
8
+ # mock out rails app for sso_secret
9
+ module TrivialSso
10
+ class Application < Rails::Application
11
+ config.sso_secret = SecureRandom.hex(64)
12
+ end
13
+ end
14
+
15
+ describe TrivialSso::Login do
16
+ let(:sso_secret) {SecureRandom.hex(64)}
17
+ let(:userdata) {
18
+ {
19
+ 'username' => Forgery::Internet.user_name,
20
+ 'groups' => ['one', 'two']
21
+ }
22
+ }
23
+
24
+ let(:encode) {
25
+ TrivialSso::Login.new({secret: sso_secret, data: userdata})
26
+ }
27
+
28
+ let(:decode) {
29
+ TrivialSso::Login.new({secret: sso_secret, data: encode.wrap})
30
+ }
31
+
32
+ let(:expired_encode) {
33
+ TrivialSso::Login.new(
34
+ {data: userdata, secret: sso_secret, expire_time: (Time.now - 1000).to_i}
35
+ )
36
+ }
37
+
38
+ it "does set the data" do
39
+ encode.mode.should eq :wrap
40
+ encode.data.should be_kind_of OpenStruct
41
+ encode.data.username.should eq userdata['username']
42
+ encode.data.groups.should eq userdata['groups']
43
+ end
44
+
45
+ it "does create cookie with userdata" do
46
+ encode.wrap.should be_kind_of String
47
+ end
48
+
49
+ it "should encode and decode" do
50
+ decode.unwrap.should be_kind_of Hash
51
+ decode.unwrap.should eq userdata
52
+ end
53
+
54
+ it "should encode and decode as OpenStruct" do
55
+ decode.struct = true
56
+ decode.unwrap.should be_kind_of OpenStruct
57
+ decode.unwrap.should eq OpenStruct.new userdata
58
+ end
59
+
60
+ it "throw exception on missing username" do
61
+ expect {
62
+ encode.data = {username: ""}
63
+ encode.wrap
64
+ }.to raise_error TrivialSso::Error::NoUsernameData
65
+ end
66
+
67
+ it "throw exception on blank cookie" do
68
+ expect {
69
+ decode.data = ""
70
+ decode.unwrap
71
+ }.to raise_error TrivialSso::Error::BadData::Missing
72
+ end
73
+
74
+ it "raise exception bad signature when given cookie w/o signature as data source" do
75
+ expect {
76
+ decode.data = "BAhbB0kiC2RqbGVlMgY6BkVUbCsHo17iTg"
77
+ decode.unwrap
78
+ }.to raise_error TrivialSso::Error::BadData::Signature
79
+ end
80
+
81
+ it "raise exception bad message when given cookie w/o encryped data" do
82
+ expect {
83
+ decode.data = "--5b3164f6d1f09fb00d6905d073b18bc45a859b50"
84
+ decode.unwrap
85
+ }.to raise_error TrivialSso::Error::BadData::Signature
86
+ end
87
+
88
+ it "raise exception on expired cookie" do
89
+ expect {
90
+ decode.data = expired_encode.wrap
91
+ decode.unwrap
92
+ }.to raise_error TrivialSso::Error::LoginExpired
93
+ end
94
+
95
+ it "raises if expire_time not valid" do
96
+ expect {
97
+ encode.expire_time = %w(this is bad data)
98
+ }.to raise_error TrivialSso::Error::BadExpireTime
99
+ end
100
+
101
+ it "uses rails sso if Rails.defined" do
102
+ encode.secret = Rails.configuration.sso_secret
103
+ encode.sso_secret.should eq Rails.configuration.sso_secret
104
+ end
105
+
106
+ end
data/spec/spec_helper.rb CHANGED
@@ -18,7 +18,6 @@ Spork.prefork do
18
18
  require 'rspec/autorun'
19
19
  require 'rspec/mocks'
20
20
  require 'factory_girl'
21
- require 'perftools'
22
21
 
23
22
  # Requires supporting ruby files with custom matchers and macros, etc,
24
23
  # in spec/support/ and its subdirectories.
@@ -31,14 +30,6 @@ Spork.prefork do
31
30
 
32
31
  config.order = "random"
33
32
 
34
- config.before :suite do
35
- PerfTools::CpuProfiler.start("#{profile_directory}/rspec_profile")
36
- end
37
-
38
- config.after :suite do
39
- PerfTools::CpuProfiler.stop
40
- end
41
-
42
33
  def profile_directory
43
34
  directory = "/tmp/trivial_sso"
44
35
  system("mkdir #{directory}") unless Dir.exist? directory
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trivial_sso
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.3
4
+ version: 4.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - David J. Lee
@@ -9,34 +9,46 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-03 00:00:00.000000000 Z
12
+ date: 2015-02-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - '>='
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '4.0'
21
+ - - ">="
19
22
  - !ruby/object:Gem::Version
20
23
  version: 4.0.0
21
24
  type: :runtime
22
25
  prerelease: false
23
26
  version_requirements: !ruby/object:Gem::Requirement
24
27
  requirements:
25
- - - '>='
28
+ - - "~>"
29
+ - !ruby/object:Gem::Version
30
+ version: '4.0'
31
+ - - ">="
26
32
  - !ruby/object:Gem::Version
27
33
  version: 4.0.0
28
34
  - !ruby/object:Gem::Dependency
29
35
  name: activesupport
30
36
  requirement: !ruby/object:Gem::Requirement
31
37
  requirements:
32
- - - '>='
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.0'
41
+ - - ">="
33
42
  - !ruby/object:Gem::Version
34
43
  version: 4.0.0
35
44
  type: :runtime
36
45
  prerelease: false
37
46
  version_requirements: !ruby/object:Gem::Requirement
38
47
  requirements:
39
- - - '>='
48
+ - - "~>"
49
+ - !ruby/object:Gem::Version
50
+ version: '4.0'
51
+ - - ">="
40
52
  - !ruby/object:Gem::Version
41
53
  version: 4.0.0
42
54
  description: |-
@@ -49,17 +61,22 @@ executables: []
49
61
  extensions: []
50
62
  extra_rdoc_files: []
51
63
  files:
64
+ - CHANGELOG.md
65
+ - MIT-LICENSE
66
+ - README.md
52
67
  - lib/generators/templates/README
53
68
  - lib/generators/templates/sso_secret.rb
54
69
  - lib/generators/trivial_sso/install_generator.rb
70
+ - lib/trivial_sso.rb
71
+ - lib/trivial_sso/api.rb
55
72
  - lib/trivial_sso/error.rb
56
73
  - lib/trivial_sso/login.rb
74
+ - lib/trivial_sso/struct/secret.rb
75
+ - lib/trivial_sso/struct/un_wrap.rb
76
+ - lib/trivial_sso/struct/wrap.rb
57
77
  - lib/trivial_sso/version.rb
58
- - lib/trivial_sso.rb
59
- - MIT-LICENSE
60
- - README.md
61
- - CHANGELOG.md
62
- - spec/models/trivial_sso_spec.rb
78
+ - spec/lib/trivial_sso/api_spec.rb
79
+ - spec/lib/trivial_sso/login_spec.rb
63
80
  - spec/spec_helper.rb
64
81
  - spec/support/deferred_garbage_collection.rb
65
82
  homepage: https://github.com/nacengineer/trivial_sso
@@ -72,21 +89,22 @@ require_paths:
72
89
  - lib
73
90
  required_ruby_version: !ruby/object:Gem::Requirement
74
91
  requirements:
75
- - - '>='
92
+ - - ">="
76
93
  - !ruby/object:Gem::Version
77
94
  version: 1.9.3
78
95
  required_rubygems_version: !ruby/object:Gem::Requirement
79
96
  requirements:
80
- - - '>='
97
+ - - ">="
81
98
  - !ruby/object:Gem::Version
82
99
  version: '0'
83
100
  requirements: []
84
101
  rubyforge_project:
85
- rubygems_version: 2.0.3
102
+ rubygems_version: 2.4.5
86
103
  signing_key:
87
104
  specification_version: 4
88
105
  summary: A simple library to help with Single Sign On cookies
89
106
  test_files:
90
- - spec/models/trivial_sso_spec.rb
107
+ - spec/lib/trivial_sso/api_spec.rb
108
+ - spec/lib/trivial_sso/login_spec.rb
91
109
  - spec/spec_helper.rb
92
110
  - spec/support/deferred_garbage_collection.rb
@@ -1,66 +0,0 @@
1
- require 'active_support/core_ext'
2
-
3
- require 'trivial_sso'
4
- require 'forgery'
5
- require 'securerandom'
6
-
7
- describe TrivialSso do
8
-
9
- def before
10
- # Stub out our Rails config so we can test things properly.
11
- Rails.stubs(:configuration).returns(Rails::Application::Configuration.allocate)
12
- Rails.configuration.sso_secret = SecureRandom.hex(64)
13
- @user_name = Forgery::Internet.user_name
14
- @data = Forgery::LoremIpsum.words(20)
15
- @userdata = {'username' => @user_name, 'data' => @data}
16
- @expired_cookie = TrivialSso::Login.cookie(
17
- {'username' => 'testor'}, 2.seconds.ago
18
- )
19
- end
20
-
21
- it "does create cookie with userdata" do
22
- TrivialSso::Login.cookie(@userdata).should_not be_nil
23
- end
24
-
25
- # def test_create_cookie_and_decode_it
26
- # mycookie = TrivialSso::Login.cookie(@userdata)
27
- # data = TrivialSso::Login.decode_cookie(mycookie)
28
- # assert_equal data['data'], @data
29
- # end
30
-
31
- # def test_throw_exception_on_missing_username
32
- # assert_raise TrivialSso::Error::NoUsernameCookie do
33
- # mycookie = TrivialSso::Login.cookie("")
34
- # end
35
- # end
36
-
37
- # def test_expire_date_exists
38
- # # in a full rails environment, this will return an ActiveSupport::TimeWithZone
39
- # assert TrivialSso::Login.expire_date.is_a?(Time),
40
- # "proper Time object not returned"
41
- # end
42
-
43
- # def test_expire_date_is_in_future
44
- # assert (DateTime.now < TrivialSso::Login.expire_date),
45
- # "Expire date is in the past - cookie will expire immediatly."
46
- # end
47
-
48
- # def test_raise_exception_on_blank_cookie
49
- # assert_raise TrivialSso::Error::MissingCookie do
50
- # TrivialSso::Login.decode_cookie("")
51
- # end
52
- # end
53
-
54
- # def test_raise_exception_on_bad_cookie
55
- # assert_raise TrivialSso::Error::BadCookie do
56
- # TrivialSso::Login.decode_cookie("BAhbB0kiC2RqbGVlMgY6BkVUbCsHo17iTg")
57
- # end
58
- # end
59
-
60
- # def test_raise_exception_on_expired_cookie
61
- # assert_raise TrivialSso::Error::LoginExpired do
62
- # TrivialSso::Login.decode_cookie(@expired_cookie)
63
- # end
64
- # end
65
-
66
- end