0
votes

Users can log in to my Rails app using an omniauth provider, but I want to enable certain features only for users with a password.

When a user is created using omniauth credentials, their password is blank. When I try to create a password for the omniauth user, I get the error "Current password can't be blank."

How can I create a password for an omniauth user that has "nil" as their current_password?

This is what I currently have for my form for editing a user's password:

<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
     <%= devise_error_messages! %>

     <% if current_user.password != nil %>
           <div class="formField"><%= f.label :current_password, :class=>"label label-info " %> <br />
              <%= f.password_field :current_password %></div>
     <% else %>
             <%= f.hidden_field :current_password, :value => nil %>
     <% end %>

     <div class="formField"><%= f.label "New password", :class=>"label label-info" %> <br />
         <%= f.password_field :password, :autocomplete => "off" %>
     </div>

     <div class="formField"><%= f.label "New password confirmation", :class=>"label label-info" %><br />
         <%= f.password_field :password_confirmation %>
     </div>

     <div class="editAccountButtons">
         <%= f.submit "Update", :class=>"btn btn-small btn-info submitButton" %>
     </div>
<% end %>

registrations_controller.rb

    def update
            @user = User.find(current_user.id)
        successfully_updated = if needs_password?(@user, params)
        Rails.logger.debug('updating with password')
            @user.update_with_password(params[:user])
            else
            # remove the virtual current_password attribute 
            if @user.provider.blank?
                    @user.update_without_password(params[:user])
                else
                @user.update_with_password(params[:user])
                end
        end

        if successfully_updated
                if params[:update_email]
            set_flash_message :alert, :signed_up_but_unconfirmed
            redirect_to after_update_path_for(@user)
        else            
            set_flash_message :notice, :updated
            sign_in @user, :bypass => true
            redirect_to after_update_path_for(@user)
        end
        else
            redirect_to :back, alert: resource.errors.full_messages[0]
        end
    end

    # check if we need password to update user data
    def needs_password?(user,params)        
        !params[:profile] && !user.password.blank?
    end
1

1 Answers

0
votes

This SO question answered my question!

Rails 3.2 Omniauth Devise - Add password - Skip current password

This was my final controller:

def update
        @user = User.find(current_user.id)
        force_updated = false

        successfully_updated = if needs_password?(@user, params)
            Rails.logger.debug('updating with password')
            @user.update_with_password(params[:user])
        else
            if resource.update_attributes(params[resource_name])
                force_updated = true
            end
        end

        if successfully_updated  || force_updated
            if params[:update_email]
                set_flash_message :alert, :signed_up_but_unconfirmed
                redirect_to after_update_path_for(@user)
            else            
                set_flash_message :notice, :updated
                sign_in @user, :bypass => true
                redirect_to after_update_path_for(@user)
            end
        else
            redirect_to :back, alert: resource.errors.full_messages[0]
        end
    end