ruby-cleverdome 0.0.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.
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: []