omniauth-latvija 2.0.0 → 6.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 875159da4f23d72890c3da6c24f1b174d197f6ec
4
- data.tar.gz: af5a474b33c9165faf67a14a61b8785e0567a456
2
+ SHA256:
3
+ metadata.gz: b501b35e3685a3963f0f38ec951a345aae8d534dd3ce323566775eda8bb048bf
4
+ data.tar.gz: f9e4ef1dff0294bd8ff5a4389be6bb6964a55b7fe5534c2c266d957515e33a4b
5
5
  SHA512:
6
- metadata.gz: 36fc98917bfe2547d020287fc90f6c4dcc986722c903be7acf49a3ffe56d7899d097661a0620352bb95646cfbc6db250cf911b89b2bbf603db1e3cc5125defed
7
- data.tar.gz: 1f5947b59168bf23f22ab34c7b4b5ec83c2e01f4402a7035400bd885d00a3751d6eebffa741902f2c149a5d730b1f9ffb038f84015f40b6c514fe624290fe862
6
+ metadata.gz: 03c8dc65d2f8a0290756e5b91d8b01bf9fff8dbbf038685566223e3ebb710fc5080e54c91c2b85fc22a32baa182fff4a00c7158d1f9868fce257ea7d3bc6de45
7
+ data.tar.gz: 13a84d4d7b8caa0dbc8685fa7f18eb322d1319ce22f074aeefaa1cd169593abd4f7f3c0853174d640de0b69716c14a507abc04fa33e04272e130393e49118145
data/README.md CHANGED
@@ -19,7 +19,7 @@ Provides the following authentication types:
19
19
  ## Installation
20
20
 
21
21
  ```ruby
22
- gem 'omniauth-latvija', '~> 2.0'
22
+ gem 'omniauth-latvija'
23
23
  ```
24
24
 
25
25
  ## Usage
@@ -39,6 +39,36 @@ Rails.application.config.middleware.use OmniAuth::Builder do
39
39
  end
