ruby-cleverdome 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/ruby-cleverdome.rb +124 -0
  2. metadata +77 -0
@@ -0,0 +1,124 @@
1
+ require 'nokogiri'
2
+ require 'savon'
3
+ require 'uuid'
4
+ require 'signed_xml'
5
+
6
+ module RubyCleverdome
7
+ class Client
8
+ def initialize(sso_endpoint, widgets_wsdl)
9
+ @sso_client = Savon.client(
10
+ endpoint: sso_endpoint,
11
+ namespace: 'urn:up-us:sso-service:service:v1',
12
+ # proxy: 'http://127.0.0.1:8888',
13
+ # log_level: :debug
14
+ )
15
+ @widgets_client = Savon.client(
16
+ wsdl: widgets_wsdl,
17
+ # proxy: 'http://127.0.0.1:8888',
18
+ element_form_default: :unqualified,
19
+ # log_level: :debug
20
+ )
21
+ end
22
+
23
+ def auth(provider, uid, private_key_file, certificate_file)
24
+ req = create_request(provider, uid)
25
+
26
+ req = sign_request(req, private_key_file, certificate_file)
27
+
28
+ resp = saml_call(req)
29
+ resp_doc = Nokogiri::XML::Document.parse(resp)
30
+ resp_doc.remove_namespaces!
31
+ check_resp(resp_doc)
32
+
33
+ session_id = resp_doc.xpath('//Assertion//AttributeStatement//Attribute[@Name="SessionID"]//AttributeValue')[0].content
34
+ session_id
35
+ end
36
+
37
+ def widgets_call(method, locals)
38
+ response = @widgets_client.call(
39
+ method,
40
+ :attributes => { 'xmlns' => 'http://tempuri.org/' },
41
+ message: { sessionID: 'EE282ABB-7BC3-42D3-BE98-9F8CE4217A12' } .merge(locals) )
42
+ end
43
+
44
+ def create_request(provider, uid)
45
+ builder = Nokogiri::XML::Builder.new do |xml|
46
+ xml['s'].Envelope('xmlns:s' => 'http://schemas.xmlsoap.org/soap/envelope/') {
47
+ xml['s'].Header {
48
+ xml.ActivityId(
49
+ UUID.new.generate,
50
+ 'CorrelationId' => UUID.new.generate,
51
+ :xmlns => 'http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics')
52
+ }
53
+ xml['s'].Body(
54
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
55
+ 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema') {
56
+ xml.AuthnRequest(
57
+ 'ID' => '_' + UUID.new.generate,
58
+ 'Version' => '2.0',
59
+ 'IssueInstant' => Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
60
+ 'IsPassive' => false,
61
+ 'ProtocolBinding' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP',
62
+ 'ProviderName' => provider,
63
+ :xmlns => 'urn:oasis:names:tc:SAML:2.0:protocol') {
64
+ xml.Issuer(
65
+ @provider,
66
+ 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameidformat:transient',
67
+ :xmlns => 'urn:oasis:names:tc:SAML:2.0:assertion')
68
+ xml.Signature(:xmlns => 'http://www.w3.org/2000/09/xmldsig#') {
69
+ xml.SignedInfo {
70
+ xml.CanonicalizationMethod( 'Algorithm' => 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315' ) { xml.text '' }
71
+ xml.SignatureMethod( 'Algorithm' => 'http://www.w3.org/2000/09/xmldsig#rsa-sha1' ) { xml.text '' }
72
+ xml.Reference( 'URI' => '' ) {
73
+ xml.Transforms {
74
+ xml.Transform( 'Algorithm' => 'http://www.w3.org/2000/09/xmldsig#enveloped-signature' ) { xml.text '' }
75
+ xml.Transform( 'Algorithm' => 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315' ) { xml.text '' }
76
+ }
77
+ xml.DigestMethod( 'Algorithm' => 'http://www.w3.org/2000/09/xmldsig#sha1' ) { xml.text '' }
78
+ xml.DigestValue
79
+ }
80
+ }
81
+ xml.SignatureValue
82
+ xml.KeyInfo {
83
+ xml.X509Data {
84
+ xml.X509Certificate
85
+ }
86
+ }
87
+ }
88
+ xml.Subject( :xmlns => 'urn:oasis:names:tc:SAML:2.0:assertion' ) {
89
+ xml.NameID(
90
+ uid,
91
+ 'Format'=>'urn:oasis:names:tc:SAML:2.0:nameid-format:transient')
92
+ }
93
+ xml.NameIDPolicy( 'AllowCreate' => true )
94
+ }
95
+ }
96
+ }
97
+ end
98
+
99
+ builder.to_xml
100
+ end
101
+
102
+ def sign_request(xml, private_key_file, certificate_file)
103
+ doc = SignedXml::Document(xml)
104
+ private_key = OpenSSL::PKey::RSA.new(File.new private_key_file)
105
+ certificate = OpenSSL::X509::Certificate.new(File.read certificate_file)
106
+ doc.sign(private_key, certificate)
107
+ doc.to_xml
108
+ end
109
+
110
+ def saml_call(req)
111
+ @sso_client.call( 'GetSSO', soap_action: 'urn:up-us:sso-service:service:v1/ISSOService/GetSSO', xml: req ).to_xml
112
+ end
113
+
114
+ def check_resp(resp_doc)
115
+ status = resp_doc.xpath('//Status//StatusCode')[0]['Value']
116
+
117
+ if status.casecmp('urn:oasis:names:tc:SAML:2.0:status:Success') != 0
118
+ raise status
119
+ end
120
+ end
121
+
122
+ private :create_request, :sign_request, :saml_call, :check_resp
123
+ end
124
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-cleverdome
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Alex Gorbunov
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-04-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: savon
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: signed_xml
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Ruby client to access CleverDome.
47
+ email: sanyo.gorbunov@gmail.com
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - lib/ruby-cleverdome.rb
53
+ homepage: https://github.com/SanyoGorbunov/ruby-cleverdome/
54
+ licenses: []
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubyforge_project:
73
+ rubygems_version: 1.8.28
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: RubyCleverdome
77
+ test_files: []