app/controllers/decidim/suomifi/omniauth_callbacks_controller.rb in decidim-suomifi-0.18.0 vs app/controllers/decidim/suomifi/omniauth_callbacks_controller.rb in decidim-suomifi-0.18.1
- old
+ new
@@ -11,38 +11,25 @@
skip_after_action :verify_same_origin_request, only: [:suomifi, :failure]
# This is called always after the user returns from the authentication
# flow from the Suomi.fi identity provider.
def suomifi
+ session["decidim-suomifi.signed_in"] = true
+
+ authenticator.validate!
+
if user_signed_in?
# The user is most likely returning from an authorization request
# because they are already signed in. In this case, add the
# authorization and redirect the user back to the authorizations view.
# Make sure the user has an identity created in order to aid future
- # Suomi.fi sign ins.
- identity = current_user.identities.find_by(
- organization: current_organization,
- provider: oauth_data[:provider],
- uid: user_identifier
- )
- unless identity
- # Check that the identity is not already bound to another user.
- id = Decidim::Identity.find_by(
- organization: current_organization,
- provider: oauth_data[:provider],
- uid: user_identifier
- )
- return fail_authorize(:identity_bound_to_other_user) if id
+ # Suomi.fi sign ins. In case this fails, it will raise a
+ # Decidim::Suomifi::Authentication::IdentityBoundToOtherUserError
+ # which is handled below.
+ authenticator.identify_user!(current_user)
- current_user.identities.create!(
- organization: current_organization,
- provider: oauth_data[:provider],
- uid: user_identifier
- )
- end
-
# Add the authorization for the user
return fail_authorize unless authorize_user(current_user)
# Show the success message and redirect back to the authorizations
flash[:notice] = t(
@@ -55,10 +42,14 @@
)
end
# Normal authentication request, proceed with Decidim's internal logic.
send(:create)
+ rescue Decidim::Suomifi::Authentication::ValidationError => e
+ fail_authorize(e.validation_key)
+ rescue Decidim::Suomifi::Authentication::IdentityBoundToOtherUserError
+ fail_authorize(:identity_bound_to_other_user)
end
def failure
strategy = failed_strategy
saml_response = strategy.response_object if strategy
@@ -130,49 +121,29 @@
end
private
def authorize_user(user)
- authorization = Decidim::Authorization.find_by(
- name: "suomifi_eid",
- unique_id: user_signature
- )
- if authorization
- return nil if authorization.user != user
- else
- authorization = Decidim::Authorization.find_or_initialize_by(
- name: "suomifi_eid",
- user: user
- )
- end
-
- authorization.attributes = {
- unique_id: user_signature,
- metadata: authorization_metadata
- }
- authorization.save!
-
- # This will update the "granted_at" timestamp of the authorization which
- # will postpone expiration on re-authorizations in case the
- # authorization is set to expire (by default it will not expire).
- authorization.grant!
-
- authorization
+ authenticator.authorize_user!(user)
+ rescue Decidim::Suomifi::Authentication::AuthorizationBoundToOtherUserError
+ nil
end
def fail_authorize(failure_message_key = :already_authorized)
flash[:alert] = t(
"failure.#{failure_message_key}",
scope: "decidim.suomifi.omniauth_callbacks"
)
- redirect_to stored_location_for(resource || :user) || decidim.root_path
- end
- # Data that is stored against the authorization "permanently" (i.e. as
- # long as the authorization is valid).
- def authorization_metadata
- metadata_collector.metadata
+ redirect_path = stored_location_for(resource || :user) || decidim.root_path
+ if session.delete("decidim-suomifi.signed_in")
+ params = "?RelayState=#{CGI.escape(redirect_path)}"
+
+ return redirect_to user_suomifi_omniauth_spslo_path + params
+ end
+
+ redirect_to redirect_path
end
# Needs to be specifically defined because the core engine routes are not
# all properly loaded for the view and this helper method is needed for
# defining the omniauth registration form's submit path.
@@ -181,87 +152,21 @@
end
# Private: Create form params from omniauth hash
# Since we are using trusted omniauth data we are generating a valid signature.
def user_params_from_oauth_hash
- return nil if oauth_data.empty?
- return nil if saml_attributes.empty?
- return nil if user_identifier.blank?
-
- {
- provider: oauth_data[:provider],
- uid: user_identifier,
- name: user_full_name,
- # The nickname is automatically "parametrized" by Decidim core from
- # the name string, i.e. it will be in correct format.
- nickname: user_full_name,
- oauth_signature: user_signature,
- avatar_url: oauth_data[:info][:image],
- raw_data: oauth_hash
- }
+ authenticator.user_params_from_oauth_hash
end
- def user_full_name
- return oauth_data[:info][:name] if oauth_data[:info][:name]
-
- @user_full_name ||= begin
- first_name = begin
- saml_attributes[:given_name] ||
- saml_attributes[:first_names] ||
- saml_attributes[:eidas_first_names]
- end
- last_name = begin
- saml_attributes[:last_name] ||
- saml_attributes[:eidas_family_name]
- end
-
- "#{first_name} #{last_name}"
- end
- end
-
- def user_signature
- @user_signature ||= OmniauthRegistrationForm.create_signature(
- oauth_data[:provider],
- user_identifier
+ def authenticator
+ @authenticator ||= Decidim::Suomifi.authenticator_for(
+ current_organization,
+ oauth_hash
)
end
- # See the omniauth-suomi gem's notes about the UID. It should be always
- # unique per person as long as it can be determined from the user's data.
- # This consists of one of the following in this order:
- # - The person's electronic identifier (SATU ID, sähköinen asiointitunnus)
- # - The person's personal identifier (HETU ID, henkilötunnus) in hashed
- # format
- # - The person's eIDAS personal identifier (eIDAS PID) in hashed format
- # - The SAML NameID in the SAML response in case no unique personal data
- # is available as defined above
- def user_identifier
- @user_identifier ||= oauth_data[:uid]
- end
-
- def person_identifier_digest
- metadata_collector.person_identifier_digest
- end
-
- def metadata_collector
- @metadata_collector ||= Decidim::Suomifi::Verification::Manager.metadata_collector_for(
- saml_attributes
- )
- end
-
def verified_email
- @verified_email ||= begin
- if saml_attributes[:email]
- saml_attributes[:email]
- elsif Decidim::Suomifi.auto_email_domain
- domain = Decidim::Suomifi.auto_email_domain
- "suomifi-#{person_identifier_digest}@#{domain}"
- end
- end
- end
-
- def saml_attributes
- @saml_attributes ||= oauth_hash[:extra][:saml_attributes]
+ authenticator.verified_email
end
end
end
end