diff --git a/Gemfile.lock b/Gemfile.lock
index fad1fa79..dbcd617e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -255,7 +255,7 @@ GEM
snaky_hash (~> 2.0)
version_gem (~> 1.1)
oj (3.14.2)
- omniauth (2.1.1)
+ omniauth (2.1.2)
hashie (>= 3.4.6)
rack (>= 2.2.3)
rack-protection
@@ -295,7 +295,7 @@ GEM
que (>= 1)
sinatra
racc (1.7.1)
- rack (2.2.8)
+ rack (2.2.9)
rack-protection (3.0.5)
rack
rack-proxy (0.7.6)
diff --git a/app/assets/images/eid-sk.svg b/app/assets/images/eid-sk.svg
index 842451ed..3d4bdd54 100644
--- a/app/assets/images/eid-sk.svg
+++ b/app/assets/images/eid-sk.svg
@@ -16,5 +16,5 @@
- Prihlásiť cez EID
+ Cez slovensko.sk
\ No newline at end of file
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index ef33e634..816e9074 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -11,6 +11,11 @@ def create
end
if new_eid_identity?
+ unless fully_represents_subject?
+ render :insufficient_representation, locals: { eid_token: eid_token }
+ return
+ end
+
render :new_eid_identity, locals: { eid_token: eid_token }
return
end
@@ -25,7 +30,18 @@ def create
notice = user.previously_new_record? ? 'first_time_login' : 'Prihlásenie úspešné. Vitajte!'
if eid_identity_approval?
- user.update!(eid_sub: eid_sub_from_auth)
+ assertion = Upvs::Assertion.assertion(eid_token)
+
+ if assertion
+ user.update!(
+ eid_sub: eid_sub_from_auth,
+ subject_name: assertion.subject_name,
+ subject_cin: assertion.subject_cin,
+ subject_edesk_number: assertion.subject_edesk_number,
+ )
+ else
+ user.update!(eid_sub: eid_sub_from_auth)
+ end
end
unless should_keep_eid_token_in_session?(user.eid_sub)
@@ -57,7 +73,10 @@ def logout
def destroy
if should_perform_eid_logout?
- redirect_to eid_token.generate_logout_url(expires_in: 5.minutes)
+ eid_logout_url = eid_token.generate_logout_url(expires_in: 5.minutes)
+ reset_session
+
+ redirect_to eid_logout_url
else
logout
end
@@ -95,4 +114,9 @@ def after_login_redirect_path
return session[:after_login_callback] if session[:after_login_callback]&.start_with?("/") # Only allow local redirects
root_path
end
+
+ def fully_represents_subject?
+ assertion = Upvs::Assertion.assertion(eid_token)
+ assertion&.fully_represents_subject?
+ end
end
diff --git a/app/models/eid_token.rb b/app/models/eid_token.rb
index af15ef7e..4840c226 100644
--- a/app/models/eid_token.rb
+++ b/app/models/eid_token.rb
@@ -14,7 +14,7 @@ def decoded_token
end
def sub
- decoded_token&.first&.fetch('actor')&.fetch('sub')
+ decoded_token&.first&.fetch('sub')
end
def name
diff --git a/app/models/upvs/assertion.rb b/app/models/upvs/assertion.rb
new file mode 100644
index 00000000..607bd08d
--- /dev/null
+++ b/app/models/upvs/assertion.rb
@@ -0,0 +1,73 @@
+module Upvs
+ class Assertion
+ include ActiveModel::Model
+ attr_accessor(:raw, :subject_name, :subject_id, :subject_cin, :subject_edesk_number, :delegation_type)
+
+ DELEGATION_TYPES = {
+ legal_representation: '0',
+ full_representation: '1',
+ partial_representation: '2',
+ }
+
+ def fully_represents_subject?
+ delegation_type&.to_s&.in?(full_representations)
+ end
+
+ def self.new_from_xml(raw:)
+ return unless raw
+
+ doc = Nokogiri::XML(raw)
+ return unless doc
+
+ doc.remove_namespaces!
+ doc_attrs = doc.xpath('//Assertion/AttributeStatement/Attribute')
+ return unless doc_attrs
+
+ new(
+ raw:,
+ subject_name: doc_attrs.detect{|n| n['Name'] == 'Subject.FormattedName' }&.xpath('AttributeValue')&.text,
+ subject_id: doc_attrs.detect{|n| n['Name'] == 'SubjectID' }&.xpath('AttributeValue')&.text,
+ subject_cin: doc_attrs.detect{|n| n['Name'] == 'Subject.ICO' }&.xpath('AttributeValue')&.text,
+ subject_edesk_number: doc_attrs.detect{|n| n['Name'] == 'Subject.eDeskNumber' }&.xpath('AttributeValue')&.text,
+ delegation_type: doc_attrs.detect{|n| n['Name'] == 'DelegationType' }&.xpath('AttributeValue')&.text,
+ )
+ end
+
+ def self.assertion(eid_token, client: Faraday, url: "#{ENV.fetch('AUTH_EID_BASE_URL')}/api/upvs/assertion?token=#{eid_token&.api_token}")
+ new_from_xml(raw: get_from_sk_api(client, url, eid_token))
+ end
+
+ def self.get_from_sk_api(client, url, eid_token)
+ headers = {
+ "Accept": "application/samlassertion+xml",
+ "AUTHORIZATION": "Bearer #{eid_token&.api_token}",
+ }
+
+ response = client.get(url, {}, headers)
+ error = begin
+ JSON.parse(response.body)
+ rescue StandardError
+ nil
+ end
+ if error && error['message']
+ return nil
+ end
+ response.body
+ rescue StandardError => _e
+ raise
+ nil
+ end
+
+ private
+
+ def full_representations
+ [
+ DELEGATION_TYPES[:legal_representation],
+ DELEGATION_TYPES[:full_representation],
+ ]
+ end
+
+ class SkApiError < StandardError
+ end
+ end
+end
diff --git a/app/views/components/_header.html.erb b/app/views/components/_header.html.erb
index 4a0e0c49..e29a5757 100644
--- a/app/views/components/_header.html.erb
+++ b/app/views/components/_header.html.erb
@@ -27,9 +27,6 @@