19

After upgrading Rails 4.1.4 to 4.1.5 i get errors with my facebook omniauth session everything was working fine since then. When i create a User Session i get an ActiveModel::ForbiddenAttributesError

Route:

  match 'auth/:provider/callback', to: 'sessions#create', as: 'signin', via: :get

Session#create controller:

  def create
        user = User.from_omniauth(env["omniauth.auth"])
        session[:user_id] = user.id 
        session[:user_name] = user.name

      redirect_to root_path
  end

and a user model like this:

  def self.from_omniauth(auth)
    where(auth.slice(:provider, :uid)).first_or_create.tap do |user|
      user.provider ||= auth.provider 
      user.uid = auth.uid
      user.name = auth.info.name
      user.save
    end
  end

I can bypass the ActiveModel error by adding a permit! method in my User Model like that:

where(auth.slice(:provider, :uid).permit!).first_or_create.tap do |user|

But it override the first user from the database... The session[:user_id] seems to always be the first User from the database.

I don't know if it's a strong parameters problem, an Omniauth problem or both?

Jonnyx Delavilla
  • 555
  • 9
  • 24

3 Answers3

56

Replace you current finder:

def self.from_omniauth(auth)
  where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
    user.provider = auth.provider 
    user.uid      = auth.uid
    user.name     = auth.info.name
    user.save
  end
end
Ruy Rocha
  • 894
  • 8
  • 8
  • 9
    Can you tell us why is this happening? – goma Aug 29 '14 at 12:21
  • 3
    I don't appear to have an `auth.provider` method but I was able to use `auth[:provider]` instead. I'm guessing the Rails team prevented `slice` from being used as a bypass for strong parameters. – David Tuite Sep 15 '14 at 05:31
  • ^ That seems to be a valid reason to do so. I also found I needed to use `auth[:provider]` sometimes. – ahnbizcad Nov 30 '14 at 17:14
5

I created a detailed writeup of what is happening here:

Rails 4.1.5 Security Fix Breaks Model.where(attributes)

Snippet:

YIKES! Rails 4.1.5 requires you to use safe params for any param to where that is_a? Hash For example, if you were doing a Model.where using slice to take some keys out of some object that derives from Hash, then your code will throw this error when you migrate from Rails 4.1.4 to Rails 4.1.5:

An ActiveModel::ForbiddenAttributesError occurred in omniauth_callbacks#facebook: ActiveModel::ForbiddenAttributesError

justingordon
  • 12,553
  • 12
  • 72
  • 116
  • 1
    So we cant use `where(some_hash.slice(:attribute1, :attribute2)` anymore? It was a nice syntax... – Rafael Oliveira Nov 14 '14 at 18:01
  • it simply becomes `where(provider: auth.provider, uid: auth.uid)`, assuming you passed in the omniauth json info `auth` into the method. It's still pretty ruby as ever. – ahnbizcad Nov 30 '14 at 17:11
0

My solution is like this.

# extend the object and add method
auth_hash_extended = auth.slice(:provider, :uid)
def auth_hash_extended.permitted?()
  true
end

where( auth_hash_extended ).first_or_create do |user|
    user.provider = auth.provider
    #blablabla
end

If you have difficulty in separating hash into key-value sets, you may use this way.

federfeld
  • 1
  • 1