# frozen_string_literal: true class RegistrationsController < Devise::RegistrationsController prepend Dmpopidor::Controllers::Registrations def edit @user = current_user @prefs = @user.get_preferences(:email) @languages = Language.sorted_by_abbreviation @orgs = Org.order("name") @other_organisations = Org.where(is_other: true).pluck(:id) @identifier_schemes = IdentifierScheme.where(active: true).order(:name) @default_org = current_user.org if !@prefs flash[:alert] = "No default preferences found (should be in branding.yml)." end end # GET /resource def new oauth = { provider: nil, uid: nil } IdentifierScheme.all.each do |scheme| unless session["devise.#{scheme.name.downcase}_data"].nil? oauth = session["devise.#{scheme.name.downcase}_data"] end end @user = User.new unless oauth.nil? # The OAuth provider could not be determined or there was no unique UID! if !oauth["provider"].nil? && !oauth["uid"].nil? # Connect the new user with the identifier sent back by the OAuth provider # rubocop:disable Metrics/LineLength flash[:notice] = _("Please make a choice below. After linking your details to a %{application_name} account, you will be able to sign in directly with your institutional credentials.") % { application_name: Rails.configuration.branding[:application][:name] } # rubocop:enable Metrics/LineLength scheme = IdentifierScheme.find_by(name: oauth["provider"].downcase) UserIdentifier.create(identifier_scheme: scheme, identifier: oauth["uid"], user: @user) end end end # POST /resource def create oauth = { provider: nil, uid: nil } IdentifierScheme.all.each do |scheme| unless session["devise.#{scheme.name.downcase}_data"].nil? oauth = session["devise.#{scheme.name.downcase}_data"] end end if params[:user][:accept_terms].to_s == "0" redirect_to after_sign_up_error_path_for(resource), alert: _("You must accept the terms and conditions to register.") elsif params[:user][:org_id].blank? && params[:user][:other_organisation].blank? # rubocop:disable Metrics/LineLength redirect_to after_sign_up_error_path_for(resource), alert: _("Please select an organisation from the list, or enter your organisation's name.") # rubocop:enable Metrics/LineLength else existing_user = User.where_case_insensitive("email", sign_up_params[:email]).first if existing_user.present? if existing_user.invitation_token.present? && !existing_user.accept_terms? # Destroys the existing user since the accept terms are nil/false. and they # have an invitation Note any existing role for that user will be deleted too. # Added to accommodate issue at: https://github.com/DMPRoadmap/roadmap/issues/322 # when invited user creates an account outside the invite workflow existing_user.destroy else redirect_to after_sign_up_error_path_for(resource), alert: _("That email address is already registered.") return end end if params[:user][:org_id].blank? other_org = Org.find_by(is_other: true) if other_org.nil? # rubocop:disable Metrics/LineLength redirect_to(after_sign_up_error_path_for(resource), alert: _("You cannot be assigned to other organisation since that option does not exist in the system. Please contact your system administrators.")) and return # rubocop:enable Metrics/LineLength end params[:user][:org_id] = other_org.id end build_resource(sign_up_params) if resource.save if resource.active_for_authentication? set_flash_message :notice, :signed_up if is_navigational_format? sign_up(resource_name, resource) UserMailer.welcome_notification(current_user).deliver_now unless oauth.nil? # The OAuth provider could not be determined or there was no unique UID! unless oauth["provider"].nil? || oauth["uid"].nil? prov = IdentifierScheme.find_by(name: oauth["provider"].downcase) # Until we enable ORCID signups if prov.name == "shibboleth" UserIdentifier.create(identifier_scheme: prov, identifier: oauth["uid"], user: @user) # rubocop:disable Metrics/LineLength flash[:notice] = _("Welcome! You have signed up successfully with your institutional credentials. You will now be able to access your account with them.") # rubocop:enable Metrics/LineLength end end end respond_with resource, location: after_sign_up_path_for(resource) else if is_navigational_format? set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" respond_with resource, location: after_inactive_sign_up_path_for(resource) end end else clean_up_passwords resource # rubocop:disable Metrics/LineLength redirect_to after_sign_up_error_path_for(resource), alert: _("Unable to create your account.#{errors_for_display(resource)}") # rubocop:enable Metrics/LineLength end end end def update if user_signed_in? then @prefs = @user.get_preferences(:email) @orgs = Org.order("name") @default_org = current_user.org @other_organisations = Org.where(is_other: true).pluck(:id) @identifier_schemes = IdentifierScheme.where(active: true).order(:name) @languages = Language.sorted_by_abbreviation if params[:skip_personal_details] == "true" do_update_password(current_user, params) else do_update(require_password = needs_password?(current_user, params)) end else render(file: File.join(Rails.root, "public/403.html"), status: 403, layout: false) end end private # check if we need password to update user data # ie if password or email was changed # extend this as needed def needs_password?(user, params) user.email != params[:user][:email] || params[:user][:password].present? end def do_update(require_password = true, confirm = false) mandatory_params = true # added to by below, overwritten otherwise message = _("Save Unsuccessful. ") # ensure that the required fields are present if params[:user][:email].blank? message += _("Please enter an email address. ") mandatory_params &&= false end if params[:user][:firstname].blank? message += _("Please enter a First name. ") mandatory_params &&= false end if params[:user][:surname].blank? message += _("Please enter a Last name. ") mandatory_params &&= false end if params[:user][:org_id].blank? && params[:user][:other_organisation].blank? # rubocop:disable Metrics/LineLength message += _("Please select an organisation from the list, or enter your organisation's name.") # rubocop:enable Metrics/LineLength mandatory_params &&= false end # has the user entered all the details if mandatory_params # user is changing email or password if require_password # if user is changing email if current_user.email != params[:user][:email] # password needs to be present if params[:user][:password].blank? message = _("Please enter your password to change email address.") successfully_updated = false else successfully_updated = current_user.update_with_password(password_update) if !successfully_updated message = _("Save unsuccessful. \ That email address is already registered. \ You must enter a unique email address.") end end else # This case is never reached since this method when called with # require_password = true is because the email changed. # The case for password changed goes to do_update_password instead successfully_updated = current_user.update_without_password(update_params) end else # password not required successfully_updated = current_user.update_without_password(update_params) end else successfully_updated = false end # unlink shibboleth from user's details if params[:unlink_flag] == "true" then current_user.update_attributes(shibboleth_id: "") end # render the correct page if successfully_updated if confirm # will error out if confirmable is turned off in user model current_user.skip_confirmation! current_user.save! end session[:locale] = current_user.get_locale unless current_user.get_locale.nil? # Method defined at controllers/application_controller.rb set_gettext_locale set_flash_message :notice, success_message(current_user, _("saved")) # Sign in the user bypassing validation in case his password changed bypass_sign_in current_user redirect_to "#{edit_user_registration_path}\#personal-details", notice: success_message(current_user, _("saved")) else flash[:alert] = message.blank? ? failure_message(current_user, _("save")) : message render "edit" end end def do_update_password(current_user, params) if params[:user][:current_password].blank? message = _("Please enter your current password") elsif params[:user][:password_confirmation].blank? message = _("Please enter a password confirmation") elsif params[:user][:password] != params[:user][:password_confirmation] message = _("Password and comfirmation must match") else successfully_updated = current_user.update_with_password(password_update) end # render the correct page if successfully_updated session[:locale] = current_user.get_locale unless current_user.get_locale.nil? # Method defined at controllers/application_controller.rbset_gettext_locale set_flash_message :notice, success_message(current_user, _("saved")) # TODO this method is deprecated bypass_sign_in current_user redirect_to "#{edit_user_registration_path}\#password-details", notice: success_message(current_user, _("saved")) else flash[:alert] = message.blank? ? failure_message(current_user, _("save")) : message redirect_to "#{edit_user_registration_path}\#password-details" end end def sign_up_params params.require(:user).permit(:email, :password, :password_confirmation, :firstname, :surname, :recovery_email, :accept_terms, :org_id, :other_organisation) end def update_params params.require(:user).permit(:firstname, :org_id, :other_organisation, :language_id, :surname, :department_id) end def password_update params.require(:user).permit(:email, :firstname, :current_password, :org_id, :language_id, :password, :password_confirmation, :surname, :other_organisation, :department_id) end end