omniauth-healthvault 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .idea/
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## v0.0.1
2
+
3
+ * Initial release. PKCS#12 key format (.p12 or .pfx) should be used as a container for public/private key pair.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in omniauth-healthvault.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Andrey Voronkov
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # OmniAuth Healthvault
2
+
3
+ This is the unofficial OmniAuth strategy for authenticating to Microsoft HealthVault. To use it, you'll need to sign up for an application id on the Microsoft HealthVault [Application Configuration Center](https://config.healthvault.com) and have a public and private keys packed in PKCS#12 file (.pfx or .p12).
4
+
5
+ ## Generating .cer file (public key in DER format) from a PKCS#12
6
+
7
+ .cer file is one of the required conditions to register your application in Application Configuration Center:
8
+
9
+ openssl pkcs12 -in my.pfx -clcerts -nokeys | openssl x509 -inform PEM -outform DER -out my.cer
10
+
11
+ ## Basic Usage
12
+
13
+ use OmniAuth::Builder do
14
+ provider :healthvault, ENV['HEALTHVAULT_APP_ID'], ENV['HEALTHVAULT_PKCS12_CERT_LOCATION']
15
+ end
16
+
17
+ ## Preproduction Usage
18
+
19
+ provider :github, ENV['HEALTHVAULT_APP_ID'], ENV['HEALTHVAULT_PKCS12_FILE_LOCATION'], {
20
+ platform_url: 'https://platform.healthvault-ppe.com/platform/wildcat.ashx',
21
+ shell_url: 'https://account.healthvault-ppe.com/redirect.aspx'
22
+ }
23
+
24
+ ## License
25
+
26
+ Copyright (c) 2013 Andrey Voronkov and Swissmed Mobile Inc.
27
+
28
+ MIT License
29
+
30
+ Permission is hereby granted, free of charge, to any person obtaining
31
+ a copy of this software and associated documentation files (the
32
+ "Software"), to deal in the Software without restriction, including
33
+ without limitation the rights to use, copy, modify, merge, publish,
34
+ distribute, sublicense, and/or sell copies of the Software, and to
35
+ permit persons to whom the Software is furnished to do so, subject to
36
+ the following conditions:
37
+
38
+ The above copyright notice and this permission notice shall be
39
+ included in all copies or substantial portions of the Software.
40
+
41
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
42
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
43
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
44
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
45
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
46
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
47
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,151 @@
1
+ require 'builder'
2
+ require 'faraday'
3
+ require 'multi_xml'
4
+
5
+ module OmniAuth
6
+ module Strategies
7
+ # Authenticate to Microsoft HealthVault service and retrieve basic user information.
8
+ # Documentation available here:
9
+ # http://msdn.microsoft.com/library/jj863179
10
+ #
11
+ # @example Basic Usage
12
+ # use OmniAuth::Builder do
13
+ # provider :healthvault, ENV['HEALTHVAULT_APP_ID'], ENV['HEALTHVAULT_PKCS12_CERT_LOCATION']
14
+ # end
15
+ #
16
+ class Healthvault
17
+ include OmniAuth::Strategy
18
+
19
+ PLATFORM_VERSION = '1.12.1002.8529'
20
+
21
+ args [:app_id, :pkcs_12_location]
22
+
23
+ option :name, 'healthvault'
24
+
25
+ option :app_id, nil
26
+
27
+ option :platform_url, 'https://platform.healthvault.com/platform/wildcat.ashx'
28
+ option :shell_url, 'https://account.healthvault.com/redirect.aspx'
29
+
30
+ def request_phase
31
+ url = "#{options[:shell_url]}?target=AUTH&targetqs=appid%3D#{options[:app_id]}"
32
+ redirect url
33
+ end
34
+
35
+ def callback_phase
36
+ if request.params['target'] == 'AppAuthSuccess'
37
+ @certificate = OpenSSL::PKCS12.new(File.read(options[:pkcs_12_location]), nil)
38
+ @wctoken = request.params['wctoken']
39
+ @shared_secret = Base64.strict_encode64(SecureRandom.hex)
40
+ @app_auth_token = create_authenticated_session_token
41
+ @raw_info = get_person_info
42
+ end
43
+ super
44
+ end
45
+
46
+ uid { @raw_info['person_id'] }
47
+ info { { name: @raw_info['name'] } }
48
+ extra { { raw_info: @raw_info } }
49
+
50
+ private
51
+
52
+ def send_request(body)
53
+ conn = ::Faraday.new(url: options[:platform_url]) do |faraday|
54
+ faraday.request :url_encoded
55
+ faraday.response :logger
56
+ faraday.adapter ::Faraday.default_adapter
57
+ end
58
+ conn.post do |i|
59
+ i.headers['Content-Type'] = 'text/xml'
60
+ i.body = body
61
+ end
62
+ end
63
+
64
+ def create_authenticated_session_token
65
+ response = send_request(build_create_authenticated_session_token_request)
66
+ parse_create_authenticated_session_token_response(response.body)
67
+ end
68
+
69
+ def get_person_info
70
+ if @app_auth_token.present?
71
+ body = build_get_person_info_request
72
+ response = send_request(body)
73
+ parse_get_person_info_response(response.body)
74
+ end
75
+ end
76
+
77
+ def build_get_person_info_request
78
+ info = ::Builder::XmlMarkup.new.info
79
+ header = ::Builder::XmlMarkup.new.header do |header|
80
+ header.method 'GetPersonInfo'
81
+ header.tag! 'method-version', 1
82
+ header.tag! 'auth-session' do
83
+ header.tag! 'auth-token', @app_auth_token
84
+ header.tag! 'user-auth-token', @wctoken
85
+ end
86
+ header.language 'en'
87
+ header.country 'US'
88
+ header.tag! 'msg-time', Time.now.to_datetime.rfc3339
89
+ header.tag! 'msg-ttl', 36000
90
+ header.version PLATFORM_VERSION
91
+ header.tag! 'info-hash' do
92
+ header.tag! 'hash-data', Base64.strict_encode64(OpenSSL::Digest::SHA1.digest(info)), 'algName' => 'SHA1'
93
+ end
94
+ end
95
+ body = ::Builder::XmlMarkup.new
96
+ body.tag!('wc-request:request', 'xmlns:wc-request' => 'urn:com.microsoft.wc.request') do
97
+ body.auth do
98
+ body.tag! 'hmac-data', Base64.strict_encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, Base64.decode64(@shared_secret), header)), 'algName' => 'HMACSHA1'
99
+ end
100
+ body << header
101
+ body << info
102
+ end
103
+ end
104
+
105
+ def parse_get_person_info_response(response_body)
106
+ result = ::MultiXml.parse(response_body)
107
+ result['response']['info']['person_info'] rescue nil
108
+ end
109
+
110
+ def build_create_authenticated_session_token_request
111
+ content = ::Builder::XmlMarkup.new
112
+ content = content.content do
113
+ content.tag! 'app-id', options[:app_id]
114
+ content.tag! 'shared-secret' do
115
+ content.tag! 'hmac-alg', @shared_secret, 'algName' => 'HMACSHA1'
116
+ end
117
+ end
118
+ body = ::Builder::XmlMarkup.new
119
+ body.tag!('wc-request:request', 'xmlns:wc-request' => 'urn:com.microsoft.wc.request') do
120
+ body.header do
121
+ body.method 'CreateAuthenticatedSessionToken'
122
+ body.tag! 'method-version', 1
123
+ body.tag! 'app-id', options[:app_id]
124
+ body.language 'en'
125
+ body.country 'US'
126
+ body.tag! 'msg-time', Time.now.to_datetime.rfc3339
127
+ body.tag! 'msg-ttl', 36000
128
+ body.version PLATFORM_VERSION
129
+ end
130
+ body.info do
131
+ body.tag! 'auth-info' do
132
+ body.tag! 'app-id', options[:app_id]
133
+ body.credential do
134
+ body.appserver do
135
+ body.sig Base64.strict_encode64(@certificate.key.sign(OpenSSL::Digest::SHA1.new, content)), 'digestMethod' => 'SHA1',
136
+ 'sigMethod' => 'RSA-SHA1', 'thumbprint' => OpenSSL::Digest::SHA1.hexdigest(@certificate.certificate.to_der).upcase
137
+ body << content
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
144
+
145
+ def parse_create_authenticated_session_token_response(response_body)
146
+ result = ::MultiXml.parse(response_body)
147
+ result['response']['info']['token']['__content__'] rescue nil
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,5 @@
1
+ module Omniauth
2
+ module Healthvault
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ require 'omniauth-healthvault/version'
2
+ require 'omniauth/strategies/healthvault'
3
+
4
+ module Omniauth
5
+ module Healthvault
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'omniauth-healthvault/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "omniauth-healthvault"
8
+ gem.version = Omniauth::Healthvault::VERSION
9
+ gem.authors = ["Andrey Voronkov"]
10
+ gem.email = ["andrey.voronkov@medm.com"]
11
+ gem.description = %q{This is the unofficial OmniAuth strategy for authenticating to Microsoft HealthVault.}
12
+ gem.summary = %q{This is the unofficial OmniAuth strategy for authenticating to Microsoft HealthVault.}
13
+ gem.homepage = "https://github.com/Antiarchitect/omniauth-healthvault"
14
+ gem.files = `git ls-files`.split($/)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.require_paths = ["lib"]
18
+
19
+ gem.add_dependency 'builder', '~> 3.0'
20
+ gem.add_dependency 'faraday', '~> 0.8'
21
+ gem.add_dependency 'multi_xml', '~> 0.5'
22
+ gem.add_dependency 'omniauth', '~> 1.1.0'
23
+ end
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: omniauth-healthvault
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Andrey Voronkov
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ version_requirements: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ none: false
21
+ name: builder
22
+ type: :runtime
23
+ prerelease: false
24
+ requirement: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ version: '3.0'
29
+ none: false
30
+ - !ruby/object:Gem::Dependency
31
+ version_requirements: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: '0.8'
36
+ none: false
37
+ name: faraday
38
+ type: :runtime
39
+ prerelease: false
40
+ requirement: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: '0.8'
45
+ none: false
46
+ - !ruby/object:Gem::Dependency
47
+ version_requirements: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ~>
50
+ - !ruby/object:Gem::Version
51
+ version: '0.5'
52
+ none: false
53
+ name: multi_xml
54
+ type: :runtime
55
+ prerelease: false
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ version: '0.5'
61
+ none: false
62
+ - !ruby/object:Gem::Dependency
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ~>
66
+ - !ruby/object:Gem::Version
67
+ version: 1.1.0
68
+ none: false
69
+ name: omniauth
70
+ type: :runtime
71
+ prerelease: false
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 1.1.0
77
+ none: false
78
+ description: This is the unofficial OmniAuth strategy for authenticating to Microsoft
79
+ HealthVault.
80
+ email:
81
+ - andrey.voronkov@medm.com
82
+ executables: []
83
+ extensions: []
84
+ extra_rdoc_files: []
85
+ files:
86
+ - .gitignore
87
+ - CHANGELOG.md
88
+ - Gemfile
89
+ - LICENSE.txt
90
+ - README.md
91
+ - Rakefile
92
+ - lib/omniauth-healthvault.rb
93
+ - lib/omniauth-healthvault/version.rb
94
+ - lib/omniauth/strategies/healthvault.rb
95
+ - omniauth-healthvault.gemspec
96
+ homepage: https://github.com/Antiarchitect/omniauth-healthvault
97
+ licenses: []
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ none: false
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ! '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ none: false
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 1.8.24
117
+ signing_key:
118
+ specification_version: 3
119
+ summary: This is the unofficial OmniAuth strategy for authenticating to Microsoft
120
+ HealthVault.
121
+ test_files: []
122
+ has_rdoc: