dot_net_services 0.3.0 → 0.4.0
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/LICENSE +21 -24
- data/README +26 -16
- data/Rakefile +65 -0
- data/lib/acs/saml_token_provider.rb +54 -0
- data/lib/acs/shared_secret_token_provider.rb +55 -0
- data/lib/acs/simple_api_auth_token_provider.rb +57 -0
- data/lib/acs/simple_web_token_provider.rb +54 -0
- data/lib/acs/token_constants.rb +112 -0
- data/lib/acs/token_info.rb +33 -0
- data/lib/acs/token_provider.rb +74 -0
- data/lib/acs/token_validator.rb +114 -0
- data/lib/common/dot_net_services_environment.rb +61 -0
- data/lib/common/environment.yml +23 -0
- data/lib/common/host_name_config.yml +45 -0
- data/lib/dot_net_services.rb +31 -144
- data/lib/service_bus/http_proxy.rb +34 -0
- data/lib/service_bus/locked_message_info.rb +34 -0
- data/lib/service_bus/message_buffer.rb +313 -0
- data/lib/service_bus/message_buffer_constants.rb +48 -0
- data/lib/service_bus/message_buffer_policy.rb +55 -0
- data/lib/service_bus/requests.rb +95 -0
- data/test/config/test_config.yml +40 -0
- data/test/dot_net_services_environment_test.rb +54 -0
- data/test/message_buffer_test.rb +96 -0
- data/test/token_test.rb +98 -0
- metadata +50 -48
- data/lib/dot_net_services/authentication.rb +0 -168
- data/lib/dot_net_services/error.rb +0 -4
- data/lib/dot_net_services/message_buffer.rb +0 -283
- data/lib/dot_net_services/session.rb +0 -308
- data/lib/net/http/create_mb.rb +0 -14
- data/lib/net/http/retrieve.rb +0 -14
- data/lib/net/http/subscribe.rb +0 -14
- data/lib/net/http/unsubscribe.rb +0 -14
- data/spec/integration/TestService/Service/AnonymousResourceService.cs +0 -9
- data/spec/integration/TestService/Service/App.config +0 -32
- data/spec/integration/TestService/Service/PlainTextService.cs +0 -37
- data/spec/integration/TestService/Service/Program.cs +0 -49
- data/spec/integration/TestService/Service/Properties/AssemblyInfo.cs +0 -33
- data/spec/integration/TestService/Service/ResourceContract.cs +0 -17
- data/spec/integration/TestService/Service/ResourceService.cs +0 -58
- data/spec/integration/TestService/Service/Service.csproj +0 -71
- data/spec/integration/TestService/TestService.sln +0 -33
- data/spec/integration/end_to_end_spec.rb +0 -84
- data/spec/integration/vmb_spec.rb +0 -30
- data/spec/spec_helper.rb +0 -23
- data/spec/unit/dot_net_services/authentication_spec.rb +0 -289
- data/spec/unit/dot_net_services/message_buffer_spec.rb +0 -161
- data/spec/unit/dot_net_services/session_spec.rb +0 -247
@@ -0,0 +1,96 @@
|
|
1
|
+
# Copyright (c) 2009, Persistent Systems Limited
|
2
|
+
#
|
3
|
+
# Redistribution and use, with or without modification, are permitted
|
4
|
+
# provided that the following conditions are met:
|
5
|
+
# - Redistributions of source code must retain the above copyright notice,
|
6
|
+
# this list of conditions and the following disclaimer.
|
7
|
+
# - Neither the name of Persistent Systems Limited nor the names of its contributors
|
8
|
+
# may be used to endorse or promote products derived from this software
|
9
|
+
# without specific prior written permission.
|
10
|
+
#
|
11
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
12
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
13
|
+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
14
|
+
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
15
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
16
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
17
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES LOSS OF USE, DATA, OR PROFITS
|
18
|
+
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
19
|
+
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
20
|
+
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
21
|
+
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
22
|
+
|
23
|
+
require 'test/unit'
|
24
|
+
require '../lib/service_bus/message_buffer'
|
25
|
+
require "../lib/acs/token_constants"
|
26
|
+
require 'yaml'
|
27
|
+
|
28
|
+
class MessageBufferTest < Test::Unit::TestCase
|
29
|
+
|
30
|
+
def setup
|
31
|
+
@config = YAML.load(File.open('config/test_config.yml'))
|
32
|
+
@issuer_name = @config['type_token']['issuer_name']
|
33
|
+
@issuer_secret = @config['type_token']['issuer_secret']
|
34
|
+
@solution_name = @config['simple_api_auth']['solution_name']
|
35
|
+
@service_name = TokenConstants.simple_auth_authentication_type
|
36
|
+
@issuer_name = @config['type_token']['issuer_name']
|
37
|
+
@issuer_key = @config['type_token']['issuer_key']
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_create_message_buffer
|
41
|
+
msg_buffer = MessageBuffer.new(@issuer_name, @issuer_key, @solution_name, @service_name, @config['proxy'])
|
42
|
+
msg_buffer_policy_obj = MessageBufferPolicy.new("Required", "None", "PT5M", 10)
|
43
|
+
assert msg_buffer.create_message_buffer("ThisIsNotAMessageBuffer", msg_buffer_policy_obj)
|
44
|
+
assert policy_msg = msg_buffer.policy("ThisIsNotAMessageBuffer")
|
45
|
+
assert policy_msg.match(/<entry/)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_delete_message_buffer
|
49
|
+
msg_buffer = MessageBuffer.new(@issuer_name, @issuer_key, @solution_name, @service_name, @config['proxy'])
|
50
|
+
msg_buffer_policy_obj = MessageBufferPolicy.new("Required", "None", "PT5M", 10)
|
51
|
+
assert msg_buffer.create_message_buffer("ThisIsNotAMessageBuffer", msg_buffer_policy_obj)
|
52
|
+
assert msg_buffer.delete_message_buffer("ThisIsNotAMessageBuffer")
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_send_message
|
56
|
+
msg_buffer = MessageBuffer.new(@issuer_name, @issuer_key, @solution_name, @service_name, @config['proxy'])
|
57
|
+
msg_buffer_policy_obj = MessageBufferPolicy.new("Required", "None", "PT5M", 10)
|
58
|
+
assert msg_buffer.create_message_buffer("ThisIsNotAMessageBuffer", msg_buffer_policy_obj)
|
59
|
+
message_text = 'This is not a message in ThisIsNotAMessageBuffer'
|
60
|
+
assert msg_buffer.send_message('ThisIsNotAMessageBuffer', message_text)
|
61
|
+
assert message = msg_buffer.retrieve_message('ThisIsNotAMessageBuffer')
|
62
|
+
assert message.include?(message_text)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_peek_lock
|
66
|
+
msg_buffer = MessageBuffer.new(@issuer_name, @issuer_key, @solution_name, @service_name, @config['proxy'])
|
67
|
+
msg_buffer_policy_obj = MessageBufferPolicy.new("Required", "None", "PT5M", 10)
|
68
|
+
assert msg_buffer.create_message_buffer("ThisIsNotAMessageBuffer", msg_buffer_policy_obj)
|
69
|
+
message_text = 'This is not a message in ThisIsNotAMessageBuffer'
|
70
|
+
assert msg_buffer.send_message('ThisIsNotAMessageBuffer', message_text)
|
71
|
+
assert locked_message_info = msg_buffer.peek_lock('ThisIsNotAMessageBuffer')
|
72
|
+
assert_not_nil locked_message_info.message_uri
|
73
|
+
assert_not_nil locked_message_info.lock_uri
|
74
|
+
assert_not_nil locked_message_info.lock_id
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_release_lock
|
78
|
+
msg_buffer = MessageBuffer.new(@issuer_name, @issuer_key, @solution_name, @service_name, @config['proxy'])
|
79
|
+
msg_buffer_policy_obj = MessageBufferPolicy.new("Required", "None", "PT5M", 10)
|
80
|
+
assert msg_buffer.create_message_buffer("ThisIsNotAMessageBuffer", msg_buffer_policy_obj)
|
81
|
+
message_text = 'This is not a message in ThisIsNotAMessageBuffer'
|
82
|
+
assert msg_buffer.send_message('ThisIsNotAMessageBuffer', message_text)
|
83
|
+
assert locked_message_info = msg_buffer.peek_lock('ThisIsNotAMessageBuffer')
|
84
|
+
assert msg_buffer.release_lock(locked_message_info.lock_uri)
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_delete_locked_message
|
88
|
+
msg_buffer = MessageBuffer.new(@issuer_name, @issuer_key, @solution_name, @service_name, @config['proxy'])
|
89
|
+
msg_buffer_policy_obj = MessageBufferPolicy.new("Required", "None", "PT5M", 10)
|
90
|
+
assert msg_buffer.create_message_buffer("ThisIsNotAMessageBuffer", msg_buffer_policy_obj)
|
91
|
+
message_text = 'This is not a message in ThisIsNotAMessageBuffer'
|
92
|
+
assert msg_buffer.send_message('ThisIsNotAMessageBuffer', message_text)
|
93
|
+
assert locked_message_info = msg_buffer.peek_lock('ThisIsNotAMessageBuffer')
|
94
|
+
assert msg_buffer.delete_locked_message(locked_message_info.message_uri, locked_message_info.lock_id)
|
95
|
+
end
|
96
|
+
end
|
data/test/token_test.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# Copyright (c) 2009, Persistent Systems Limited
|
2
|
+
#
|
3
|
+
# Redistribution and use, with or without modification, are permitted
|
4
|
+
# provided that the following conditions are met:
|
5
|
+
# - Redistributions of source code must retain the above copyright notice,
|
6
|
+
# this list of conditions and the following disclaimer.
|
7
|
+
# - Neither the name of Persistent Systems Limited nor the names of its contributors
|
8
|
+
# may be used to endorse or promote products derived from this software
|
9
|
+
# without specific prior written permission.
|
10
|
+
#
|
11
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
12
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
13
|
+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
14
|
+
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
15
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
16
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
17
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES LOSS OF USE, DATA, OR PROFITS
|
18
|
+
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
19
|
+
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
20
|
+
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
21
|
+
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
22
|
+
|
23
|
+
require 'test/unit'
|
24
|
+
require "../lib/acs/simple_api_auth_token_provider"
|
25
|
+
require "../lib/acs/shared_secret_token_provider"
|
26
|
+
require "../lib/acs/simple_web_token_provider"
|
27
|
+
require "../lib/acs/saml_token_provider"
|
28
|
+
require "../lib/acs/token_constants"
|
29
|
+
require "../lib/common/dot_net_services_environment"
|
30
|
+
require "../lib/acs/token_validator"
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
class TokenTest < Test::Unit::TestCase
|
35
|
+
def setup
|
36
|
+
@config = YAML.load(File.open('config/test_config.yml'))
|
37
|
+
@wrap_name = @config['simple_api_auth']['wrap_name']
|
38
|
+
@wrap_password = @config['simple_api_auth']['wrap_password']
|
39
|
+
@issuer_name = @config['type_token']['issuer_name']
|
40
|
+
@issuer_key = @config['type_token']['issuer_key']
|
41
|
+
@solution_name = @config['simple_api_auth']['solution_name']
|
42
|
+
@service_name = TokenConstants.simple_auth_authentication_type
|
43
|
+
@simple_api_auth_applies_to = @config['simple_api_auth']['applies_to']
|
44
|
+
@trusted_signing_key = @config['simple_api_auth']['trusted_key']
|
45
|
+
|
46
|
+
@request_uri = @config['type_token']['rest_request_uri']
|
47
|
+
@applies_to = @config['type_token']['rest_applies_to']
|
48
|
+
|
49
|
+
if @config['proxy']['http_web_proxy_server'] && @config['proxy']['http_web_proxy_port']
|
50
|
+
@http_web_proxy = Net::HTTP::Proxy(@config['proxy']['http_web_proxy_server'], @config['proxy']['http_web_proxy_port'])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_simple_api_auth_token
|
55
|
+
saatp = SimpleApiAuthTokenProvider.new(@wrap_name, @wrap_password, @config['proxy'])
|
56
|
+
request_uri = "https://#{@solution_name}.#{DotNetServicesEnvironment.acm_host_name}/#{@service_name}/"
|
57
|
+
token_info = saatp.token(request_uri, @simple_api_auth_applies_to)
|
58
|
+
assert token_valid?(token_info.token), "TOKEN VALIDITY FAILED!"
|
59
|
+
assert token_claims_valid?(token_info.token), "TOKEN VALIDITY FAILED!"
|
60
|
+
assert_not_nil token_info.token
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_shared_secret_token
|
64
|
+
sstp = SharedSecretTokenProvider.new(@issuer_name, @issuer_key, @config['proxy'])
|
65
|
+
token_info = sstp.token(@request_uri, @applies_to)
|
66
|
+
assert_not_nil token_info.token, "Shared Secret Token acquired is nil" #msg_buffer_uri = applies_to
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_simple_web_token
|
70
|
+
simple_web_token_provider = SimpleWebTokenProvider.new(@issuer_name, @issuer_key, @config['proxy'])
|
71
|
+
token_info = simple_web_token_provider.token(@request_uri, @applies_to)
|
72
|
+
assert_not_nil token_info.token
|
73
|
+
end
|
74
|
+
|
75
|
+
# TODO: Replace SimpleWebTokenProvider with SamlToken once Saml token is implemented.
|
76
|
+
def test_saml_token
|
77
|
+
#~ saml_token_provider = SimpleWebTokenProvider.new(saml_token, @http_web_proxy)
|
78
|
+
#~ token_info = saml_token_provider.token(@request_uri, @applies_to)
|
79
|
+
#~ assert_not_nil token_info.token
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def token_valid?(token)
|
85
|
+
tv = TokenValidator.new(@service_name, @solution_name, @simple_api_auth_applies_to, @trusted_signing_key, @service_name + " " + token)
|
86
|
+
tv.validate
|
87
|
+
end
|
88
|
+
|
89
|
+
def token_claims_valid?(token)
|
90
|
+
tv = TokenValidator.new(@service_name, @solution_name, @simple_api_auth_applies_to, @trusted_signing_key, @service_name + " " + token)
|
91
|
+
tv.populate_claims(CGI::unescape(token))
|
92
|
+
valid_claim = tv.validate_claims({"ViewRegion"=>"true"})
|
93
|
+
invalid_claim = tv.validate_claims({"InvalidClaim"=>"true"})
|
94
|
+
incorrect_claim = tv.validate_claims({"ViewRegion"=>"false"})
|
95
|
+
valid_claim && !invalid_claim && !incorrect_claim
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
metadata
CHANGED
@@ -1,64 +1,66 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dot_net_services
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- ""
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-11-13 00:00:00 +05:30
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: ruby-hmac
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.3.1
|
24
|
+
version:
|
25
|
+
description: Ruby wrapper for .NET services
|
26
|
+
email: ""
|
18
27
|
executables: []
|
19
28
|
|
20
29
|
extensions: []
|
21
30
|
|
22
|
-
extra_rdoc_files:
|
23
|
-
|
24
|
-
files:
|
25
|
-
- lib/dot_net_services
|
26
|
-
- lib/dot_net_services/authentication.rb
|
27
|
-
- lib/dot_net_services/error.rb
|
28
|
-
- lib/dot_net_services/message_buffer.rb
|
29
|
-
- lib/dot_net_services/session.rb
|
30
|
-
- lib/dot_net_services.rb
|
31
|
-
- lib/net
|
32
|
-
- lib/net/http
|
33
|
-
- lib/net/http/create_mb.rb
|
34
|
-
- lib/net/http/retrieve.rb
|
35
|
-
- lib/net/http/subscribe.rb
|
36
|
-
- lib/net/http/unsubscribe.rb
|
37
|
-
- spec/integration
|
38
|
-
- spec/integration/end_to_end_spec.rb
|
39
|
-
- spec/integration/TestService
|
40
|
-
- spec/integration/TestService/Service
|
41
|
-
- spec/integration/TestService/Service/AnonymousResourceService.cs
|
42
|
-
- spec/integration/TestService/Service/App.config
|
43
|
-
- spec/integration/TestService/Service/PlainTextService.cs
|
44
|
-
- spec/integration/TestService/Service/Program.cs
|
45
|
-
- spec/integration/TestService/Service/Properties
|
46
|
-
- spec/integration/TestService/Service/Properties/AssemblyInfo.cs
|
47
|
-
- spec/integration/TestService/Service/ResourceContract.cs
|
48
|
-
- spec/integration/TestService/Service/ResourceService.cs
|
49
|
-
- spec/integration/TestService/Service/Service.csproj
|
50
|
-
- spec/integration/TestService/TestService.sln
|
51
|
-
- spec/integration/vmb_spec.rb
|
52
|
-
- spec/spec_helper.rb
|
53
|
-
- spec/unit
|
54
|
-
- spec/unit/dot_net_services
|
55
|
-
- spec/unit/dot_net_services/authentication_spec.rb
|
56
|
-
- spec/unit/dot_net_services/message_buffer_spec.rb
|
57
|
-
- spec/unit/dot_net_services/session_spec.rb
|
31
|
+
extra_rdoc_files:
|
58
32
|
- README
|
59
33
|
- LICENSE
|
34
|
+
files:
|
35
|
+
- LICENSE
|
36
|
+
- README
|
37
|
+
- Rakefile
|
38
|
+
- lib/acs/saml_token_provider.rb
|
39
|
+
- lib/acs/shared_secret_token_provider.rb
|
40
|
+
- lib/acs/simple_api_auth_token_provider.rb
|
41
|
+
- lib/acs/simple_web_token_provider.rb
|
42
|
+
- lib/acs/token_constants.rb
|
43
|
+
- lib/acs/token_info.rb
|
44
|
+
- lib/acs/token_provider.rb
|
45
|
+
- lib/acs/token_validator.rb
|
46
|
+
- lib/common/dot_net_services_environment.rb
|
47
|
+
- lib/common/environment.yml
|
48
|
+
- lib/common/host_name_config.yml
|
49
|
+
- lib/dot_net_services.rb
|
50
|
+
- lib/service_bus/http_proxy.rb
|
51
|
+
- lib/service_bus/locked_message_info.rb
|
52
|
+
- lib/service_bus/message_buffer.rb
|
53
|
+
- lib/service_bus/message_buffer_constants.rb
|
54
|
+
- lib/service_bus/message_buffer_policy.rb
|
55
|
+
- lib/service_bus/requests.rb
|
56
|
+
- test/config/test_config.yml
|
57
|
+
- test/dot_net_services_environment_test.rb
|
58
|
+
- test/message_buffer_test.rb
|
59
|
+
- test/token_test.rb
|
60
60
|
has_rdoc: true
|
61
|
-
homepage:
|
61
|
+
homepage:
|
62
|
+
licenses: []
|
63
|
+
|
62
64
|
post_install_message:
|
63
65
|
rdoc_options: []
|
64
66
|
|
@@ -78,10 +80,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
80
|
version:
|
79
81
|
requirements: []
|
80
82
|
|
81
|
-
rubyforge_project:
|
82
|
-
rubygems_version: 1.3.
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 1.3.5
|
83
85
|
signing_key:
|
84
|
-
specification_version:
|
85
|
-
summary:
|
86
|
+
specification_version: 3
|
87
|
+
summary: Ruby wrapper for .NET services
|
86
88
|
test_files: []
|
87
89
|
|
@@ -1,168 +0,0 @@
|
|
1
|
-
require 'cgi'
|
2
|
-
require 'net/http'
|
3
|
-
require 'net/https'
|
4
|
-
|
5
|
-
module DotNetServices
|
6
|
-
# This stores the token and expiration time. The default expiration
|
7
|
-
# time is 1 day.
|
8
|
-
module Authentication # :nodoc:
|
9
|
-
@cache = {}
|
10
|
-
|
11
|
-
# Authentication token.
|
12
|
-
class Token # :nodoc:
|
13
|
-
|
14
|
-
attr_reader :value, :expiry
|
15
|
-
|
16
|
-
# Create a new authentication token; defaults to expire in one day.
|
17
|
-
def initialize(value, expiry = Time.now + 24 *60 * 60)
|
18
|
-
# workaround for a known bug
|
19
|
-
match = value.match(/^([^=]+==).*/)
|
20
|
-
if match
|
21
|
-
@value = match[1]
|
22
|
-
@expiry = expiry
|
23
|
-
else
|
24
|
-
raise AuthenticationError,
|
25
|
-
"Response from access control service doesn't seem to contain a valid authentication token:\n" +
|
26
|
-
value.inspect
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def expired?
|
31
|
-
@expiry < Time.now
|
32
|
-
end
|
33
|
-
|
34
|
-
def to_s
|
35
|
-
@value
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# Standard Username and Password authenticator.
|
40
|
-
class UsernamePassword # :nodoc:
|
41
|
-
|
42
|
-
attr_reader :token, :username, :password
|
43
|
-
|
44
|
-
def initialize(username, password, token = nil)
|
45
|
-
@username, @password = username, password
|
46
|
-
@token = token
|
47
|
-
end
|
48
|
-
|
49
|
-
def authenticate
|
50
|
-
return if @token and not @token.expired?
|
51
|
-
@token = acquire_token
|
52
|
-
end
|
53
|
-
|
54
|
-
# Enhance the request with the identity token provided by the identity service.
|
55
|
-
def enhance(request)
|
56
|
-
authenticate
|
57
|
-
request['X-MS-Identity-Token'] = token.value
|
58
|
-
end
|
59
|
-
|
60
|
-
def ==(other)
|
61
|
-
other.is_a?(Authentication::UsernamePassword) && @username == other.username && @password == other.password
|
62
|
-
end
|
63
|
-
alias :eql? :==
|
64
|
-
|
65
|
-
def hash
|
66
|
-
@hash ||= @username.hash & @password.hash
|
67
|
-
end
|
68
|
-
|
69
|
-
# Retrieve a token from the DotNetServices token issuing service.
|
70
|
-
def acquire_token
|
71
|
-
http = Net::HTTP.new(DotNetServices.identity_host, 443)
|
72
|
-
http.use_ssl = true
|
73
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
74
|
-
|
75
|
-
escaped_username = CGI.escape(@username)
|
76
|
-
escaped_password = CGI.escape(@password)
|
77
|
-
begin
|
78
|
-
response = http.get("/issuetoken.aspx?u=#{escaped_username}&p=#{escaped_password}")
|
79
|
-
rescue => e
|
80
|
-
raise AuthenticationError, "Failed to obtain authentication token. Original error of type #{e.class} " +
|
81
|
-
"was overridden to prevent logging security-sensitive data"
|
82
|
-
end
|
83
|
-
|
84
|
-
unless response.is_a?(Net::HTTPOK)
|
85
|
-
raise AuthenticationError, "Failed to obtain a security token from the identity service. HTTP response was #{response.class.name}"
|
86
|
-
end
|
87
|
-
|
88
|
-
Token.new(response.body)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
# Certificate authenticator. NOT YET IMPLEMENTED
|
93
|
-
class Certificate # :nodoc:
|
94
|
-
def authenticate
|
95
|
-
raise "not implemented"
|
96
|
-
end
|
97
|
-
|
98
|
-
def enhance(request)
|
99
|
-
raise "not implemented"
|
100
|
-
end
|
101
|
-
|
102
|
-
def hash
|
103
|
-
1
|
104
|
-
end
|
105
|
-
|
106
|
-
def ==(other)
|
107
|
-
other.is_a?(Certificate)
|
108
|
-
end
|
109
|
-
alias :eql? :==
|
110
|
-
end
|
111
|
-
|
112
|
-
# An anonymous authenticator. It is used as a stand-in for
|
113
|
-
# services which do not require authentication.
|
114
|
-
class Anonymous # :nodoc:
|
115
|
-
def authenticate() end
|
116
|
-
def enhance(request) end
|
117
|
-
def ==(another) another.is_a?(Anonymous) end
|
118
|
-
alias :eql? :==
|
119
|
-
def hash() -1 end
|
120
|
-
end
|
121
|
-
|
122
|
-
class << self
|
123
|
-
def setup(auth_data)
|
124
|
-
authenticator = create_authenticator(auth_data)
|
125
|
-
@cache[authenticator] ||= authenticator
|
126
|
-
end
|
127
|
-
|
128
|
-
# Create an authenticator based on the data provided.
|
129
|
-
def create_authenticator(auth_data)
|
130
|
-
if auth_data.nil?
|
131
|
-
Authentication::Anonymous.new
|
132
|
-
elsif !auth_data.is_a? Hash
|
133
|
-
auth_data
|
134
|
-
elsif auth_data.empty?
|
135
|
-
Authentication::Anonymous.new
|
136
|
-
else
|
137
|
-
auth_data_copy = auth_data.dup
|
138
|
-
username = auth_data_copy.delete(:username)
|
139
|
-
password = auth_data_copy.delete(:password)
|
140
|
-
certificate = auth_data_copy.delete(:certificate)
|
141
|
-
|
142
|
-
unless auth_data_copy.empty?
|
143
|
-
raise ArgumentError, "Auth data contains unknown options: #{auth_data.keys.inspect}"
|
144
|
-
end
|
145
|
-
|
146
|
-
if username && !password
|
147
|
-
raise ArgumentError, "Auth data specifies username, but no password."
|
148
|
-
elsif password && !username
|
149
|
-
raise ArgumentError, "Auth data specifies password, but no username."
|
150
|
-
elsif (username || password) && certificate
|
151
|
-
raise ArgumentError, "Cannot determine authentication type from auth data."
|
152
|
-
elsif username && password
|
153
|
-
Authentication::UsernamePassword.new(username, password)
|
154
|
-
elsif certificate
|
155
|
-
Authentication::Certificate.new
|
156
|
-
else
|
157
|
-
raise "Internal error. Unable to setup authenticator from #{auth_data.inspect}"
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
def clear_cache!
|
163
|
-
@cache.clear
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
end
|
168
|
-
end
|