Skip to content

Commit

Permalink
Feature/eid login (#656)
Browse files Browse the repository at this point in the history
* Handle case when actor key value can be null

Co-authored-by: Lucia Janíková <[email protected]>

* Handle case when actor key value can be null

Co-authored-by: Lucia Janíková <[email protected]>

* Add login button, expect callback URL from UPVS to be always /login for safety reasons

* Fix logout redirect

* Improve login button, fetch assertion

* Persist subject data from assertion

* Disallow subject login for non-full representation

* Update app/views/sessions/insufficient_representation.html.erb

Co-authored-by: Jano Suchal <[email protected]>

* Remove index which is not necessary

---------

Co-authored-by: Ahmed Al Hafoudh <[email protected]>
Co-authored-by: Lucia Janíková <[email protected]>
Co-authored-by: Jano Suchal <[email protected]>
  • Loading branch information
4 people authored Apr 30, 2024
1 parent 2d78d95 commit ac499f9
Show file tree
Hide file tree
Showing 15 changed files with 172 additions and 64 deletions.
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion app/assets/images/eid-sk.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 26 additions & 2 deletions app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
2 changes: 1 addition & 1 deletion app/models/eid_token.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
73 changes: 73 additions & 0 deletions app/models/upvs/assertion.rb
Original file line number Diff line number Diff line change
@@ -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
3 changes: 0 additions & 3 deletions app/views/components/_header.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@
<a href="#" data-turbolinks="false" class="sdn-header__link sdn-header__dropdown-toggle js-dropdown-toggle" aria-controls="subnav-dropdown">
<span class="sdn-header__fixed-width-text">
<%= current_user.email %>
<% if eid_token&.valid? %>
<sup>EID</sup>
<% end %>
</span>
</a>
<ul class="sdn-header__dropdown" id="subnav-dropdown">
Expand Down
4 changes: 4 additions & 0 deletions app/views/eid/onboarding/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
<%= image_submit_tag 'google/btn_google_signin_dark_normal.svg', class: 'govuk-link', title: 'Prihlásiť sa cez Google', alt: 'Prihlásiť sa cez Google', style: 'max-width: 300px' %>
<% end %>
<%= form_tag(auth_path(:eid), method: :post, class: 'govuk-body govuk-!-margin-bottom-8') do %>
<%= image_submit_tag 'eid-sk.svg', class: 'govuk-link', title: 'Prihlásiť sa cez eID', alt: 'Prihlásiť sa cez eID', style: 'max-width: 300px' %>
<% end %>
<%= form_tag(auth_path(:magiclink), method: :post, id: 'login-email') do %>
<fieldset class="govuk-fieldset">
<div class="govuk-form-group">
Expand Down
33 changes: 33 additions & 0 deletions app/views/profiles/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,39 @@
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<div class="govuk-body sdn-content">
<% if current_user.subject_name.present? || current_user.subject_edesk_number.present? || current_user.subject_cin.present? %>
<h2 class="govuk-heading-l">Vaše identifikačné údaje</h2>
<% if current_user.subject_name.present? %>
<div class="govuk-text govuk-!-padding-bottom-5">
<div style = "color: #505a5f;" class="govuk-!-font-size-19 govuk-!-padding-bottom-1">
Meno
</div>
<div class="govuk-!-font-size-24">
<%= current_user.subject_name %>
</div>
</div>
<% end %>
<% if current_user.subject_edesk_number.present? %>
<div class="govuk-text govuk-!-padding-bottom-5">
<div style = "color: #505a5f;" class="govuk-!-font-size-19 govuk-!-padding-bottom-1">
Identifikátor schránky
</div>
<div class="govuk-!-font-size-24">
<%= current_user.subject_edesk_number %>
</div>
</div>
<% end %>
<% if current_user.subject_cin.present? %>
<div class="govuk-text govuk-!-padding-bottom-5">
<div style = "color: #505a5f;" class="govuk-!-font-size-19 govuk-!-padding-bottom-1">
IČO
</div>
<div class="govuk-!-font-size-24">
<%= current_user.subject_cin %>
</div>
</div>
<% end %>
<% end %>
<h2 class="govuk-heading-l">Nastavenia</h2>
<div class="govuk-inset-text">Jedného dňa tu pribudne veľa zaujímavých nastavení, ale zatiaľ je to tu také
prázdne. Ak nám chceš pomôcť testovať novú funkcionalitu Návody.Digital, <%= link_to 'ozvi sa nám', page_path('kontakt') %>.
Expand Down
9 changes: 9 additions & 0 deletions app/views/sessions/insufficient_representation.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<%= content_for :title, build_page_title('Chyba pri prihlasovaní') %>

<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h2 class="govuk-heading-xl">Nastala chyba pri prihlasovaní</h2>

<p class="govuk-body-lead">Nemáte dostatočné oprávnenia, aby ste mohli zastupovať zvolený subjekt.</p>
</div>
</div>
4 changes: 4 additions & 0 deletions app/views/sessions/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
<%= image_submit_tag 'google/btn_google_signin_dark_normal.svg', class: 'govuk-link', title: 'Prihlásiť sa cez Google', alt: 'Prihlásiť sa cez Google', style: 'max-width: 300px' %>
<% end %>
<%= form_tag(auth_path(:eid), method: :post, class: 'govuk-body govuk-!-margin-bottom-8') do %>
<%= image_submit_tag 'eid-sk.svg', class: 'govuk-link', title: 'Prihlásiť sa cez slovensko.sk', alt: 'Prihlásiť sa cez slovensko.sk', style: 'max-width: 300px' %>
<% end %>
<%= form_tag(auth_path(:magiclink), method: :post, id: 'login-email') do %>
<fieldset class="govuk-fieldset">
<div class="govuk-form-group">
Expand Down
1 change: 1 addition & 0 deletions config/initializers/omniauth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
}
provider :eid, {
config: Rails.application.config_for(:auth).fetch(:eid),
callback_path: '/login',
}
end

