maestrano 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.md +2 -2
- data/lib/maestrano.rb +19 -0
- data/lib/maestrano/sso.rb +5 -8
- data/lib/maestrano/sso/session.rb +37 -10
- data/lib/maestrano/version.rb +1 -1
- data/test/maestrano/maestrano_test.rb +44 -3
- data/test/maestrano/sso/session_test.rb +36 -9
- data/test/maestrano/sso_test.rb +28 -16
- metadata +1 -1
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -23,9 +23,9 @@ Maestrano Cloud Integration is currently in closed beta. Want to know more? Send
|
|
23
23
|
- - -
|
24
24
|
|
25
25
|
## Getting Setup
|
26
|
-
Before integrating with us you will need an API Key. Maestrano Cloud Integration being still in closed beta you will need to contact us beforehand to gain production access.
|
26
|
+
Before integrating with us you will need an App ID and API Key. Maestrano Cloud Integration being still in closed beta you will need to contact us beforehand to gain production access.
|
27
27
|
|
28
|
-
For testing purpose we provide an API Sandbox where you can freely obtain an API
|
28
|
+
For testing purpose we provide an API Sandbox where you can freely obtain an App ID and API Key. The sandbox is great to test single sign-on and API integration (e.g: billing API).
|
29
29
|
|
30
30
|
To get started just go to: http://api-sandbox.maestrano.io
|
31
31
|
|
data/lib/maestrano.rb
CHANGED
@@ -61,6 +61,25 @@ module Maestrano
|
|
61
61
|
self.config.api_token = "#{self.config.app_id}:#{self.config.api_key}"
|
62
62
|
end
|
63
63
|
|
64
|
+
# Check that app_id and api_key passed
|
65
|
+
# in argument match
|
66
|
+
def self.authenticate(app_id,api_key)
|
67
|
+
self.param(:app_id) == app_id && self.param(:api_key) == api_key
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.mask_user(user_uid,group_uid)
|
71
|
+
sanitized_user_uid = self.unmask_user(user_uid)
|
72
|
+
if Maestrano.param('user_creation_mode') == 'virtual'
|
73
|
+
return "#{sanitized_user_uid}.#{group_uid}"
|
74
|
+
else
|
75
|
+
return sanitized_user_uid
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.unmask_user(user_uid)
|
80
|
+
user_uid.split(".").first
|
81
|
+
end
|
82
|
+
|
64
83
|
# Get configuration parameter value
|
65
84
|
# E.g:
|
66
85
|
# Maestrano.param('api_key')
|
data/lib/maestrano/sso.rb
CHANGED
@@ -68,14 +68,11 @@ module Maestrano
|
|
68
68
|
# Takes the BaseUser hash representation and current session
|
69
69
|
# in arguments
|
70
70
|
def self.set_session(session, auth)
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
end
|
77
|
-
session[:mno_group_uid] = (sso_session[:group_uid] || sso_session['group_uid'])
|
78
|
-
end
|
71
|
+
Maestrano::SSO::Session.from_user_auth_hash(session,auth).save
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.unset_session(session)
|
75
|
+
session.delete(:maestrano) && session.delete('maestrano')
|
79
76
|
end
|
80
77
|
end
|
81
78
|
end
|
@@ -1,19 +1,37 @@
|
|
1
1
|
module Maestrano
|
2
2
|
module SSO
|
3
3
|
class Session
|
4
|
-
attr_accessor :session, :uid, :session_token, :recheck
|
4
|
+
attr_accessor :session, :uid, :session_token, :recheck, :group_uid
|
5
|
+
|
6
|
+
# Load a Maestrano::SSO::Session object from a
|
7
|
+
# hash generated by Maestrano::SSO::BaseUser#to_hash
|
8
|
+
def self.from_user_auth_hash(session, auth)
|
9
|
+
instance = self.new({})
|
10
|
+
instance.session = session
|
11
|
+
|
12
|
+
if (extra = (auth[:extra] || auth['extra'])) && (sso_session = (extra[:session] || extra['session']))
|
13
|
+
instance.uid = (sso_session[:uid] || sso_session['uid'])
|
14
|
+
instance.session_token = (sso_session[:token] || sso_session['token'])
|
15
|
+
instance.group_uid = (sso_session[:group_uid] || sso_session['group_uid'])
|
16
|
+
if recheck = (sso_session[:recheck] || sso_session['recheck'])
|
17
|
+
instance.recheck = recheck
|
18
|
+
end
|
19
|
+
end
|
20
|
+
return instance
|
21
|
+
end
|
5
22
|
|
6
23
|
def initialize(session)
|
7
24
|
self.session = session
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
25
|
+
begin
|
26
|
+
if mno_session = (self.session[:maestrano] || self.session['maestrano'])
|
27
|
+
decrypted_session = JSON.parse(Base64.decode64(mno_session))
|
28
|
+
self.uid = decrypted_session['uid']
|
29
|
+
self.session_token = decrypted_session['session']
|
30
|
+
self.recheck = Time.iso8601(decrypted_session['session_recheck'])
|
31
|
+
self.group_uid = decrypted_session['group_uid']
|
32
|
+
end
|
33
|
+
rescue
|
12
34
|
end
|
13
|
-
|
14
|
-
if self.uid.nil? || self.session_token.nil? || self.recheck.nil?
|
15
|
-
$stderr.puts "WARNING: Maestrano session information missing. User will have to relogin"
|
16
|
-
end
|
17
35
|
end
|
18
36
|
|
19
37
|
def remote_check_required?
|
@@ -49,7 +67,7 @@ module Maestrano
|
|
49
67
|
def valid?
|
50
68
|
if self.remote_check_required?
|
51
69
|
if perform_remote_check
|
52
|
-
self.
|
70
|
+
self.save
|
53
71
|
return true
|
54
72
|
else
|
55
73
|
return false
|
@@ -58,6 +76,15 @@ module Maestrano
|
|
58
76
|
return true
|
59
77
|
end
|
60
78
|
|
79
|
+
def save
|
80
|
+
self.session[:maestrano] = Base64.encode64({
|
81
|
+
uid: self.uid,
|
82
|
+
session: self.session_token,
|
83
|
+
session_recheck: self.recheck.utc.iso8601,
|
84
|
+
group_uid: self.group_uid
|
85
|
+
}.to_json)
|
86
|
+
end
|
87
|
+
|
61
88
|
end
|
62
89
|
end
|
63
90
|
end
|
data/lib/maestrano/version.rb
CHANGED
@@ -23,12 +23,53 @@ class MaestranoTest < Test::Unit::TestCase
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
context "param" do
|
27
|
+
should "return the specified parameters" do
|
28
|
+
@config.keys.each do |key|
|
29
|
+
assert Maestrano.param(key) == @config[key]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "authenticate" do
|
35
|
+
should "return true if app_id and api_key match" do
|
36
|
+
assert Maestrano.authenticate(Maestrano.param(:app_id),Maestrano.param(:api_key))
|
37
|
+
end
|
38
|
+
|
39
|
+
should "return false otherwise" do
|
40
|
+
assert !Maestrano.authenticate(Maestrano.param(:app_id) + 'a',Maestrano.param(:api_key))
|
41
|
+
assert !Maestrano.authenticate(Maestrano.param(:app_id),Maestrano.param(:api_key) + 'a')
|
29
42
|
end
|
30
43
|
end
|
31
44
|
|
45
|
+
context "mask_user_uid" do
|
46
|
+
should "return the composite uid if creation_mode is virtual" do
|
47
|
+
Maestrano.configure { |c| c.user_creation_mode = 'virtual' }
|
48
|
+
assert_equal 'usr-1.cld-1', Maestrano.mask_user('usr-1','cld-1')
|
49
|
+
end
|
50
|
+
|
51
|
+
should "not double up the composite uid" do
|
52
|
+
Maestrano.configure { |c| c.user_creation_mode = 'virtual' }
|
53
|
+
assert_equal 'usr-1.cld-1', Maestrano.mask_user('usr-1.cld-1','cld-1')
|
54
|
+
end
|
55
|
+
|
56
|
+
should "return the real uid if creation_mode is real" do
|
57
|
+
Maestrano.configure { |c| c.user_creation_mode = 'real' }
|
58
|
+
assert_equal 'usr-1', Maestrano.mask_user('usr-1','cld-1')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "unmask_user_uid" do
|
63
|
+
should "return the right uid if composite" do
|
64
|
+
assert_equal 'usr-1', Maestrano.unmask_user('usr-1.cld-1')
|
65
|
+
end
|
66
|
+
|
67
|
+
should "return the right uid if non composite" do
|
68
|
+
assert_equal 'usr-1', Maestrano.unmask_user('usr-1')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
32
73
|
context "configuration" do
|
33
74
|
should "return the right test parameters" do
|
34
75
|
Maestrano.configure { |config| config.environment = 'test' }
|
@@ -4,20 +4,47 @@ module Maestrano
|
|
4
4
|
module SSO
|
5
5
|
class SessionTest < Test::Unit::TestCase
|
6
6
|
setup do
|
7
|
+
@mno_session = {
|
8
|
+
uid: 'usr-1',
|
9
|
+
session: 'g4dfg4fdg8378d6acf45',
|
10
|
+
session_recheck: Time.now.utc.iso8601,
|
11
|
+
group_uid: 'cld-2'
|
12
|
+
}
|
7
13
|
@session = {
|
8
|
-
|
9
|
-
mno_session: 'g4dfg4fdg8378d6acf45',
|
10
|
-
mno_session_recheck: Time.now.utc.iso8601
|
14
|
+
maestrano: Base64.encode64(@mno_session.to_json)
|
11
15
|
}
|
12
16
|
end
|
13
17
|
|
14
18
|
should "initialize the sso session properly" do
|
15
19
|
sso_session = Maestrano::SSO::Session.new(@session)
|
16
|
-
assert_equal sso_session.uid, @
|
17
|
-
assert_equal sso_session.session_token, @
|
18
|
-
assert_equal sso_session.recheck, Time.iso8601(@
|
20
|
+
assert_equal sso_session.uid, @mno_session[:uid]
|
21
|
+
assert_equal sso_session.session_token, @mno_session[:session]
|
22
|
+
assert_equal sso_session.recheck, Time.iso8601(@mno_session[:session_recheck])
|
23
|
+
assert_equal sso_session.group_uid, @mno_session[:group_uid]
|
19
24
|
end
|
20
|
-
|
25
|
+
|
26
|
+
context "from_user_auth_hash" do
|
27
|
+
should "set the session correctly" do
|
28
|
+
sso_session = {}
|
29
|
+
auth = {
|
30
|
+
extra: {
|
31
|
+
session: {
|
32
|
+
uid: 'usr-1',
|
33
|
+
token: '15fg6d',
|
34
|
+
recheck: Time.now,
|
35
|
+
group_uid: 'cld-3'
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
39
|
+
sso_session = Maestrano::SSO::Session.from_user_auth_hash(@session,auth)
|
40
|
+
assert_equal sso_session.uid, auth[:extra][:session][:uid]
|
41
|
+
assert_equal sso_session.session_token, auth[:extra][:session][:token]
|
42
|
+
assert_equal sso_session.recheck.utc.iso8601, auth[:extra][:session][:recheck].utc.iso8601
|
43
|
+
assert_equal sso_session.group_uid, auth[:extra][:session][:group_uid]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
21
48
|
context "remote_check_required?" do
|
22
49
|
setup do
|
23
50
|
@sso_session = Maestrano::SSO::Session.new(@session)
|
@@ -87,13 +114,13 @@ module Maestrano
|
|
87
114
|
assert @sso_session.valid?
|
88
115
|
end
|
89
116
|
|
90
|
-
should "update session recheck timestamp if remote_check_required? and valid" do
|
117
|
+
should "update maestrano session with recheck timestamp if remote_check_required? and valid" do
|
91
118
|
recheck = (@sso_session.recheck + 600)
|
92
119
|
@sso_session.recheck = recheck
|
93
120
|
@sso_session.stubs(:remote_check_required?).returns(true)
|
94
121
|
@sso_session.stubs(:perform_remote_check).returns(true)
|
95
122
|
@sso_session.valid?
|
96
|
-
assert_equal @session[:
|
123
|
+
assert_equal JSON.parse(Base64.decode64(@session[:maestrano]))['session_recheck'], recheck.utc.iso8601
|
97
124
|
end
|
98
125
|
|
99
126
|
should "return false if remote_check_required? and invalid" do
|
data/test/maestrano/sso_test.rb
CHANGED
@@ -58,24 +58,36 @@ module Maestrano
|
|
58
58
|
response = Maestrano::SSO.build_response(response_document)
|
59
59
|
assert Maestrano::SSO.build_response(response_document) == response
|
60
60
|
end
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
61
|
+
|
62
|
+
context "session management" do
|
63
|
+
setup do
|
64
|
+
@session = {}
|
65
|
+
@auth = {
|
66
|
+
extra: {
|
67
|
+
session: {
|
68
|
+
uid: 'usr-1',
|
69
|
+
token: '15fg6d',
|
70
|
+
recheck: Time.now,
|
71
|
+
group_uid: 'cld-3'
|
72
|
+
}
|
71
73
|
}
|
72
74
|
}
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
75
|
+
end
|
76
|
+
|
77
|
+
should "set the session correctly" do
|
78
|
+
Maestrano::SSO.set_session(@session,@auth)
|
79
|
+
decrypt_session = JSON.parse(Base64.decode64(@session[:maestrano]))
|
80
|
+
assert_equal decrypt_session['uid'], @auth[:extra][:session][:uid]
|
81
|
+
assert_equal decrypt_session['session'], @auth[:extra][:session][:token]
|
82
|
+
assert_equal decrypt_session['session_recheck'], @auth[:extra][:session][:recheck].utc.iso8601
|
83
|
+
assert_equal decrypt_session['group_uid'], @auth[:extra][:session][:group_uid]
|
84
|
+
end
|
85
|
+
|
86
|
+
should "unset the session correctly" do
|
87
|
+
Maestrano::SSO.set_session(@session,@auth)
|
88
|
+
Maestrano::SSO.unset_session(@session)
|
89
|
+
assert @session[:maestrano].nil?
|
90
|
+
end
|
79
91
|
end
|
80
92
|
end
|
81
93
|
end
|