40
40
  ```
41
41
 
42
+
43
+ ## Auth Hash
44
+
45
+ Here's an example hash available in `request.env['omniauth.auth']`
46
+
47
+ ```ruby
48
+ {
49
+ provider: 'latvija',
50
+ uid: 'PK:12345612345',
51
+ info: {
52
+ name: 'JANIS BERZINS',
53
+ first_name: 'JANIS',
54
+ last_name: 'BERZINS',
55
+ private_personal_identifier: '12345612345'
56
+ },
57
+ extra: {
58
+ raw_info: {
59
+ givenname: 'JANIS',
60
+ surname: 'BERZINS',
61
+ privatepersonalidentifier: '12345612345',
62
+ historical_privatepersonalidentifier: [],
63
+ not_valid_before: '2019-05-09T07:29:41Z',
64
+ not_valid_on_or_after: '2019-05-09T08:29:41Z'
65
+ },
66
+ authentication_method: 'SWEDBANK',
67
+ legacy_uids: ['JANIS BERZINS, 12345612345']
68
+ }
69
+ }
70
+ ```
71
+
42
72
  ## References
43
73
 
44
74
  * http://docs.oasis-open.org/wsfed/federation/v1.2/os/ws-federation-1.2-spec-os.html
@@ -1,5 +1,5 @@
1
1
  module OmniAuth
2
2
  module Latvija
3
- VERSION = '2.0.0'
3
+ VERSION = '6.1.0'
4
4
  end
5
5
  end
@@ -1,6 +1,7 @@
1
1
  require 'time'
2
2
  require 'openssl'
3
3
  require 'digest/sha1'
4
+ require 'digest/sha2'
4
5
  require 'xmlenc'
5
6
  require 'nokogiri'
6
7
  require 'omniauth/strategies/latvija/response'
@@ -34,6 +35,23 @@ module OmniAuth::Strategies
34
35
  option :certificate, nil
35
36
  option :private_key, nil
36
37
 
38
+ info do
39
+ {
40
+ name: full_name,
41
+ first_name: raw_info['givenname'],
42
+ last_name: raw_info['surname'],
43
+ private_personal_identifier: raw_info['privatepersonalidentifier']
44
+ }
45
+ end
46
+
47
+ extra do
48
+ {
49
+ raw_info: raw_info,
50
+ authentication_method: @response.authentication_method,
51
+ legacy_uids: legacy_uids
52
+ }
53
+ end
54
+
37
55
  def request_phase
38
56
  params = {
39
57
  wa: 'wsignin1.0',
@@ -64,18 +82,31 @@ module OmniAuth::Strategies
64
82
  fail!(:invalid_response, e)
65
83
  end
66
84
 
67
- def auth_hash
68
- OmniAuth::Utils.deep_merge(super,
69
- uid: "#{@response.attributes['givenname']} #{@response.attributes['surname']}, #{@response.attributes["privatepersonalidentifier"]}",
70
- user_info: {
71
- name: "#{@response.attributes['givenname']} #{@response.attributes['surname']}",
72
- first_name: @response.attributes['givenname'],
73
- last_name: @response.attributes['surname'],
74
- private_personal_identifier: @response.attributes['privatepersonalidentifier']
75
- },
76
- authentication_method: @response.authentication_method,
77
- extra: @response.attributes
78
- )
85
+ def raw_info
86
+ @response.attributes
87
+ end
88
+
89
+ def uid
90
+ @response.name_identifier
91
+ end
92
+
93
+ def full_name
94
+ @full_name ||= "#{raw_info['givenname']} #{raw_info['surname']}"
95
+ end
96
+
97
+ def legacy_uids
98
+ # UIDs that could have been assigned to this identity by previous versions of the gem, or due to peronal identifier change
99
+
100
+ legacy_uids = [
101
+ "#{full_name}, #{raw_info["privatepersonalidentifier"]}" # generated by gem version <= 4.0
102
+ ]
103
+
104
+ raw_info.fetch('historical_privatepersonalidentifier', []).each do |historical_identifier|
105
+ legacy_uids << "#{full_name}, #{historical_identifier}" # generated by gem version <= 4.0
106
+ legacy_uids << "PK:#{historical_identifier}" # due to personal identifier change
107
+ end
108
+
109
+ legacy_uids
79
110
  end
80
111
  end
81
112
  end
@@ -13,7 +13,7 @@ module OmniAuth::Strategies
13
13
  end
14
14
 
15
15
  def validate!
16
- @document.validate!(fingerprint)
16
+ @document.validate!(fingerprint) && validate_conditions!
17
17
  end
18
18
 
19
19
  def xml
@@ -26,19 +26,42 @@ module OmniAuth::Strategies
26
26
  end
27
27
  end
28
28
 
29
+ def name_identifier
30
+ @name_identifier ||= begin
31
+ xml.xpath('//saml:AuthenticationStatement/saml:Subject/saml:NameIdentifier', saml: ASSERTION).text()
32
+ end
33
+ end
34
+
29
35
  # A hash of all the attributes with the response.
30
36
  # Assuming there is only one value for each key
31
37
  def attributes
32
38
  @attributes ||= begin
39
+ attrs = {
40
+ 'not_valid_before' => not_valid_before,
41
+ 'not_valid_on_or_after' => not_valid_on_or_after,
42
+ 'historical_privatepersonalidentifier' => []
43
+ }
44
+
45
+ stmt_elements = xml.xpath('//saml:Attribute', saml: ASSERTION)
33
46
 
34
- stmt_elements = xml.xpath('//a:Attribute', a: ASSERTION)
35
- return {} if stmt_elements.nil?
47
+ return attrs if stmt_elements.nil?
36
48
 
37
- stmt_elements.each_with_object({}) do |element, result|
38
- name = element.attribute('AttributeName').value
49
+ identifiers = stmt_elements.xpath("//saml:Attribute[@AttributeName='privatepersonalidentifier']", saml: ASSERTION)
50
+
51
+ stmt_elements.each_with_object(attrs) do |element, result|
52
+ name = element.attribute('AttributeName').value
39
53
  value = element.text
40
54
 
41
- result[name] = value
55
+ case name
56
+ when 'privatepersonalidentifier' # person can change their identifier, service will return all the versions
57
+ if identifiers.length == 1 || element.attribute('OriginalIssuer') # this is the primary identifier, as returned by third party auth service
58
+ result[name] = value
59
+ else
60
+ result['historical_privatepersonalidentifier'] << value
61
+ end
62
+ else
63
+ result[name] = value
64
+ end
42
65
  end
43
66
  end
44
67
  end
@@ -47,7 +70,27 @@ module OmniAuth::Strategies
47
70
 
48
71
  def fingerprint
49
72
  cert = OpenSSL::X509::Certificate.new(options[:certificate])
50
- Digest::SHA1.hexdigest(cert.to_der).upcase.scan(/../).join(':')
73
+ Digest::SHA256.hexdigest(cert.to_der).upcase.scan(/../).join(':')
74
+ end
75
+
76
+ def conditions_tag
77
+ @conditions_tag ||= xml.xpath('//saml:Conditions', saml: ASSERTION)
78
+ end
79
+
80
+ def not_valid_before
81
+ @not_valid_before ||= conditions_tag.attribute('NotBefore').value
82
+ end
83
+
84
+ def not_valid_on_or_after
85
+ @not_valid_on_or_after ||= conditions_tag.attribute('NotOnOrAfter').value
86
+ end
87
+
88
+ def validate_conditions!
89
+ if not_valid_on_or_after.present? && Time.current < Time.parse(not_valid_on_or_after)
90
+ true
91
+ else
92
+ raise ValidationError, 'Current time is on or after NotOnOrAfter condition'
93
+ end
51
94
  end
52
95
  end
53
96
  end
@@ -64,8 +64,18 @@ module OmniAuth::Strategies
64
64
  end
65
65
  end
66
66
 
67
+ def digest_method_class(reference)
68
+ value = reference.xpath('.//xmlns:DigestMethod', xmlns: DSIG).attribute('Algorithm').value
69
+ value == "#{DSIG}sha1" ? Digest::SHA1 : Digest::SHA256
70
+ end
71
+
72
+ def signature_method_class(sig_element)
73
+ value = sig_element.xpath('.//xmlns:SignatureMethod', xmlns: DSIG).attribute('Algorithm').value
74
+ value == "#{DSIG}rsa-sha1" ? OpenSSL::Digest::SHA1 : OpenSSL::Digest::SHA256
75
+ end
76
+
67
77
  def validate_fingerprint!(idp_cert_fingerprint)
68
- fingerprint = Digest::SHA1.hexdigest(certificate.to_der)
78
+ fingerprint = Digest::SHA256.hexdigest(certificate.to_der)
69
79
  if fingerprint != idp_cert_fingerprint.gsub(/[^a-zA-Z0-9]/, '').downcase
70
80
  raise ValidationError, 'Fingerprint mismatch'
71
81
  end
@@ -80,7 +90,7 @@ module OmniAuth::Strategies
80
90
  hashed_element = response_without_signature.
81
91
  at_xpath("//*[@AssertionID='#{uri[1, uri.size]}']").
82
92
  canonicalize(CANON_MODE)
83
- hash = Base64.encode64(Digest::SHA1.digest(hashed_element)).chomp
93
+ hash = Base64.encode64(digest_method_class(ref).digest(hashed_element)).chomp
84
94
  digest_value = ref.xpath('.//xmlns:DigestValue', xmlns: DSIG).text
85
95
 
86
96
  raise ValidationError, 'Digest mismatch' if hash != digest_value
@@ -94,7 +104,7 @@ module OmniAuth::Strategies
94
104
  base64_signature = sig_element.xpath('.//xmlns:SignatureValue', xmlns: DSIG).text
95
105
  signature = Base64.decode64(base64_signature)
96
106
 
97
- unless certificate.public_key.verify(OpenSSL::Digest::SHA1.new, signature, signed_info_element)
107
+ unless certificate.public_key.verify(signature_method_class(sig_element).new, signature, signed_info_element)
98
108
  raise ValidationError, 'Key validation error'
99
109
  end
100
110
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-latvija
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 6.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Edgars Beigarts
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-23 00:00:00.000000000 Z
11
+ date: 2020-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: omniauth
@@ -56,30 +56,30 @@ dependencies:
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '12.1'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '12.1'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '2.10'
75
+ version: '3.7'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '2.10'
82
+ version: '3.7'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: byebug
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: timecop
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
125
139
  description: Latvija.lv authentication strategy for OmniAuth
126
140
  email:
127
141
  - edgars.beigarts@makit.lv
@@ -137,10 +151,10 @@ files:
137
151
  - lib/omniauth/strategies/latvija/decryptor.rb
138
152
  - lib/omniauth/strategies/latvija/response.rb
139
153
  - lib/omniauth/strategies/latvija/signed_document.rb
140
- homepage:
154
+ homepage:
141
155
  licenses: []
142
156
  metadata: {}
143
- post_install_message:
157
+ post_install_message:
144
158
  rdoc_options: []
145
159
  require_paths:
146
160
  - lib
@@ -155,9 +169,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
155
169
  - !ruby/object:Gem::Version
156
170
  version: '0'
157
171
  requirements: []
158
- rubyforge_project:
159
- rubygems_version: 2.6.11
160
- signing_key:
172
+ rubygems_version: 3.0.6
173
+ signing_key:
161
174
  specification_version: 4
162
175
  summary: Latvija.lv authentication strategy for OmniAuth
163
176
  test_files: []