Skip to content

Commit

Permalink
Refactor IAM identity and UPVS SSO endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
pavolzbell committed Feb 6, 2021
1 parent 9637d2f commit 7bc1571
Show file tree
Hide file tree
Showing 23 changed files with 396 additions and 63 deletions.
2 changes: 1 addition & 1 deletion INSTALL.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
**Inštalačná príručka popisuje komponent verzie** [2.0.0](https://github.com/slovensko-digital/slovensko-sk-api/releases/tag/v2.0.0), uistite sa, že čítate príručku [verzie komponentu](https://github.com/slovensko-digital/slovensko-sk-api/releases), ktorý používate.
**Inštalačná príručka popisuje komponent verzie [2.0.0](https://github.com/slovensko-digital/slovensko-sk-api/releases/tag/v2.0.0), uistite sa, že čítate príručku [verzie komponentu](https://github.com/slovensko-digital/slovensko-sk-api/releases), ktorý používate.**

# slovensko.sk API - inštalačná príručka

Expand Down
1 change: 1 addition & 0 deletions app/controllers/api_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def self.rescue_from_soap_fault(&handler)

private

# TODO replace **options with ... when on ruby 2.7
def authenticate(**options)
self.upvs_identity = Environment.api_token_authenticator.verify_token(authenticity_token, options)
end
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/iam/identities_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class Iam::IdentitiesController < ApiController
include Pagination

before_action { authenticate(allow_sub: true, allow_obo_token: true, require_obo_token_scope: action_scope) }
before_action { authenticate(allow_sub: true) }

before_action(only: :search) { set_page }
before_action(only: :search) { set_per_page(default: 10, range: 10..100) }
Expand Down
25 changes: 17 additions & 8 deletions app/controllers/upvs_controller.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
class UpvsController < ApiController
skip_before_action(:verify_request_body, except: :assertion)
skip_before_action(:verify_format)
skip_before_action(:verify_request_body, except: [:assertion, :identity])
skip_before_action(:verify_format, except: :identity)

before_action(only: :assertion) { respond_to(:saml) }
before_action(only: [:assertion, :identity]) { authenticate(allow_obo_token: true, require_obo_token_scope: action_scope) }

def login
session[:login_callback_url] = fetch_callback_url(Environment.login_callback_urls)
Expand All @@ -17,12 +18,6 @@ def callback
redirect_to callback_url_with_token(session[:login_callback_url], token)
end

def assertion
_, assertion = Environment.api_token_authenticator.verify_token(authenticity_token, allow_obo_token: true)

render content_type: Mime[:saml], plain: assertion
end

def logout
if params[:SAMLRequest]
redirect_to "/auth/saml/slo?#{slo_request_params.to_query}"
Expand All @@ -36,12 +31,22 @@ def logout
end
end

def assertion
render content_type: Mime[:saml], plain: upvs_identity[:obo]
end

def identity
render partial: 'iam/identity', locals: { identity: iam_repository(upvs_identity).identity(obo_subject_id(upvs_identity[:obo])) }
end

include CallbackHelper

CallbackError = Class.new(StandardError)

rescue_from(CallbackError) { |error| render_bad_request(error.message, :callback) }

rescue_from(sk.gov.schemas.identity.service._1_7.GetIdentityFault) { |error| render_bad_request(:invalid, :identity_id, upvs_fault(error)) }

private

def fetch_callback_url(registered_urls)
Expand All @@ -63,4 +68,8 @@ def slo_request_params
def slo_response_params(redirect_url)
params.permit(:SAMLResponse, :SigAlg, :Signature).merge(RelayState: redirect_url)
end

def obo_subject_id(assertion)
Nokogiri::XML(assertion).at_xpath('//saml:Attribute[@Name="SubjectID"]/saml:AttributeValue').content
end
end
2 changes: 1 addition & 1 deletion app/services/environment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def obo_token_assertion_store
end

def obo_token_scopes
@obo_token_scopes ||= ['iam/identities/show', 'iam/identities/search', 'sktalk/receive', 'sktalk/receive_and_save_to_outbox', 'sktalk/save_to_outbox']
@obo_token_scopes ||= ['sktalk/receive', 'sktalk/receive_and_save_to_outbox', 'sktalk/save_to_outbox', 'upvs/assertion', 'upvs/identity']
end

# RedisCacheStore ignores standard errors
Expand Down
4 changes: 4 additions & 0 deletions app/views/iam/_affix.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
return json.nil! unless affix

json.type affix.type.underscore.remove('_title').tap { |t| t.replace('military') if t == 'form_of_address' }
json.value affix.value
30 changes: 30 additions & 0 deletions app/views/iam/_corporate_body.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
json.cin identity.id.find { |id| id.identifier_type.id == '7' }&.identifier_value
json.tin identity.id.find { |id| id.identifier_type.id == '8' }&.identifier_value

json.organization_id corporate_body.org_id
json.organization_units corporate_body.organization_unit

json.partial! 'iam/corporate_body_name', corporate_body: corporate_body
json.alternative_names corporate_body.corporate_body_alternative_name

json.legal_form { json.partial! 'iam/enumeration', value: corporate_body.legal_form }
json.legal_facts corporate_body.other_legal_facts

json.activities corporate_body.activities

# TODO
# json.bank_connections corporate_body.bank_connection do |c|
# end

# TODO
# json.stakeholders corporate_body.stakeholder do |s|
# end

# TODO
# corporate_body.sid
# corporate_body.equity
# corporate_body.suspension

json.established_on corporate_body.establishment.to_s.to_date
json.terminated_on corporate_body.termination.to_s.to_date
json.updated_on corporate_body.date_of_status_change.to_s.to_date
1 change: 1 addition & 0 deletions app/views/iam/_corporate_body_name.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
json.name corporate_body.corporate_body_name
5 changes: 5 additions & 0 deletions app/views/iam/_enumeration.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
return json.nil! unless value

json.id value.id
json.name value.title_sk
json.description value.desc
114 changes: 114 additions & 0 deletions app/views/iam/_identity.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
json.ids identity.general_data.egov_identifier do |egov_identifier|
json.type sector = egov_identifier.sector_identifier.downcase
json.value egov_identifier.identifier.tap { |id| id.downcase! if sector == 'sector_upvs' }
end

json.uri identity.general_data.uri
json.en identity.upvs_attributes.edesk_number
json.type identity.general_data.identity_type.value.downcase
json.status identity.upvs_attributes.identity_status.value.downcase
json.name identity.general_data.formatted_name
json.suffix identity.general_data.suffix

json.various_ids identity.id do |id|
json.type { json.partial! 'iam/enumeration', value: id.identifier_type }
json.value id.identifier_value
json.specified id.is_specified
end

json.upvs do
json.edesk_number identity.upvs_attributes.edesk_number
json.edesk_status identity.upvs_attributes.edesk_status&.value&.downcase
json.edesk_remote_uri identity.upvs_attributes.edesk_remote_uri
json.edesk_cuet_delivery_enabled identity.upvs_attributes.is_edesk_cuet_enabled
json.edesk_delivery_limited identity.upvs_attributes.is_edesk_delivery_limited

json.enotify_preferred_channel identity.upvs_attributes.enotify_preferred_channel&.value&.downcase
json.enotify_preferred_calendar identity.upvs_attributes.enotify_preferred_calendar&.downcase
json.enotify_emergency_allowed identity.upvs_attributes.is_enotify_emergency_allowed
json.enotify_email_allowed identity.upvs_attributes.is_enotify_email_allowed
json.enotify_sms_allowed identity.upvs_attributes.is_enotify_sms_allowed

# TODO
# identity.upvs_attributes.organizacna_zlozka_ovm
# identity.upvs_attributes.issuer_foreign_eid
# identity.upvs_attributes.location
# identity.upvs_attributes.location_activated

json.preferred_language identity.upvs_attributes.preferred_language&.value&.downcase

json.re_iam_identity_id identity.upvs_attributes.re_identity_id
end

if identity.corporate_body
json.corporate_body { json.partial! 'iam/corporate_body', identity: identity, corporate_body: identity.corporate_body }
end

if identity.physical_person
json.natural_person { json.partial! 'iam/natural_person', identity: identity, natural_person: identity.physical_person }
end

json.addresses identity.physical_address do |a|
raise 'Too many regions' if a.region.count > 1

json.type a.type.value.underscore.remove('_address').tap { |t| t.replace('resident') if t == 'street' }
json.inline a.address_line

json.country { json.partial! 'iam/enumeration', value: a.country }
json.region a.region.first
json.district { json.partial! 'iam/enumeration', value: a.county }
json.municipality { json.partial! 'iam/enumeration', value: a.municipality }
json.part a.district
json.street a.street_name
json.building_number a.building_number
json.registration_number a.property_registration_number
json.unit a.unit

# TODO
# json.address_point do
# end

json.building_index a.building_index

json.delivery_address do
if a.delivery_address
json.(a.delivery_address, :postal_code, :post_office_box)

json.recipient do
if a.delivery_address.recipient
if a.delivery_address.recipient.organization_unit || a.delivery_address.recipient.corporate_body_name
json.corporate_body do
json.organization_unit a.delivery_address.recipient.organization_unit
json.partial! 'iam/corporate_body_name', corporate_body: a.delivery_address.recipient
end
end

if a.delivery_address.recipient.person_name
json.natural_person do
json.partial! 'iam/natural_person_name', natural_person: a.delivery_address.recipient.person_name
end
end

json.note a.delivery_address.recipient.additional_text
else
json.nil!
end
end
else
json.nil!
end
end

json.ra_entry a.address_register_entry
json.specified a.is_specified
end

json.emails identity.internet_address do |e|
json.(e, :address, :dsig_key_info)
end

json.phones identity.telephone_address do |p|
json.type { json.partial! 'iam/enumeration', value: p.telephone_type }
json.number p.telephone_number.formatted_number&.value
json.(p.telephone_number, :international_country_code, :national_number, :area_city_code, :subscriber_number, :extension)
end
49 changes: 49 additions & 0 deletions app/views/iam/_natural_person.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# TODO
# natural_person.pco

json.type { json.partial! 'iam/enumeration', value: natural_person.identity_type_detail }

json.partial! 'iam/natural_person_name', natural_person: natural_person.person_name
json.alternative_names natural_person.alternative_name

json.gender { json.partial! 'iam/enumeration', value: natural_person.sex }

json.marital_status natural_person.marital_status
json.vital_status { json.partial! 'iam/enumeration', value: natural_person.death&.status }

json.nationality { json.partial! 'iam/enumeration', value: natural_person.nationality }
json.occupation { json.partial! 'iam/enumeration', value: natural_person.occupation }

# TODO
# json.bank_connections natural_person.bank_connection do |c|
# end

# TODO
# json.related_persons natural_person.related_person do |c|
# end

json.birth do
if natural_person.birth
json.date natural_person.birth.date_of_birth.to_s.in_time_zone.to_date
json.country { json.partial! 'iam/enumeration', value: natural_person.birth.country }
json.district { json.partial! 'iam/enumeration', value: natural_person.birth.county }
json.municipality { json.partial! 'iam/enumeration', value: natural_person.birth.municipality }
json.part natural_person.birth.district
else
json.nil!
end
end

json.death do
if natural_person.death
json.date natural_person.death.date_of_death.to_s.in_time_zone.to_date
json.country { json.partial! 'iam/enumeration', value: natural_person.death.country }
json.district { json.partial! 'iam/enumeration', value: natural_person.death.county }
json.municipality { json.partial! 'iam/enumeration', value: natural_person.death.municipality }
json.part natural_person.death.district
else
json.nil!
end
end

json.updated_on natural_person.death&.date_of_status_change.to_s.to_date
19 changes: 19 additions & 0 deletions app/views/iam/_natural_person_name.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
json.name natural_person.formatted_name
json.given_names natural_person.given_name
json.preferred_given_name natural_person.preferred_given_name

json.given_family_names natural_person.given_family_name do |n|
json.primary n.is_primary
json.(n, :prefix, :value)
end

json.family_names natural_person.family_name do |n|
json.primary n.is_primary
json.(n, :prefix, :value)
end

json.legal_name natural_person.legal_name
json.other_name natural_person.other_name

json.prefixes natural_person.affix.select { |a| a.position.to_s == 'Prefix' }, partial: 'iam/affix'
json.suffixes natural_person.affix.select { |a| a.position.to_s == 'Postfix' }, partial: 'iam/affix'
2 changes: 1 addition & 1 deletion app/views/iam/identities/search.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1 +1 @@
json.array! @identities, partial: 'identity', as: :identity
json.array! @identities, partial: 'iam/identity', as: :identity
2 changes: 1 addition & 1 deletion app/views/iam/identities/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1 +1 @@
json.partial! 'identity', identity: @identity
json.partial! 'iam/identity', identity: @identity
3 changes: 2 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@

if UpvsEnvironment.sso_support?
namespace :upvs do
get :assertion, path: 'sso/assertion'
get :assertion
get :identity
end
end
end
Expand Down
Loading

0 comments on commit 7bc1571

Please sign in to comment.