2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@
get '/auth/failure', to: 'sessions#failure'
get '/auth/:provider/callback', to: 'sessions#create', as: :auth_callback
post '/auth/:provider', to: lambda { |_| [404, {}, ["Not Found"]] }, as: :auth
get '/login', to: 'sessions#create', as: :login
get '/logout', to: 'sessions#destroy', as: :logout

resources :faqs, path: 'casto-kladene-otazky'
resources :pages, path: '', only: 'show'
Expand Down
7 changes: 7 additions & 0 deletions db/migrate/20240427124856_add_subject_data_to_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class AddSubjectDataToUsers < ActiveRecord::Migration[6.1]
def change
add_column :users, :subject_name, :string
add_column :users, :subject_cin, :string
add_column :users, :subject_edesk_number, :string
end
end
62 changes: 8 additions & 54 deletions db/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -510,8 +510,8 @@ ALTER SEQUENCE public.apps_id_seq OWNED BY public.apps.id;
CREATE TABLE public.ar_internal_metadata (
key character varying NOT NULL,
value character varying,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL
);


Expand Down Expand Up @@ -1233,7 +1233,10 @@ CREATE TABLE public.users (
email text NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
eid_sub character varying
eid_sub character varying,
subject_name character varying,
subject_cin character varying,
subject_edesk_number character varying
);


Expand Down Expand Up @@ -1325,41 +1328,6 @@ CREATE SEQUENCE upvs.form_template_related_documents_id_seq
ALTER SEQUENCE upvs.form_template_related_documents_id_seq OWNED BY upvs.form_template_related_documents.id;


--
-- Name: form_template_related_documents_temp; Type: TABLE; Schema: upvs; Owner: -
--

CREATE TABLE upvs.form_template_related_documents_temp (
id bigint NOT NULL,
posp_id character varying NOT NULL,
posp_version character varying NOT NULL,
message_type character varying NOT NULL,
xsd_schema text,
xslt_transformation text,
created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL
);


--
-- Name: form_template_related_documents_temp_id_seq; Type: SEQUENCE; Schema: upvs; Owner: -
--

CREATE SEQUENCE upvs.form_template_related_documents_temp_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;


--
-- Name: form_template_related_documents_temp_id_seq; Type: SEQUENCE OWNED BY; Schema: upvs; Owner: -
--

ALTER SEQUENCE upvs.form_template_related_documents_temp_id_seq OWNED BY upvs.form_template_related_documents_temp.id;


--
-- Name: submissions; Type: TABLE; Schema: upvs; Owner: -
--
Expand Down Expand Up @@ -1616,13 +1584,6 @@ ALTER TABLE ONLY upvs.egov_application_allow_rules ALTER COLUMN id SET DEFAULT n
ALTER TABLE ONLY upvs.form_template_related_documents ALTER COLUMN id SET DEFAULT nextval('upvs.form_template_related_documents_id_seq'::regclass);


--
-- Name: form_template_related_documents_temp id; Type: DEFAULT; Schema: upvs; Owner: -
--

ALTER TABLE ONLY upvs.form_template_related_documents_temp ALTER COLUMN id SET DEFAULT nextval('upvs.form_template_related_documents_temp_id_seq'::regclass);


--
-- Name: submissions id; Type: DEFAULT; Schema: upvs; Owner: -
--
Expand Down Expand Up @@ -1902,14 +1863,6 @@ ALTER TABLE ONLY upvs.form_template_related_documents
ADD CONSTRAINT form_template_related_documents_pkey PRIMARY KEY (id);


--
-- Name: form_template_related_documents_temp form_template_related_documents_temp_pkey; Type: CONSTRAINT; Schema: upvs; Owner: -
--

ALTER TABLE ONLY upvs.form_template_related_documents_temp
ADD CONSTRAINT form_template_related_documents_temp_pkey PRIMARY KEY (id);


--
-- Name: submissions submissions_pkey; Type: CONSTRAINT; Schema: upvs; Owner: -
--
Expand Down Expand Up @@ -2486,6 +2439,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20221022143119'),
('20230325092744'),
('20230325095737'),
('20230325151049');
('20230325151049'),
('20240427124856');


2 changes: 1 addition & 1 deletion lib/omniauth/strategies/eid.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def callback_phase
end

def on_callback_path?
on_path?('/login')
on_path?('/auth/eid/callback') || on_path?('/login')
end

uid do
Expand Down

0 comments on commit ac499f9

Please sign in to comment.